--- /dev/null
+From 4c91adf772b2abda2e0ecb41c77ad9d82a17627a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 10:17:32 +0800
+Subject: ALSA: ac97: Fix possible NULL dereference in snd_ac97_mixer
+
+From: Su Hui <suhui@nfschina.com>
+
+[ Upstream commit 79597c8bf64ca99eab385115743131d260339da5 ]
+
+smatch error:
+sound/pci/ac97/ac97_codec.c:2354 snd_ac97_mixer() error:
+we previously assumed 'rac97' could be null (see line 2072)
+
+remove redundant assignment, return error if rac97 is NULL.
+
+Fixes: da3cec35dd3c ("ALSA: Kill snd_assert() in sound/pci/*")
+Signed-off-by: Su Hui <suhui@nfschina.com>
+Link: https://lore.kernel.org/r/20230615021732.1972194-1-suhui@nfschina.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/ac97/ac97_codec.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
+index 9afc5906d662e..80a65b8ad7b9b 100644
+--- a/sound/pci/ac97/ac97_codec.c
++++ b/sound/pci/ac97/ac97_codec.c
+@@ -2069,8 +2069,8 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
+ .dev_disconnect = snd_ac97_dev_disconnect,
+ };
+
+- if (rac97)
+- *rac97 = NULL;
++ if (!rac97)
++ return -EINVAL;
+ if (snd_BUG_ON(!bus || !template))
+ return -EINVAL;
+ if (snd_BUG_ON(template->num >= 4))
+--
+2.39.2
+
--- /dev/null
+From edda30e17f483152801f3516cf591576687cead9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 15:44:12 -0700
+Subject: amdgpu: validate offset_in_bo of drm_amdgpu_gem_va
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chia-I Wu <olvaffe@gmail.com>
+
+[ Upstream commit 9f0bcf49e9895cb005d78b33a5eebfa11711b425 ]
+
+This is motivated by OOB access in amdgpu_vm_update_range when
+offset_in_bo+map_size overflows.
+
+v2: keep the validations in amdgpu_vm_bo_map
+v3: add the validations to amdgpu_vm_bo_map/amdgpu_vm_bo_replace_map
+ rather than to amdgpu_gem_va_ioctl
+
+Fixes: 9f7eb5367d00 ("drm/amdgpu: actually use the VM map parameters")
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index 587879f3ac2e6..30c0c49b37105 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -1436,14 +1436,14 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
+ uint64_t eaddr;
+
+ /* validate the parameters */
+- if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK ||
+- size == 0 || size & ~PAGE_MASK)
++ if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK)
++ return -EINVAL;
++ if (saddr + size <= saddr || offset + size <= offset)
+ return -EINVAL;
+
+ /* make sure object fit at this offset */
+ eaddr = saddr + size - 1;
+- if (saddr >= eaddr ||
+- (bo && offset + size > amdgpu_bo_size(bo)) ||
++ if ((bo && offset + size > amdgpu_bo_size(bo)) ||
+ (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT))
+ return -EINVAL;
+
+@@ -1502,14 +1502,14 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
+ int r;
+
+ /* validate the parameters */
+- if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK ||
+- size == 0 || size & ~PAGE_MASK)
++ if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK)
++ return -EINVAL;
++ if (saddr + size <= saddr || offset + size <= offset)
+ return -EINVAL;
+
+ /* make sure object fit at this offset */
+ eaddr = saddr + size - 1;
+- if (saddr >= eaddr ||
+- (bo && offset + size > amdgpu_bo_size(bo)) ||
++ if ((bo && offset + size > amdgpu_bo_size(bo)) ||
+ (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT))
+ return -EINVAL;
+
+--
+2.39.2
+
--- /dev/null
+From 2fae7287a25a187a34989fabb526837498c3bb4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 May 2023 15:12:49 -0500
+Subject: APEI: GHES: correctly return NULL for ghes_get_devices()
+
+From: Li Yang <leoyang.li@nxp.com>
+
+[ Upstream commit 9368aa1882ac7178adcd936cee5f0899dbf76dc4 ]
+
+Since 315bada690e0 ("EDAC: Check for GHES preference in the
+chipset-specific EDAC drivers"), vendor specific EDAC driver will not
+probe correctly when CONFIG_ACPI_APEI_GHES is enabled but no GHES device
+is present. Make ghes_get_devices() return NULL when the GHES device
+list is empty to fix the problem.
+
+Fixes: 9057a3f7ac36 ("EDAC/ghes: Prepare to make ghes_edac a proper module")
+Signed-off-by: Li Yang <leoyang.li@nxp.com>
+Reviewed-by: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/apei/ghes.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
+index 34ad071a64e96..4382fe13ee3e4 100644
+--- a/drivers/acpi/apei/ghes.c
++++ b/drivers/acpi/apei/ghes.c
+@@ -1544,6 +1544,8 @@ struct list_head *ghes_get_devices(void)
+
+ pr_warn_once("Force-loading ghes_edac on an unsupported platform. You're on your own!\n");
+ }
++ } else if (list_empty(&ghes_devs)) {
++ return NULL;
+ }
+
+ return &ghes_devs;
+--
+2.39.2
+
--- /dev/null
+From 5a2727c4d204c10b77a0715b0861830888fc6916 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 00:50:50 +0900
+Subject: ARC: define ASM_NL and __ALIGN(_STR) outside #ifdef __ASSEMBLY__
+ guard
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 92e2921eeafdfca9acd9b83f07d2b7ca099bac24 ]
+
+ASM_NL is useful not only in *.S files but also in .c files for using
+inline assembler in C code.
+
+On ARC, however, ASM_NL is evaluated inconsistently. It is expanded to
+a backquote (`) in *.S files, but a semicolon (;) in *.c files because
+arch/arc/include/asm/linkage.h defines it inside #ifdef __ASSEMBLY__,
+so the definition for C code falls back to the default value defined in
+include/linux/linkage.h.
+
+If ASM_NL is used in inline assembler in .c files, it will result in
+wrong assembly code because a semicolon is not an instruction separator,
+but the start of a comment for ARC.
+
+Move ASM_NL (also __ALIGN and __ALIGN_STR) out of the #ifdef.
+
+Fixes: 9df62f054406 ("arch: use ASM_NL instead of ';' for assembler new line character in the macro")
+Fixes: 8d92e992a785 ("ARC: define __ALIGN_STR and __ALIGN symbols for ARC")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arc/include/asm/linkage.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arc/include/asm/linkage.h b/arch/arc/include/asm/linkage.h
+index c9434ff3aa4ce..8a3fb71e9cfad 100644
+--- a/arch/arc/include/asm/linkage.h
++++ b/arch/arc/include/asm/linkage.h
+@@ -8,6 +8,10 @@
+
+ #include <asm/dwarf.h>
+
++#define ASM_NL ` /* use '`' to mark new line in macro */
++#define __ALIGN .align 4
++#define __ALIGN_STR __stringify(__ALIGN)
++
+ #ifdef __ASSEMBLY__
+
+ .macro ST2 e, o, off
+@@ -28,10 +32,6 @@
+ #endif
+ .endm
+
+-#define ASM_NL ` /* use '`' to mark new line in macro */
+-#define __ALIGN .align 4
+-#define __ALIGN_STR __stringify(__ALIGN)
+-
+ /* annotation for data we want in DCCM - if enabled in .config */
+ .macro ARCFP_DATA nm
+ #ifdef CONFIG_ARC_HAS_DCCM
+--
+2.39.2
+
--- /dev/null
+From 8cf982bab7ba2aed015a1ad327a72f86020ce90c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 19:28:42 +0100
+Subject: ARM: 9303/1: kprobes: avoid missing-declaration warnings
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 1b9c3ddcec6a55e15d3e38e7405e2d078db02020 ]
+
+checker_stack_use_t32strd() and kprobe_handler() can be made static since
+they are not used from other files, while coverage_start_registers()
+and __kprobes_test_case() are used from assembler code, and just need
+a declaration to avoid a warning with the global definition.
+
+arch/arm/probes/kprobes/checkers-common.c:43:18: error: no previous prototype for 'checker_stack_use_t32strd'
+arch/arm/probes/kprobes/core.c:236:16: error: no previous prototype for 'kprobe_handler'
+arch/arm/probes/kprobes/test-core.c:723:10: error: no previous prototype for 'coverage_start_registers'
+arch/arm/probes/kprobes/test-core.c:918:14: error: no previous prototype for '__kprobes_test_case_start'
+arch/arm/probes/kprobes/test-core.c:952:14: error: no previous prototype for '__kprobes_test_case_end_16'
+arch/arm/probes/kprobes/test-core.c:967:14: error: no previous prototype for '__kprobes_test_case_end_32'
+
+Fixes: 6624cf651f1a ("ARM: kprobes: collects stack consumption for store instructions")
+Fixes: 454f3e132d05 ("ARM/kprobes: Remove jprobe arm implementation")
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/probes/kprobes/checkers-common.c | 2 +-
+ arch/arm/probes/kprobes/core.c | 2 +-
+ arch/arm/probes/kprobes/opt-arm.c | 2 --
+ arch/arm/probes/kprobes/test-core.c | 2 +-
+ arch/arm/probes/kprobes/test-core.h | 4 ++++
+ 5 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/probes/kprobes/checkers-common.c b/arch/arm/probes/kprobes/checkers-common.c
+index 4d720990cf2a3..eba7ac4725c02 100644
+--- a/arch/arm/probes/kprobes/checkers-common.c
++++ b/arch/arm/probes/kprobes/checkers-common.c
+@@ -40,7 +40,7 @@ enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn,
+ * Different from other insn uses imm8, the real addressing offset of
+ * STRD in T32 encoding should be imm8 * 4. See ARMARM description.
+ */
+-enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
++static enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+ {
+diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c
+index 9090c3a74dcce..d8238da095df7 100644
+--- a/arch/arm/probes/kprobes/core.c
++++ b/arch/arm/probes/kprobes/core.c
+@@ -233,7 +233,7 @@ singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb)
+ * kprobe, and that level is reserved for user kprobe handlers, so we can't
+ * risk encountering a new kprobe in an interrupt handler.
+ */
+-void __kprobes kprobe_handler(struct pt_regs *regs)
++static void __kprobes kprobe_handler(struct pt_regs *regs)
+ {
+ struct kprobe *p, *cur;
+ struct kprobe_ctlblk *kcb;
+diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c
+index dbef34ed933f2..7f65048380ca5 100644
+--- a/arch/arm/probes/kprobes/opt-arm.c
++++ b/arch/arm/probes/kprobes/opt-arm.c
+@@ -145,8 +145,6 @@ __arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty)
+ }
+ }
+
+-extern void kprobe_handler(struct pt_regs *regs);
+-
+ static void
+ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
+ {
+diff --git a/arch/arm/probes/kprobes/test-core.c b/arch/arm/probes/kprobes/test-core.c
+index c562832b86272..171c7076b89f4 100644
+--- a/arch/arm/probes/kprobes/test-core.c
++++ b/arch/arm/probes/kprobes/test-core.c
+@@ -720,7 +720,7 @@ static const char coverage_register_lookup[16] = {
+ [REG_TYPE_NOSPPCX] = COVERAGE_ANY_REG | COVERAGE_SP,
+ };
+
+-unsigned coverage_start_registers(const struct decode_header *h)
++static unsigned coverage_start_registers(const struct decode_header *h)
+ {
+ unsigned regs = 0;
+ int i;
+diff --git a/arch/arm/probes/kprobes/test-core.h b/arch/arm/probes/kprobes/test-core.h
+index 56ad3c0aaeeac..c7297037c1623 100644
+--- a/arch/arm/probes/kprobes/test-core.h
++++ b/arch/arm/probes/kprobes/test-core.h
+@@ -454,3 +454,7 @@ void kprobe_thumb32_test_cases(void);
+ #else
+ void kprobe_arm_test_cases(void);
+ #endif
++
++void __kprobes_test_case_start(void);
++void __kprobes_test_case_end_16(void);
++void __kprobes_test_case_end_32(void);
+--
+2.39.2
+
--- /dev/null
+From e6c2ef14b75df24fc0a722ddbca03e63d7db5370 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 May 2023 14:28:30 +0200
+Subject: ARM: dts: BCM5301X: Drop "clock-names" from the SPI node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit d3c8e2c5757153bbfad70019ec1decbca86f3def ]
+
+There is no such property in the SPI controller binding documentation.
+Also Linux driver doesn't look for it.
+
+This fixes:
+arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: spi@18029200: Unevaluated properties are not allowed ('clock-names' was unexpected)
+ From schema: Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.yaml
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20230503122830.3200-1-zajec5@gmail.com
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/bcm5301x.dtsi | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi
+index 5fc1b847f4aa5..787a0dd8216b7 100644
+--- a/arch/arm/boot/dts/bcm5301x.dtsi
++++ b/arch/arm/boot/dts/bcm5301x.dtsi
+@@ -542,7 +542,6 @@ spi@18029200 {
+ "spi_lr_session_done",
+ "spi_lr_overread";
+ clocks = <&iprocmed>;
+- clock-names = "iprocmed";
+ num-cs = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+--
+2.39.2
+
--- /dev/null
+From 2a0057ace7ddcea5ee7b064061a69b2b192e127e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Jun 2023 17:36:29 +0200
+Subject: ARM: dts: BCM5301X: fix duplex-full => full-duplex
+
+From: Christian Lamparter <chunkeey@gmail.com>
+
+[ Upstream commit fd274b733bfdde3ca72f0fa2a37f032f3a8c402c ]
+
+this typo was found by the dtbs_check
+| ports:port@5:fixed-link: 'oneOf' conditional failed,
+| {'speed': [[1000]], 'duplex-full': True} is not of type 'array'
+| 'duplex-full' does not match any of the regexes: 'pinctrl-[0-]..."
+
+this should have been full-duplex;
+
+Fixes: 935327a73553 ("ARM: dts: BCM5301X: Add DT for Meraki MR26")
+Fixes: ec88a9c344d9 ("ARM: BCM5301X: Add DT for Meraki MR32")
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Link: https://lore.kernel.org/r/50522f45566951a9eabd22820647924cc6b4a264.1686238550.git.chunkeey@gmail.com
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 +-
+ arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
+index 14f58033efeb9..ca2266b936ee2 100644
+--- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
++++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
+@@ -128,7 +128,7 @@ port@5 {
+
+ fixed-link {
+ speed = <1000>;
+- duplex-full;
++ full-duplex;
+ };
+ };
+ };
+diff --git a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
+index 46c2c93b01d88..a34e1746a6c59 100644
+--- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
++++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
+@@ -187,7 +187,7 @@ port@5 {
+
+ fixed-link {
+ speed = <1000>;
+- duplex-full;
++ full-duplex;
+ };
+ };
+ };
+--
+2.39.2
+
--- /dev/null
+From 96d22e992dab0128bc7aed1d9d81b2f82ffdca2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 13:32:25 +0300
+Subject: ARM: dts: gta04: Move model property out of pinctrl node
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit 4ffec92e70ac5097b9f67ec154065305b16a3b46 ]
+
+The model property should be at the top level, let's move it out
+of the pinctrl node.
+
+Fixes: d2eaf949d2c3 ("ARM: dts: omap3-gta04a5one: define GTA04A5 variant with OneNAND")
+Cc: Andreas Kemnade <andreas@kemnade.info>
+Cc: H. Nikolaus Schaller <hns@goldelico.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/omap3-gta04a5one.dts | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/omap3-gta04a5one.dts b/arch/arm/boot/dts/omap3-gta04a5one.dts
+index 9db9fe67cd63b..95df45cc70c09 100644
+--- a/arch/arm/boot/dts/omap3-gta04a5one.dts
++++ b/arch/arm/boot/dts/omap3-gta04a5one.dts
+@@ -5,9 +5,11 @@
+
+ #include "omap3-gta04a5.dts"
+
+-&omap3_pmx_core {
++/ {
+ model = "Goldelico GTA04A5/Letux 2804 with OneNAND";
++};
+
++&omap3_pmx_core {
+ gpmc_pins: pinmux_gpmc_pins {
+ pinctrl-single,pins = <
+
+--
+2.39.2
+
--- /dev/null
+From 1ffeb180c97caf967a739fc270dd18dfbbee1df5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 May 2023 17:35:16 +0200
+Subject: ARM: dts: iwg20d-q7-common: Fix backlight pwm specifier
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 0501fdec106a291c43b3c1b525cf22ab4c24b2d8 ]
+
+make dtbs_check:
+
+ arch/arm/boot/dts/renesas/r8a7743-iwg20d-q7.dtb: backlight: pwms: [[58, 0, 5000000], [0]] is too long
+ From schema: Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml
+ arch/arm/boot/dts/renesas/r8a7743-iwg20d-q7-dbcm-ca.dtb: backlight: pwms: [[67, 0, 5000000], [0]] is too long
+ From schema: Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml
+ arch/arm/boot/dts/renesas/r8a7744-iwg20d-q7-dbcm-ca.dtb: backlight: pwms: [[67, 0, 5000000], [0]] is too long
+ From schema: Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml
+ arch/arm/boot/dts/renesas/r8a7744-iwg20d-q7.dtb: backlight: pwms: [[58, 0, 5000000], [0]] is too long
+ From schema: Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml
+
+PWM specifiers referring to R-Car PWM Timer Controllers should contain
+only two cells.
+
+Fix this by dropping the bogus third cell.
+
+Fixes: 6f89dd9e9325d05b ("ARM: dts: iwg20d-q7-common: Add LCD support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/6e5c3167424a43faf8c1fa68d9667b3d87dc86d8.1684855911.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/iwg20d-q7-common.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/iwg20d-q7-common.dtsi b/arch/arm/boot/dts/iwg20d-q7-common.dtsi
+index 03caea6fc6ffa..4351c5a02fa59 100644
+--- a/arch/arm/boot/dts/iwg20d-q7-common.dtsi
++++ b/arch/arm/boot/dts/iwg20d-q7-common.dtsi
+@@ -49,7 +49,7 @@ audio_clock: audio_clock {
+ lcd_backlight: backlight {
+ compatible = "pwm-backlight";
+
+- pwms = <&pwm3 0 5000000 0>;
++ pwms = <&pwm3 0 5000000>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ enable-gpios = <&gpio5 14 GPIO_ACTIVE_HIGH>;
+--
+2.39.2
+
--- /dev/null
+From d7af71b700cc13ee592cca8a3dabb0dcc684899a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 15:18:39 +0200
+Subject: ARM: dts: lan966x: kontron-d10: fix board reset
+
+From: Michael Walle <mwalle@kernel.org>
+
+[ Upstream commit bfcd5714f6424c03e385e0e9296dcd69855cfea7 ]
+
+The pinctrl node was missing which change the pin mux to GPIO mode. Add
+it.
+
+Fixes: 79d83b3a458e ("ARM: dts: lan966x: add basic Kontron KSwitch D10 support")
+Signed-off-by: Michael Walle <mwalle@kernel.org>
+[claudiu.beznea: moved pinctrl-* bindings after compatible]
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230616-feature-d10-dt-cleanups-v1-1-50dd0452b8fe@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi b/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi
+index 0097e72e3fb22..42be207509a46 100644
+--- a/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi
++++ b/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi
+@@ -18,6 +18,8 @@ chosen {
+
+ gpio-restart {
+ compatible = "gpio-restart";
++ pinctrl-0 = <&reset_pins>;
++ pinctrl-names = "default";
+ gpios = <&gpio 56 GPIO_ACTIVE_LOW>;
+ priority = <200>;
+ };
+@@ -59,6 +61,12 @@ miim_c_pins: miim-c-pins {
+ function = "miim_c";
+ };
+
++ reset_pins: reset-pins {
++ /* SYS_RST# */
++ pins = "GPIO_56";
++ function = "gpio";
++ };
++
+ sgpio_a_pins: sgpio-a-pins {
+ /* SCK, D0, D1 */
+ pins = "GPIO_32", "GPIO_33", "GPIO_34";
+--
+2.39.2
+
--- /dev/null
+From 225500356c0cad924b7cbb9c1ea773b6b73fa6f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 15:18:40 +0200
+Subject: ARM: dts: lan966x: kontron-d10: fix SPI CS
+
+From: Michael Walle <mwalle@kernel.org>
+
+[ Upstream commit fcb79ee3f0b15ed15f35eca5f24e952fdced9c61 ]
+
+The pinctrl node was missing which change the pin mux to GPIO mode.
+Add it so we don't have to rely on the bootloader to set the correct
+mode.
+
+Fixes: 79d83b3a458e ("ARM: dts: lan966x: add basic Kontron KSwitch D10 support")
+Signed-off-by: Michael Walle <mwalle@kernel.org>
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230616-feature-d10-dt-cleanups-v1-2-50dd0452b8fe@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi b/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi
+index 42be207509a46..f4df4cc1dfa5e 100644
+--- a/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi
++++ b/arch/arm/boot/dts/lan966x-kontron-kswitch-d10-mmt.dtsi
+@@ -41,7 +41,7 @@ &flx3 {
+ status = "okay";
+
+ spi3: spi@400 {
+- pinctrl-0 = <&fc3_b_pins>;
++ pinctrl-0 = <&fc3_b_pins>, <&spi3_cs_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ cs-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+@@ -79,6 +79,12 @@ sgpio_b_pins: sgpio-b-pins {
+ function = "sgpio_b";
+ };
+
++ spi3_cs_pins: spi3-cs-pins {
++ /* CS# */
++ pins = "GPIO_46";
++ function = "gpio";
++ };
++
+ usart0_pins: usart0-pins {
+ /* RXD, TXD */
+ pins = "GPIO_25", "GPIO_26";
+--
+2.39.2
+
--- /dev/null
+From 2e9b6ec9aa65fd0737937f7f7617458e66b5acd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 May 2023 22:30:29 +0200
+Subject: ARM: dts: meson8: correct uart_B and uart_C clock references
+
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+
+[ Upstream commit 98b503c7fb13a17a47d8ebf15fa8f7c10118e75c ]
+
+On Meson8 uart_B and uart_C do not work, because they are relying on
+incorrect clocks. Change the references of pclk to the correct CLKID
+(UART1 for uart_B and UART2 for uart_C), to allow use of the two uarts.
+
+This was originally reported by Hans-Frieder Vogt for Meson8b [0], but
+the same bug is also present in meson8.dtsi
+
+[0] https://lore.kernel.org/linux-amlogic/trinity-bf20bcb9-790b-4ab9-99e3-0831ef8257f4-1680878185420@3c-app-gmx-bap55/
+
+Fixes: 57007bfb5469 ("ARM: dts: meson8: Fix the UART device-tree schema validation")
+Reported-by: Hans-Frieder Vogt <hfdevel@gmx.net> # for meson8b.dtsi
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://lore.kernel.org/r/20230516203029.1031174-1-martin.blumenstingl@googlemail.com
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/meson8.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi
+index 21eb59041a7d9..8432efd48f610 100644
+--- a/arch/arm/boot/dts/meson8.dtsi
++++ b/arch/arm/boot/dts/meson8.dtsi
+@@ -752,13 +752,13 @@ &uart_A {
+
+ &uart_B {
+ compatible = "amlogic,meson8-uart";
+- clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
++ clocks = <&xtal>, <&clkc CLKID_UART1>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
+ };
+
+ &uart_C {
+ compatible = "amlogic,meson8-uart";
+- clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
++ clocks = <&xtal>, <&clkc CLKID_UART2>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 763f55812b2146c76e5103589ad56b6d115cf1c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Apr 2023 16:36:25 +0200
+Subject: ARM: dts: meson8b: correct uart_B and uart_C clock references
+
+From: hfdevel@gmx.net <hfdevel@gmx.net>
+
+[ Upstream commit d542ce8d4769cdef6a7bc3437e59cfed9c68f0e4 ]
+
+With the current device tree for meson8b, uarts B (e.g. available on pins
+8/10 on Odroid-C1) and C (pins 3/5 on Odroid-C1) do not work, because they
+are relying on incorrect clocks. Change the references of pclk to the
+correct CLKID, to allow use of the two uarts.
+
+Fixes: 3375aa77135f ("ARM: dts: meson8b: Fix the UART device-tree schema validation")
+Signed-off-by: Hans-Frieder Vogt <hfdevel@gmx.net>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://lore.kernel.org/r/trinity-bf20bcb9-790b-4ab9-99e3-0831ef8257f4-1680878185420@3c-app-gmx-bap55
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/meson8b.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi
+index d5a3fe21e8e7e..25f7c985f9ea1 100644
+--- a/arch/arm/boot/dts/meson8b.dtsi
++++ b/arch/arm/boot/dts/meson8b.dtsi
+@@ -740,13 +740,13 @@ &uart_A {
+
+ &uart_B {
+ compatible = "amlogic,meson8b-uart";
+- clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
++ clocks = <&xtal>, <&clkc CLKID_UART1>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
+ };
+
+ &uart_C {
+ compatible = "amlogic,meson8b-uart";
+- clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
++ clocks = <&xtal>, <&clkc CLKID_UART2>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
+ };
+
+--
+2.39.2
+
--- /dev/null
+From cb887b93d3cafe4525a991b335905ecdac12b8d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 May 2023 22:07:33 +0300
+Subject: ARM: dts: qcom: apq8074-dragonboard: Set DMA as remotely controlled
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit e60c230588d88036f974cec7e93361e2c4f62226 ]
+
+Add the qcom,controlled-remotely property for the blsp2_bam
+controller node. This board requires this, otherwise the board stalls
+during the boot for some reason (most probably because TZ mishandles the
+protection error and keeps on looping somewhere inside).
+
+Fixes: 62bc81792223 dts: msm8974: Add blsp2_bam dma node
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230507190735.2333145-3-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-apq8074-dragonboard.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+index 1345df7cbd002..6b047c6793707 100644
+--- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
++++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+@@ -23,6 +23,10 @@ &blsp1_uart2 {
+ status = "okay";
+ };
+
++&blsp2_dma {
++ qcom,controlled-remotely;
++};
++
+ &blsp2_i2c5 {
+ status = "okay";
+ clock-frequency = <200000>;
+--
+2.39.2
+
--- /dev/null
+From 3dc0667488fbb8e6791a2e7c1b9aa8c36a43cfe6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Apr 2023 19:52:32 +0200
+Subject: ARM: dts: qcom: msm8974: do not use underscore in node name (again)
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 311bbc884b2edcf584b67d331be85ce43b27586f ]
+
+Align RPM requests node with DT schema by using hyphen instead of
+underscore.
+
+Fixes: f300826d27be ("ARM: dts: qcom-msm8974: Sort and clean up nodes")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230410175232.22317-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 834ad95515b17..1c3d36701b8e5 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -300,7 +300,7 @@ rpm {
+ qcom,ipc = <&apcs 8 0>;
+ qcom,smd-edge = <15>;
+
+- rpm_requests: rpm_requests {
++ rpm_requests: rpm-requests {
+ compatible = "qcom,rpm-msm8974";
+ qcom,smd-channels = "rpm_requests";
+
+--
+2.39.2
+
--- /dev/null
+From 7af37fc662c7f5155cb1a1386122a92aaa63f0fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 20:01:12 +0200
+Subject: ARM: dts: stm32: Fix audio routing on STM32MP15xx DHCOM PDK2
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit e3f2778b1b6ced649bffdc7cbb05b80bb92f2108 ]
+
+The audio routing flow is not correct, the flow should be from source
+(second element in the pair) to sink (first element in the pair). The
+flow now is from "HP_OUT" to "Playback", where "Playback" is source
+and "HP_OUT" is sink, i.e. the direction is swapped and there is no
+direct link between the two either.
+
+Fill in the correct routing, where "HP_OUT" supplies the "Headphone Jack",
+"Line In Jack" supplies "LINE_IN" input, "Microphone Jack" supplies "MIC_IN"
+input and "Mic Bias" supplies "Microphone Jack".
+
+Fixes: 34e0c7847dcf ("ARM: dts: stm32: Add DH Electronics DHCOM STM32MP1 SoM and PDK2 board")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
+index 4709677151aac..46b87a27d8b37 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
+@@ -137,10 +137,13 @@ reg_panel_supply: regulator-panel-supply {
+
+ sound {
+ compatible = "audio-graph-card";
+- routing =
+- "MIC_IN", "Capture",
+- "Capture", "Mic Bias",
+- "Playback", "HP_OUT";
++ widgets = "Headphone", "Headphone Jack",
++ "Line", "Line In Jack",
++ "Microphone", "Microphone Jack";
++ routing = "Headphone Jack", "HP_OUT",
++ "LINE_IN", "Line In Jack",
++ "MIC_IN", "Microphone Jack",
++ "Microphone Jack", "Mic Bias";
+ dais = <&sai2a_port &sai2b_port>;
+ status = "okay";
+ };
+--
+2.39.2
+
--- /dev/null
+From f9beb34f97f853fb660abc6c533cdbfaaf02d9a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 13:56:04 +0200
+Subject: ARM: dts: stm32: fix i2s endpoint format property for stm32mp15xx-dkx
+
+From: Olivier Moysan <olivier.moysan@foss.st.com>
+
+[ Upstream commit 076c74c592cabe4a47537fe5205b5b678bed010d ]
+
+Use "dai-format" to configure DAI audio format as specified in
+audio-graph-port.yaml bindings.
+
+Fixes: 144d1ba70548 ("ARM: dts: stm32: Adapt STM32MP157 DK boards to stm32 DT diversity")
+Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/stm32mp15xx-dkx.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
+index 11370ae0d868b..030b7ace63f1e 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
+@@ -438,7 +438,7 @@ &i2s2 {
+ i2s2_port: port {
+ i2s2_endpoint: endpoint {
+ remote-endpoint = <&sii9022_tx_endpoint>;
+- format = "i2s";
++ dai-format = "i2s";
+ mclk-fs = <256>;
+ };
+ };
+--
+2.39.2
+
--- /dev/null
+From 2b83805caff8e86e5b5bc17be10d8c341dd31a80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 May 2023 23:37:29 +0200
+Subject: ARM: dts: stm32: Move ethernet MAC EEPROM from SoM to carrier boards
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 9660efc2af37f3c12dc6e6a5511ad99e0addc297 ]
+
+The ethernet MAC EEPROM is not populated on the SoM itself, it has to be
+populated on each carrier board. Move the EEPROM into the correct place
+in DTs, i.e. the carrier board DTs. Add label to the EEPROM too.
+
+Fixes: 7e76f82acd9e1 ("ARM: dts: stm32: Split Avenger96 into DHCOR SoM and Avenger96 board")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 6 ++++++
+ arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi | 6 ++++++
+ arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi | 6 ------
+ arch/arm/boot/dts/stm32mp15xx-dhcor-testbench.dtsi | 8 ++++++++
+ 4 files changed, 20 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+index 50af4a27d6be4..e67c0fa209cde 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+@@ -321,6 +321,12 @@ adv7513_i2s0: endpoint {
+ };
+ };
+ };
++
++ dh_mac_eeprom: eeprom@53 {
++ compatible = "atmel,24c02";
++ reg = <0x53>;
++ pagesize = <16>;
++ };
+ };
+
+ <dc {
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi
+index c32c160f97f20..39af79dc654cc 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi
+@@ -192,6 +192,12 @@ eeprom@50 {
+ reg = <0x50>;
+ pagesize = <16>;
+ };
++
++ dh_mac_eeprom: eeprom@53 {
++ compatible = "atmel,24c02";
++ reg = <0x53>;
++ pagesize = <16>;
++ };
+ };
+
+ &sdmmc1 { /* MicroSD */
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
+index bb40fb46da81d..bba19f21e5277 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
+@@ -213,12 +213,6 @@ watchdog {
+ status = "disabled";
+ };
+ };
+-
+- eeprom@53 {
+- compatible = "atmel,24c02";
+- reg = <0x53>;
+- pagesize = <16>;
+- };
+ };
+
+ &ipcc {
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-testbench.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-testbench.dtsi
+index 5fdb74b652aca..faed31b6d84a1 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-testbench.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-testbench.dtsi
+@@ -90,6 +90,14 @@ phy0: ethernet-phy@7 {
+ };
+ };
+
++&i2c4 {
++ dh_mac_eeprom: eeprom@53 {
++ compatible = "atmel,24c02";
++ reg = <0x53>;
++ pagesize = <16>;
++ };
++};
++
+ &sdmmc1 {
+ pinctrl-names = "default", "opendrain", "sleep";
+ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_b>;
+--
+2.39.2
+
--- /dev/null
+From 567d3a003c245b909fe6a2295a2afddc35d0a318 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 02:42:32 +0200
+Subject: ARM: dts: stm32: Shorten the AV96 HDMI sound card name
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 0cf765e598712addec34d0208cc1418c151fefb2 ]
+
+Fix the following error in kernel log due to too long sound card name:
+"
+asoc-audio-graph-card sound: ASoC: driver name too long 'STM32MP1-AV96-HDMI' -> 'STM32MP1-AV96-H'
+"
+
+Fixes: e027da342772 ("ARM: dts: stm32: Add bindings for audio on AV96")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+index e67c0fa209cde..7d5d6d4360385 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+@@ -87,7 +87,7 @@ sd_switch: regulator-sd_switch {
+
+ sound {
+ compatible = "audio-graph-card";
+- label = "STM32MP1-AV96-HDMI";
++ label = "STM32-AV96-HDMI";
+ dais = <&sai2a_port>;
+ status = "okay";
+ };
+--
+2.39.2
+
--- /dev/null
+From 56e0b3c4aa9f89415c9390eda5c31d6cafdd70c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 May 2023 17:30:58 +0200
+Subject: ARM: ep93xx: fix missing-prototype warnings
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 419013740ea1e4343d8ade535d999f59fa28e460 ]
+
+ep93xx_clocksource_read() is only called from the file it is declared in,
+while ep93xx_timer_init() is declared in a header that is not included here.
+
+arch/arm/mach-ep93xx/timer-ep93xx.c:120:13: error: no previous prototype for 'ep93xx_timer_init'
+arch/arm/mach-ep93xx/timer-ep93xx.c:63:5: error: no previous prototype for 'ep93xx_clocksource_read'
+
+Fixes: 000bc17817bf ("ARM: ep93xx: switch to GENERIC_CLOCKEVENTS")
+Acked-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
+Link: https://lore.kernel.org/r/20230516153109.514251-3-arnd@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-ep93xx/timer-ep93xx.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-ep93xx/timer-ep93xx.c b/arch/arm/mach-ep93xx/timer-ep93xx.c
+index dd4b164d18317..a9efa7bc2fa12 100644
+--- a/arch/arm/mach-ep93xx/timer-ep93xx.c
++++ b/arch/arm/mach-ep93xx/timer-ep93xx.c
+@@ -9,6 +9,7 @@
+ #include <linux/io.h>
+ #include <asm/mach/time.h>
+ #include "soc.h"
++#include "platform.h"
+
+ /*************************************************************************
+ * Timer handling for EP93xx
+@@ -60,7 +61,7 @@ static u64 notrace ep93xx_read_sched_clock(void)
+ return ret;
+ }
+
+-u64 ep93xx_clocksource_read(struct clocksource *c)
++static u64 ep93xx_clocksource_read(struct clocksource *c)
+ {
+ u64 ret;
+
+--
+2.39.2
+
--- /dev/null
+From 0e499cb4478acbae63d96f61faa9071040cf49e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Apr 2023 11:35:05 +0200
+Subject: ARM/mfd/gpio: Fixup TPS65010 regression on OMAP1 OSK1
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit c32c81f3dbdfd68f6ab20a29ad86f811aed36e4e ]
+
+Aaro reports problems on the OSK1 board after we altered
+the dynamic base for GPIO allocations.
+
+It appears this happens because the OMAP driver now
+allocates GPIO numbers dynamically, so all that is
+references by number is a bit up in the air.
+
+Let's bite the bullet and try to just move the gpio_chip
+in the tps65010 MFD driver over to using dynamic allocations.
+Alter everything in the OSK1 board file to use a GPIO
+descriptor table and lookups.
+
+Utilize the NULL device to define some board-specific
+GPIO lookups and use these to immediately look up the
+same GPIOs, convert to IRQ numbers and pass as resources
+to the devices. This is ugly but should work.
+
+The .setup() callback for tps65010 was used for some GPIO
+hogging, but since the OSK1 is the only user in the entire
+kernel we can alter the signatures to something that
+is helpful and make a clean transition.
+
+Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base")
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: andy.shevchenko@gmail.com
+Cc: Andreas Kemnade <andreas@kemnade.info>
+Acked-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Lee Jones <lee@kernel.org>
+Reported-by: Aaro Koskinen <aaro.koskinen@iki.fi>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap1/board-osk.c | 139 ++++++++++++++++++++++----------
+ drivers/mfd/tps65010.c | 14 ++--
+ include/linux/mfd/tps65010.h | 11 +--
+ 3 files changed, 104 insertions(+), 60 deletions(-)
+
+diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
+index df758c1f92373..a8ca8d427182d 100644
+--- a/arch/arm/mach-omap1/board-osk.c
++++ b/arch/arm/mach-omap1/board-osk.c
+@@ -25,7 +25,8 @@
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+-#include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
++#include <linux/gpio/driver.h>
+ #include <linux/gpio/machine.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+@@ -64,13 +65,12 @@
+ /* TPS65010 has four GPIOs. nPG and LED2 can be treated like GPIOs with
+ * alternate pin configurations for hardware-controlled blinking.
+ */
+-#define OSK_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+-# define OSK_TPS_GPIO_USB_PWR_EN (OSK_TPS_GPIO_BASE + 0)
+-# define OSK_TPS_GPIO_LED_D3 (OSK_TPS_GPIO_BASE + 1)
+-# define OSK_TPS_GPIO_LAN_RESET (OSK_TPS_GPIO_BASE + 2)
+-# define OSK_TPS_GPIO_DSP_PWR_EN (OSK_TPS_GPIO_BASE + 3)
+-# define OSK_TPS_GPIO_LED_D9 (OSK_TPS_GPIO_BASE + 4)
+-# define OSK_TPS_GPIO_LED_D2 (OSK_TPS_GPIO_BASE + 5)
++#define OSK_TPS_GPIO_USB_PWR_EN 0
++#define OSK_TPS_GPIO_LED_D3 1
++#define OSK_TPS_GPIO_LAN_RESET 2
++#define OSK_TPS_GPIO_DSP_PWR_EN 3
++#define OSK_TPS_GPIO_LED_D9 4
++#define OSK_TPS_GPIO_LED_D2 5
+
+ static struct mtd_partition osk_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+@@ -174,11 +174,20 @@ static const struct gpio_led tps_leds[] = {
+ /* NOTE: D9 and D2 have hardware blink support.
+ * Also, D9 requires non-battery power.
+ */
+- { .gpio = OSK_TPS_GPIO_LED_D9, .name = "d9",
+- .default_trigger = "disk-activity", },
+- { .gpio = OSK_TPS_GPIO_LED_D2, .name = "d2", },
+- { .gpio = OSK_TPS_GPIO_LED_D3, .name = "d3", .active_low = 1,
+- .default_trigger = "heartbeat", },
++ { .name = "d9", .default_trigger = "disk-activity", },
++ { .name = "d2", },
++ { .name = "d3", .default_trigger = "heartbeat", },
++};
++
++static struct gpiod_lookup_table tps_leds_gpio_table = {
++ .dev_id = "leds-gpio",
++ .table = {
++ /* Use local offsets on TPS65010 */
++ GPIO_LOOKUP_IDX("tps65010", OSK_TPS_GPIO_LED_D9, NULL, 0, GPIO_ACTIVE_HIGH),
++ GPIO_LOOKUP_IDX("tps65010", OSK_TPS_GPIO_LED_D2, NULL, 1, GPIO_ACTIVE_HIGH),
++ GPIO_LOOKUP_IDX("tps65010", OSK_TPS_GPIO_LED_D3, NULL, 2, GPIO_ACTIVE_LOW),
++ { }
++ },
+ };
+
+ static struct gpio_led_platform_data tps_leds_data = {
+@@ -192,29 +201,34 @@ static struct platform_device osk5912_tps_leds = {
+ .dev.platform_data = &tps_leds_data,
+ };
+
+-static int osk_tps_setup(struct i2c_client *client, void *context)
++/* The board just hold these GPIOs hogged from setup to teardown */
++static struct gpio_desc *eth_reset;
++static struct gpio_desc *vdd_dsp;
++
++static int osk_tps_setup(struct i2c_client *client, struct gpio_chip *gc)
+ {
++ struct gpio_desc *d;
+ if (!IS_BUILTIN(CONFIG_TPS65010))
+ return -ENOSYS;
+
+ /* Set GPIO 1 HIGH to disable VBUS power supply;
+ * OHCI driver powers it up/down as needed.
+ */
+- gpio_request(OSK_TPS_GPIO_USB_PWR_EN, "n_vbus_en");
+- gpio_direction_output(OSK_TPS_GPIO_USB_PWR_EN, 1);
++ d = gpiochip_request_own_desc(gc, OSK_TPS_GPIO_USB_PWR_EN, "n_vbus_en",
++ GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH);
+ /* Free the GPIO again as the driver will request it */
+- gpio_free(OSK_TPS_GPIO_USB_PWR_EN);
++ gpiochip_free_own_desc(d);
+
+ /* Set GPIO 2 high so LED D3 is off by default */
+ tps65010_set_gpio_out_value(GPIO2, HIGH);
+
+ /* Set GPIO 3 low to take ethernet out of reset */
+- gpio_request(OSK_TPS_GPIO_LAN_RESET, "smc_reset");
+- gpio_direction_output(OSK_TPS_GPIO_LAN_RESET, 0);
++ eth_reset = gpiochip_request_own_desc(gc, OSK_TPS_GPIO_LAN_RESET, "smc_reset",
++ GPIO_ACTIVE_HIGH, GPIOD_OUT_LOW);
+
+ /* GPIO4 is VDD_DSP */
+- gpio_request(OSK_TPS_GPIO_DSP_PWR_EN, "dsp_power");
+- gpio_direction_output(OSK_TPS_GPIO_DSP_PWR_EN, 1);
++ vdd_dsp = gpiochip_request_own_desc(gc, OSK_TPS_GPIO_DSP_PWR_EN, "dsp_power",
++ GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH);
+ /* REVISIT if DSP support isn't configured, power it off ... */
+
+ /* Let LED1 (D9) blink; leds-gpio may override it */
+@@ -232,15 +246,22 @@ static int osk_tps_setup(struct i2c_client *client, void *context)
+
+ /* register these three LEDs */
+ osk5912_tps_leds.dev.parent = &client->dev;
++ gpiod_add_lookup_table(&tps_leds_gpio_table);
+ platform_device_register(&osk5912_tps_leds);
+
+ return 0;
+ }
+
++static void osk_tps_teardown(struct i2c_client *client, struct gpio_chip *gc)
++{
++ gpiochip_free_own_desc(eth_reset);
++ gpiochip_free_own_desc(vdd_dsp);
++}
++
+ static struct tps65010_board tps_board = {
+- .base = OSK_TPS_GPIO_BASE,
+ .outmask = 0x0f,
+ .setup = osk_tps_setup,
++ .teardown = osk_tps_teardown,
+ };
+
+ static struct i2c_board_info __initdata osk_i2c_board_info[] = {
+@@ -263,11 +284,6 @@ static void __init osk_init_smc91x(void)
+ {
+ u32 l;
+
+- if ((gpio_request(0, "smc_irq")) < 0) {
+- printk("Error requesting gpio 0 for smc91x irq\n");
+- return;
+- }
+-
+ /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
+ l = omap_readl(EMIFS_CCS(1));
+ l |= 0x3;
+@@ -279,10 +295,6 @@ static void __init osk_init_cf(int seg)
+ struct resource *res = &osk5912_cf_resources[1];
+
+ omap_cfg_reg(M7_1610_GPIO62);
+- if ((gpio_request(62, "cf_irq")) < 0) {
+- printk("Error requesting gpio 62 for CF irq\n");
+- return;
+- }
+
+ switch (seg) {
+ /* NOTE: CS0 could be configured too ... */
+@@ -308,18 +320,17 @@ static void __init osk_init_cf(int seg)
+ seg, omap_readl(EMIFS_CCS(seg)), omap_readl(EMIFS_ACS(seg)));
+ omap_writel(0x0004a1b3, EMIFS_CCS(seg)); /* synch mode 4 etc */
+ omap_writel(0x00000000, EMIFS_ACS(seg)); /* OE hold/setup */
+-
+- /* the CF I/O IRQ is really active-low */
+- irq_set_irq_type(gpio_to_irq(62), IRQ_TYPE_EDGE_FALLING);
+ }
+
+ static struct gpiod_lookup_table osk_usb_gpio_table = {
+ .dev_id = "ohci",
+ .table = {
+ /* Power GPIO on the I2C-attached TPS65010 */
+- GPIO_LOOKUP("tps65010", 0, "power", GPIO_ACTIVE_HIGH),
++ GPIO_LOOKUP("tps65010", OSK_TPS_GPIO_USB_PWR_EN, "power",
++ GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP(OMAP_GPIO_LABEL, 9, "overcurrent",
+ GPIO_ACTIVE_HIGH),
++ { }
+ },
+ };
+
+@@ -341,8 +352,25 @@ static struct omap_usb_config osk_usb_config __initdata = {
+
+ #define EMIFS_CS3_VAL (0x88013141)
+
++static struct gpiod_lookup_table osk_irq_gpio_table = {
++ .dev_id = NULL,
++ .table = {
++ /* GPIO used for SMC91x IRQ */
++ GPIO_LOOKUP(OMAP_GPIO_LABEL, 0, "smc_irq",
++ GPIO_ACTIVE_HIGH),
++ /* GPIO used for CF IRQ */
++ GPIO_LOOKUP("gpio-48-63", 14, "cf_irq",
++ GPIO_ACTIVE_HIGH),
++ /* GPIO used by the TPS65010 chip */
++ GPIO_LOOKUP("mpuio", 1, "tps65010",
++ GPIO_ACTIVE_HIGH),
++ { }
++ },
++};
++
+ static void __init osk_init(void)
+ {
++ struct gpio_desc *d;
+ u32 l;
+
+ osk_init_smc91x();
+@@ -359,10 +387,31 @@ static void __init osk_init(void)
+
+ osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys();
+ osk_flash_resource.end += SZ_32M - 1;
+- osk5912_smc91x_resources[1].start = gpio_to_irq(0);
+- osk5912_smc91x_resources[1].end = gpio_to_irq(0);
+- osk5912_cf_resources[0].start = gpio_to_irq(62);
+- osk5912_cf_resources[0].end = gpio_to_irq(62);
++
++ /*
++ * Add the GPIOs to be used as IRQs and immediately look them up
++ * to be passed as an IRQ resource. This is ugly but should work
++ * until the day we convert to device tree.
++ */
++ gpiod_add_lookup_table(&osk_irq_gpio_table);
++
++ d = gpiod_get(NULL, "smc_irq", GPIOD_IN);
++ if (IS_ERR(d)) {
++ pr_err("Unable to get SMC IRQ GPIO descriptor\n");
++ } else {
++ irq_set_irq_type(gpiod_to_irq(d), IRQ_TYPE_EDGE_RISING);
++ osk5912_smc91x_resources[1] = DEFINE_RES_IRQ(gpiod_to_irq(d));
++ }
++
++ d = gpiod_get(NULL, "cf_irq", GPIOD_IN);
++ if (IS_ERR(d)) {
++ pr_err("Unable to get CF IRQ GPIO descriptor\n");
++ } else {
++ /* the CF I/O IRQ is really active-low */
++ irq_set_irq_type(gpiod_to_irq(d), IRQ_TYPE_EDGE_FALLING);
++ osk5912_cf_resources[0] = DEFINE_RES_IRQ(gpiod_to_irq(d));
++ }
++
+ platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+@@ -372,13 +421,15 @@ static void __init osk_init(void)
+ gpiod_add_lookup_table(&osk_usb_gpio_table);
+ omap1_usb_init(&osk_usb_config);
+
++ omap_serial_init();
++
+ /* irq for tps65010 chip */
+ /* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */
+- if (gpio_request(OMAP_MPUIO(1), "tps65010") == 0)
+- gpio_direction_input(OMAP_MPUIO(1));
+-
+- omap_serial_init();
+- osk_i2c_board_info[0].irq = gpio_to_irq(OMAP_MPUIO(1));
++ d = gpiod_get(NULL, "tps65010", GPIOD_IN);
++ if (IS_ERR(d))
++ pr_err("Unable to get TPS65010 IRQ GPIO descriptor\n");
++ else
++ osk_i2c_board_info[0].irq = gpiod_to_irq(d);
+ omap_register_i2c_bus(1, 400, osk_i2c_board_info,
+ ARRAY_SIZE(osk_i2c_board_info));
+ }
+diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c
+index fb733288cca3b..faea4ff44c6fe 100644
+--- a/drivers/mfd/tps65010.c
++++ b/drivers/mfd/tps65010.c
+@@ -506,12 +506,8 @@ static void tps65010_remove(struct i2c_client *client)
+ struct tps65010 *tps = i2c_get_clientdata(client);
+ struct tps65010_board *board = dev_get_platdata(&client->dev);
+
+- if (board && board->teardown) {
+- int status = board->teardown(client, board->context);
+- if (status < 0)
+- dev_dbg(&client->dev, "board %s %s err %d\n",
+- "teardown", client->name, status);
+- }
++ if (board && board->teardown)
++ board->teardown(client, &tps->chip);
+ if (client->irq > 0)
+ free_irq(client->irq, tps);
+ cancel_delayed_work_sync(&tps->work);
+@@ -619,7 +615,7 @@ static int tps65010_probe(struct i2c_client *client)
+ tps, DEBUG_FOPS);
+
+ /* optionally register GPIOs */
+- if (board && board->base != 0) {
++ if (board) {
+ tps->outmask = board->outmask;
+
+ tps->chip.label = client->name;
+@@ -632,7 +628,7 @@ static int tps65010_probe(struct i2c_client *client)
+ /* NOTE: only partial support for inputs; nyet IRQs */
+ tps->chip.get = tps65010_gpio_get;
+
+- tps->chip.base = board->base;
++ tps->chip.base = -1;
+ tps->chip.ngpio = 7;
+ tps->chip.can_sleep = 1;
+
+@@ -641,7 +637,7 @@ static int tps65010_probe(struct i2c_client *client)
+ dev_err(&client->dev, "can't add gpiochip, err %d\n",
+ status);
+ else if (board->setup) {
+- status = board->setup(client, board->context);
++ status = board->setup(client, &tps->chip);
+ if (status < 0) {
+ dev_dbg(&client->dev,
+ "board %s %s err %d\n",
+diff --git a/include/linux/mfd/tps65010.h b/include/linux/mfd/tps65010.h
+index a1fb9bc5311de..5edf1aef11185 100644
+--- a/include/linux/mfd/tps65010.h
++++ b/include/linux/mfd/tps65010.h
+@@ -28,6 +28,8 @@
+ #ifndef __LINUX_I2C_TPS65010_H
+ #define __LINUX_I2C_TPS65010_H
+
++struct gpio_chip;
++
+ /*
+ * ----------------------------------------------------------------------------
+ * Registers, all 8 bits
+@@ -176,12 +178,10 @@ struct i2c_client;
+
+ /**
+ * struct tps65010_board - packages GPIO and LED lines
+- * @base: the GPIO number to assign to GPIO-1
+ * @outmask: bit (N-1) is set to allow GPIO-N to be used as an
+ * (open drain) output
+ * @setup: optional callback issued once the GPIOs are valid
+ * @teardown: optional callback issued before the GPIOs are invalidated
+- * @context: optional parameter passed to setup() and teardown()
+ *
+ * Board data may be used to package the GPIO (and LED) lines for use
+ * in by the generic GPIO and LED frameworks. The first four GPIOs
+@@ -193,12 +193,9 @@ struct i2c_client;
+ * devices in their initial states using these GPIOs.
+ */
+ struct tps65010_board {
+- int base;
+ unsigned outmask;
+-
+- int (*setup)(struct i2c_client *client, void *context);
+- int (*teardown)(struct i2c_client *client, void *context);
+- void *context;
++ int (*setup)(struct i2c_client *client, struct gpio_chip *gc);
++ void (*teardown)(struct i2c_client *client, struct gpio_chip *gc);
+ };
+
+ #endif /* __LINUX_I2C_TPS65010_H */
+--
+2.39.2
+
--- /dev/null
+From 865b34a8c2195bc139e3b6ae54703242fd93f96f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 May 2023 23:20:07 +0200
+Subject: ARM/mmc: Convert old mmci-omap to GPIO descriptors
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit e519f0bb64efc2c9c8b67bb2d114dda458bdc34d ]
+
+A recent change to the OMAP driver making it use a dynamic GPIO
+base created problems with some old OMAP1 board files, among
+them Nokia 770, SX1 and also the OMAP2 Nokia n8x0.
+
+Fix up all instances of GPIOs being used for the MMC driver
+by pushing the handling of power, slot selection and MMC
+"cover" into the driver as optional GPIOs.
+
+This is maybe not the most perfect solution as the MMC
+framework have some central handlers for some of the
+stuff, but it at least makes the situtation better and
+solves the immediate issue.
+
+Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base")
+Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap1/board-nokia770.c | 43 ++++---------
+ arch/arm/mach-omap1/board-sx1-mmc.c | 1 -
+ arch/arm/mach-omap2/board-n8x0.c | 85 ++++++++------------------
+ drivers/mmc/host/omap.c | 46 +++++++++++++-
+ include/linux/platform_data/mmc-omap.h | 2 -
+ 5 files changed, 83 insertions(+), 94 deletions(-)
+
+diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
+index a501a473ffd68..bde472d0c82f6 100644
+--- a/arch/arm/mach-omap1/board-nokia770.c
++++ b/arch/arm/mach-omap1/board-nokia770.c
+@@ -156,27 +156,23 @@ static struct omap_usb_config nokia770_usb_config __initdata = {
+
+ #if IS_ENABLED(CONFIG_MMC_OMAP)
+
+-#define NOKIA770_GPIO_MMC_POWER 41
+-#define NOKIA770_GPIO_MMC_SWITCH 23
+-
+-static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on,
+- int vdd)
+-{
+- gpio_set_value(NOKIA770_GPIO_MMC_POWER, power_on);
+- return 0;
+-}
+-
+-static int nokia770_mmc_get_cover_state(struct device *dev, int slot)
+-{
+- return gpio_get_value(NOKIA770_GPIO_MMC_SWITCH);
+-}
++static struct gpiod_lookup_table nokia770_mmc_gpio_table = {
++ .dev_id = "mmci-omap.1",
++ .table = {
++ /* Slot index 0, VSD power, GPIO 41 */
++ GPIO_LOOKUP_IDX("gpio-32-47", 9,
++ "vsd", 0, GPIO_ACTIVE_HIGH),
++ /* Slot index 0, switch, GPIO 23 */
++ GPIO_LOOKUP_IDX("gpio-16-31", 7,
++ "cover", 0, GPIO_ACTIVE_HIGH),
++ { }
++ },
++};
+
+ static struct omap_mmc_platform_data nokia770_mmc2_data = {
+ .nr_slots = 1,
+ .max_freq = 12000000,
+ .slots[0] = {
+- .set_power = nokia770_mmc_set_power,
+- .get_cover_state = nokia770_mmc_get_cover_state,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .name = "mmcblk",
+ },
+@@ -186,20 +182,7 @@ static struct omap_mmc_platform_data *nokia770_mmc_data[OMAP16XX_NR_MMC];
+
+ static void __init nokia770_mmc_init(void)
+ {
+- int ret;
+-
+- ret = gpio_request(NOKIA770_GPIO_MMC_POWER, "MMC power");
+- if (ret < 0)
+- return;
+- gpio_direction_output(NOKIA770_GPIO_MMC_POWER, 0);
+-
+- ret = gpio_request(NOKIA770_GPIO_MMC_SWITCH, "MMC cover");
+- if (ret < 0) {
+- gpio_free(NOKIA770_GPIO_MMC_POWER);
+- return;
+- }
+- gpio_direction_input(NOKIA770_GPIO_MMC_SWITCH);
+-
++ gpiod_add_lookup_table(&nokia770_mmc_gpio_table);
+ /* Only the second MMC controller is used */
+ nokia770_mmc_data[1] = &nokia770_mmc2_data;
+ omap1_init_mmc(nokia770_mmc_data, OMAP16XX_NR_MMC);
+diff --git a/arch/arm/mach-omap1/board-sx1-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c
+index f1c160924dfe4..f183a8448a7b0 100644
+--- a/arch/arm/mach-omap1/board-sx1-mmc.c
++++ b/arch/arm/mach-omap1/board-sx1-mmc.c
+@@ -9,7 +9,6 @@
+ * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT
+ */
+
+-#include <linux/gpio.h>
+ #include <linux/platform_device.h>
+
+ #include "hardware.h"
+diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
+index 3353b0a923d96..50b88eb23f9f8 100644
+--- a/arch/arm/mach-omap2/board-n8x0.c
++++ b/arch/arm/mach-omap2/board-n8x0.c
+@@ -11,6 +11,7 @@
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+ #include <linux/gpio.h>
++#include <linux/gpio/machine.h>
+ #include <linux/init.h>
+ #include <linux/io.h>
+ #include <linux/irq.h>
+@@ -170,22 +171,32 @@ static struct spi_board_info n800_spi_board_info[] __initdata = {
+ * GPIO23 and GPIO9 slot 2 EMMC on N810
+ *
+ */
+-#define N8X0_SLOT_SWITCH_GPIO 96
+-#define N810_EMMC_VSD_GPIO 23
+-#define N810_EMMC_VIO_GPIO 9
+-
+ static int slot1_cover_open;
+ static int slot2_cover_open;
+ static struct device *mmc_device;
+
+-static int n8x0_mmc_switch_slot(struct device *dev, int slot)
+-{
+-#ifdef CONFIG_MMC_DEBUG
+- dev_dbg(dev, "Choose slot %d\n", slot + 1);
+-#endif
+- gpio_set_value(N8X0_SLOT_SWITCH_GPIO, slot);
+- return 0;
+-}
++static struct gpiod_lookup_table nokia8xx_mmc_gpio_table = {
++ .dev_id = "mmci-omap.0",
++ .table = {
++ /* Slot switch, GPIO 96 */
++ GPIO_LOOKUP("gpio-80-111", 16,
++ "switch", GPIO_ACTIVE_HIGH),
++ { }
++ },
++};
++
++static struct gpiod_lookup_table nokia810_mmc_gpio_table = {
++ .dev_id = "mmci-omap.0",
++ .table = {
++ /* Slot index 1, VSD power, GPIO 23 */
++ GPIO_LOOKUP_IDX("gpio-16-31", 7,
++ "vsd", 1, GPIO_ACTIVE_HIGH),
++ /* Slot index 1, VIO power, GPIO 9 */
++ GPIO_LOOKUP_IDX("gpio-0-15", 9,
++ "vsd", 1, GPIO_ACTIVE_HIGH),
++ { }
++ },
++};
+
+ static int n8x0_mmc_set_power_menelaus(struct device *dev, int slot,
+ int power_on, int vdd)
+@@ -256,31 +267,13 @@ static int n8x0_mmc_set_power_menelaus(struct device *dev, int slot,
+ return 0;
+ }
+
+-static void n810_set_power_emmc(struct device *dev,
+- int power_on)
+-{
+- dev_dbg(dev, "Set EMMC power %s\n", power_on ? "on" : "off");
+-
+- if (power_on) {
+- gpio_set_value(N810_EMMC_VSD_GPIO, 1);
+- msleep(1);
+- gpio_set_value(N810_EMMC_VIO_GPIO, 1);
+- msleep(1);
+- } else {
+- gpio_set_value(N810_EMMC_VIO_GPIO, 0);
+- msleep(50);
+- gpio_set_value(N810_EMMC_VSD_GPIO, 0);
+- msleep(50);
+- }
+-}
+-
+ static int n8x0_mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+ {
+ if (board_is_n800() || slot == 0)
+ return n8x0_mmc_set_power_menelaus(dev, slot, power_on, vdd);
+
+- n810_set_power_emmc(dev, power_on);
++ /* The n810 power will be handled by GPIO code in the driver */
+
+ return 0;
+ }
+@@ -418,13 +411,6 @@ static void n8x0_mmc_shutdown(struct device *dev)
+ static void n8x0_mmc_cleanup(struct device *dev)
+ {
+ menelaus_unregister_mmc_callback();
+-
+- gpio_free(N8X0_SLOT_SWITCH_GPIO);
+-
+- if (board_is_n810()) {
+- gpio_free(N810_EMMC_VSD_GPIO);
+- gpio_free(N810_EMMC_VIO_GPIO);
+- }
+ }
+
+ /*
+@@ -433,7 +419,6 @@ static void n8x0_mmc_cleanup(struct device *dev)
+ */
+ static struct omap_mmc_platform_data mmc1_data = {
+ .nr_slots = 0,
+- .switch_slot = n8x0_mmc_switch_slot,
+ .init = n8x0_mmc_late_init,
+ .cleanup = n8x0_mmc_cleanup,
+ .shutdown = n8x0_mmc_shutdown,
+@@ -463,14 +448,9 @@ static struct omap_mmc_platform_data mmc1_data = {
+
+ static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC];
+
+-static struct gpio n810_emmc_gpios[] __initdata = {
+- { N810_EMMC_VSD_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vddf" },
+- { N810_EMMC_VIO_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vdd" },
+-};
+-
+ static void __init n8x0_mmc_init(void)
+ {
+- int err;
++ gpiod_add_lookup_table(&nokia8xx_mmc_gpio_table);
+
+ if (board_is_n810()) {
+ mmc1_data.slots[0].name = "external";
+@@ -483,20 +463,7 @@ static void __init n8x0_mmc_init(void)
+ */
+ mmc1_data.slots[1].name = "internal";
+ mmc1_data.slots[1].ban_openended = 1;
+- }
+-
+- err = gpio_request_one(N8X0_SLOT_SWITCH_GPIO, GPIOF_OUT_INIT_LOW,
+- "MMC slot switch");
+- if (err)
+- return;
+-
+- if (board_is_n810()) {
+- err = gpio_request_array(n810_emmc_gpios,
+- ARRAY_SIZE(n810_emmc_gpios));
+- if (err) {
+- gpio_free(N8X0_SLOT_SWITCH_GPIO);
+- return;
+- }
++ gpiod_add_lookup_table(&nokia810_mmc_gpio_table);
+ }
+
+ mmc1_data.nr_slots = 2;
+diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
+index cc2213ea324f1..566a09faaaced 100644
+--- a/drivers/mmc/host/omap.c
++++ b/drivers/mmc/host/omap.c
+@@ -26,6 +26,7 @@
+ #include <linux/clk.h>
+ #include <linux/scatterlist.h>
+ #include <linux/slab.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/platform_data/mmc-omap.h>
+
+
+@@ -111,6 +112,9 @@ struct mmc_omap_slot {
+ struct mmc_request *mrq;
+ struct mmc_omap_host *host;
+ struct mmc_host *mmc;
++ struct gpio_desc *vsd;
++ struct gpio_desc *vio;
++ struct gpio_desc *cover;
+ struct omap_mmc_slot_data *pdata;
+ };
+
+@@ -133,6 +137,7 @@ struct mmc_omap_host {
+ int irq;
+ unsigned char bus_mode;
+ unsigned int reg_shift;
++ struct gpio_desc *slot_switch;
+
+ struct work_struct cmd_abort_work;
+ unsigned abort:1;
+@@ -216,8 +221,13 @@ static void mmc_omap_select_slot(struct mmc_omap_slot *slot, int claimed)
+
+ if (host->current_slot != slot) {
+ OMAP_MMC_WRITE(host, CON, slot->saved_con & 0xFC00);
+- if (host->pdata->switch_slot != NULL)
+- host->pdata->switch_slot(mmc_dev(slot->mmc), slot->id);
++ if (host->slot_switch)
++ /*
++ * With two slots and a simple GPIO switch, setting
++ * the GPIO to 0 selects slot ID 0, setting it to 1
++ * selects slot ID 1.
++ */
++ gpiod_set_value(host->slot_switch, slot->id);
+ host->current_slot = slot;
+ }
+
+@@ -297,6 +307,9 @@ static void mmc_omap_release_slot(struct mmc_omap_slot *slot, int clk_enabled)
+ static inline
+ int mmc_omap_cover_is_open(struct mmc_omap_slot *slot)
+ {
++ /* If we have a GPIO then use that */
++ if (slot->cover)
++ return gpiod_get_value(slot->cover);
+ if (slot->pdata->get_cover_state)
+ return slot->pdata->get_cover_state(mmc_dev(slot->mmc),
+ slot->id);
+@@ -1106,6 +1119,11 @@ static void mmc_omap_set_power(struct mmc_omap_slot *slot, int power_on,
+
+ host = slot->host;
+
++ if (slot->vsd)
++ gpiod_set_value(slot->vsd, power_on);
++ if (slot->vio)
++ gpiod_set_value(slot->vio, power_on);
++
+ if (slot->pdata->set_power != NULL)
+ slot->pdata->set_power(mmc_dev(slot->mmc), slot->id, power_on,
+ vdd);
+@@ -1240,6 +1258,23 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id)
+ slot->power_mode = MMC_POWER_UNDEFINED;
+ slot->pdata = &host->pdata->slots[id];
+
++ /* Check for some optional GPIO controls */
++ slot->vsd = gpiod_get_index_optional(host->dev, "vsd",
++ id, GPIOD_OUT_LOW);
++ if (IS_ERR(slot->vsd))
++ return dev_err_probe(host->dev, PTR_ERR(slot->vsd),
++ "error looking up VSD GPIO\n");
++ slot->vio = gpiod_get_index_optional(host->dev, "vio",
++ id, GPIOD_OUT_LOW);
++ if (IS_ERR(slot->vio))
++ return dev_err_probe(host->dev, PTR_ERR(slot->vio),
++ "error looking up VIO GPIO\n");
++ slot->cover = gpiod_get_index_optional(host->dev, "cover",
++ id, GPIOD_IN);
++ if (IS_ERR(slot->cover))
++ return dev_err_probe(host->dev, PTR_ERR(slot->cover),
++ "error looking up cover switch GPIO\n");
++
+ host->slots[id] = slot;
+
+ mmc->caps = 0;
+@@ -1350,6 +1385,13 @@ static int mmc_omap_probe(struct platform_device *pdev)
+ if (IS_ERR(host->virt_base))
+ return PTR_ERR(host->virt_base);
+
++ host->slot_switch = gpiod_get_optional(host->dev, "switch",
++ GPIOD_OUT_LOW);
++ if (IS_ERR(host->slot_switch))
++ return dev_err_probe(host->dev, PTR_ERR(host->slot_switch),
++ "error looking up slot switch GPIO\n");
++
++
+ INIT_WORK(&host->slot_release_work, mmc_omap_slot_release_work);
+ INIT_WORK(&host->send_stop_work, mmc_omap_send_stop_work);
+
+diff --git a/include/linux/platform_data/mmc-omap.h b/include/linux/platform_data/mmc-omap.h
+index 91051e9907f34..054d0c3c5ec58 100644
+--- a/include/linux/platform_data/mmc-omap.h
++++ b/include/linux/platform_data/mmc-omap.h
+@@ -20,8 +20,6 @@ struct omap_mmc_platform_data {
+ * maximum frequency on the MMC bus */
+ unsigned int max_freq;
+
+- /* switch the bus to a new slot */
+- int (*switch_slot)(struct device *dev, int slot);
+ /* initialize board-specific MMC functionality, can be NULL if
+ * not supported */
+ int (*init)(struct device *dev);
+--
+2.39.2
+
--- /dev/null
+From 2f139c285f7332a13debbe4cd24ebab9c482ccde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Apr 2023 21:38:24 +0200
+Subject: ARM/musb: omap2: Remove global GPIO numbers from TUSB6010
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit 8e0285ab95a9baf374f2c13eb152221c8ecb3f28 ]
+
+The TUSB6010 (MUSB) device is picking up some GPIO lines
+hardcoded by number and passing on to the TUSB6010 device
+when registering it.
+
+Instead of nasty workarounds, provide a GPIO descriptor
+table and then make the TUSB6010 MUSB glue driver pick up
+the GPIO lines directly, convert it to an IRQ and pass down
+to the MUSB driver. OMAP2 is the only system using the
+TUSB6010.
+
+Stash the GPIO descriptors in the glue layer and use
+then to power up and down the TUSB6010 on-demand, instead
+of using boardfile callbacks.
+
+Since the OMAP2 boards are the only boards using the
+.set_power() and .board_set_power() callbacks, we can
+just delete them as the power is now handled directly
+in the TUSB6010 glue code.
+
+Cc: Bin Liu <b-liu@ti.com>
+Cc: linux-usb@vger.kernel.org
+Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base")
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/board-n8x0.c | 71 ++++++++----------------------
+ arch/arm/mach-omap2/usb-tusb6010.c | 20 ++-------
+ arch/arm/mach-omap2/usb-tusb6010.h | 12 +++++
+ drivers/usb/musb/musb_core.c | 1 -
+ drivers/usb/musb/musb_core.h | 2 -
+ drivers/usb/musb/tusb6010.c | 53 ++++++++++++++++------
+ include/linux/usb/musb.h | 13 ------
+ 7 files changed, 73 insertions(+), 99 deletions(-)
+ create mode 100644 arch/arm/mach-omap2/usb-tusb6010.h
+
+diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
+index 50b88eb23f9f8..564bf80a26212 100644
+--- a/arch/arm/mach-omap2/board-n8x0.c
++++ b/arch/arm/mach-omap2/board-n8x0.c
+@@ -10,8 +10,8 @@
+
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+-#include <linux/gpio.h>
+ #include <linux/gpio/machine.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/init.h>
+ #include <linux/io.h>
+ #include <linux/irq.h>
+@@ -29,13 +29,12 @@
+
+ #include "common.h"
+ #include "mmc.h"
++#include "usb-tusb6010.h"
+ #include "soc.h"
+ #include "common-board-devices.h"
+
+ #define TUSB6010_ASYNC_CS 1
+ #define TUSB6010_SYNC_CS 4
+-#define TUSB6010_GPIO_INT 58
+-#define TUSB6010_GPIO_ENABLE 0
+ #define TUSB6010_DMACHAN 0x3f
+
+ #define NOKIA_N810_WIMAX (1 << 2)
+@@ -62,37 +61,6 @@ static void board_check_revision(void)
+ }
+
+ #if IS_ENABLED(CONFIG_USB_MUSB_TUSB6010)
+-/*
+- * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
+- * 1.5 V voltage regulators of PM companion chip. Companion chip will then
+- * provide then PGOOD signal to TUSB6010 which will release it from reset.
+- */
+-static int tusb_set_power(int state)
+-{
+- int i, retval = 0;
+-
+- if (state) {
+- gpio_set_value(TUSB6010_GPIO_ENABLE, 1);
+- msleep(1);
+-
+- /* Wait until TUSB6010 pulls INT pin down */
+- i = 100;
+- while (i && gpio_get_value(TUSB6010_GPIO_INT)) {
+- msleep(1);
+- i--;
+- }
+-
+- if (!i) {
+- printk(KERN_ERR "tusb: powerup failed\n");
+- retval = -ENODEV;
+- }
+- } else {
+- gpio_set_value(TUSB6010_GPIO_ENABLE, 0);
+- msleep(10);
+- }
+-
+- return retval;
+-}
+
+ static struct musb_hdrc_config musb_config = {
+ .multipoint = 1,
+@@ -103,39 +71,36 @@ static struct musb_hdrc_config musb_config = {
+
+ static struct musb_hdrc_platform_data tusb_data = {
+ .mode = MUSB_OTG,
+- .set_power = tusb_set_power,
+ .min_power = 25, /* x2 = 50 mA drawn from VBUS as peripheral */
+ .power = 100, /* Max 100 mA VBUS for host mode */
+ .config = &musb_config,
+ };
+
++static struct gpiod_lookup_table tusb_gpio_table = {
++ .dev_id = "musb-tusb",
++ .table = {
++ GPIO_LOOKUP("gpio-0-15", 0, "enable",
++ GPIO_ACTIVE_HIGH),
++ GPIO_LOOKUP("gpio-48-63", 10, "int",
++ GPIO_ACTIVE_HIGH),
++ { }
++ },
++};
++
+ static void __init n8x0_usb_init(void)
+ {
+ int ret = 0;
+- static const char announce[] __initconst = KERN_INFO "TUSB 6010\n";
+-
+- /* PM companion chip power control pin */
+- ret = gpio_request_one(TUSB6010_GPIO_ENABLE, GPIOF_OUT_INIT_LOW,
+- "TUSB6010 enable");
+- if (ret != 0) {
+- printk(KERN_ERR "Could not get TUSB power GPIO%i\n",
+- TUSB6010_GPIO_ENABLE);
+- return;
+- }
+- tusb_set_power(0);
+
++ gpiod_add_lookup_table(&tusb_gpio_table);
+ ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2,
+- TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS,
+- TUSB6010_GPIO_INT, TUSB6010_DMACHAN);
++ TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS,
++ TUSB6010_DMACHAN);
+ if (ret != 0)
+- goto err;
++ return;
+
+- printk(announce);
++ pr_info("TUSB 6010\n");
+
+ return;
+-
+-err:
+- gpio_free(TUSB6010_GPIO_ENABLE);
+ }
+ #else
+
+diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
+index 18fa52f828dc7..b46c254c2bc41 100644
+--- a/arch/arm/mach-omap2/usb-tusb6010.c
++++ b/arch/arm/mach-omap2/usb-tusb6010.c
+@@ -11,12 +11,12 @@
+ #include <linux/errno.h>
+ #include <linux/delay.h>
+ #include <linux/platform_device.h>
+-#include <linux/gpio.h>
+ #include <linux/export.h>
+ #include <linux/platform_data/usb-omap.h>
+
+ #include <linux/usb/musb.h>
+
++#include "usb-tusb6010.h"
+ #include "gpmc.h"
+
+ static u8 async_cs, sync_cs;
+@@ -132,10 +132,6 @@ static struct resource tusb_resources[] = {
+ { /* Synchronous access */
+ .flags = IORESOURCE_MEM,
+ },
+- { /* IRQ */
+- .name = "mc",
+- .flags = IORESOURCE_IRQ,
+- },
+ };
+
+ static u64 tusb_dmamask = ~(u32)0;
+@@ -154,9 +150,9 @@ static struct platform_device tusb_device = {
+
+ /* this may be called only from board-*.c setup code */
+ int __init tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
+- unsigned ps_refclk, unsigned waitpin,
+- unsigned async, unsigned sync,
+- unsigned irq, unsigned dmachan)
++ unsigned int ps_refclk, unsigned int waitpin,
++ unsigned int async, unsigned int sync,
++ unsigned int dmachan)
+ {
+ int status;
+ static char error[] __initdata =
+@@ -192,14 +188,6 @@ int __init tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
+ if (status < 0)
+ return status;
+
+- /* IRQ */
+- status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq");
+- if (status < 0) {
+- printk(error, 3, status);
+- return status;
+- }
+- tusb_resources[2].start = gpio_to_irq(irq);
+-
+ /* set up memory timings ... can speed them up later */
+ if (!ps_refclk) {
+ printk(error, 4, status);
+diff --git a/arch/arm/mach-omap2/usb-tusb6010.h b/arch/arm/mach-omap2/usb-tusb6010.h
+new file mode 100644
+index 0000000000000..d210ff6238c26
+--- /dev/null
++++ b/arch/arm/mach-omap2/usb-tusb6010.h
+@@ -0,0 +1,12 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++
++#ifndef __USB_TUSB6010_H
++#define __USB_TUSB6010_H
++
++extern int __init tusb6010_setup_interface(
++ struct musb_hdrc_platform_data *data,
++ unsigned int ps_refclk, unsigned int waitpin,
++ unsigned int async_cs, unsigned int sync_cs,
++ unsigned int dmachan);
++
++#endif /* __USB_TUSB6010_H */
+diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
+index 648bb6021c5ef..dc773f4f6df2d 100644
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -2330,7 +2330,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
+
+ spin_lock_init(&musb->lock);
+ spin_lock_init(&musb->list_lock);
+- musb->board_set_power = plat->set_power;
+ musb->min_power = plat->min_power;
+ musb->ops = plat->platform_ops;
+ musb->port_mode = plat->mode;
+diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
+index b7588d11cfc59..91b5b6b66f963 100644
+--- a/drivers/usb/musb/musb_core.h
++++ b/drivers/usb/musb/musb_core.h
+@@ -352,8 +352,6 @@ struct musb {
+ u16 epmask;
+ u8 nr_endpoints;
+
+- int (*board_set_power)(int state);
+-
+ u8 min_power; /* vbus for periph, in mA/2 */
+
+ enum musb_mode port_mode;
+diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
+index 5609b4e84d40a..b5ba713d08592 100644
+--- a/drivers/usb/musb/tusb6010.c
++++ b/drivers/usb/musb/tusb6010.c
+@@ -11,6 +11,8 @@
+ * interface.
+ */
+
++#include <linux/gpio/consumer.h>
++#include <linux/delay.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+@@ -30,6 +32,8 @@ struct tusb6010_glue {
+ struct device *dev;
+ struct platform_device *musb;
+ struct platform_device *phy;
++ struct gpio_desc *enable;
++ struct gpio_desc *intpin;
+ };
+
+ static void tusb_musb_set_vbus(struct musb *musb, int is_on);
+@@ -1021,16 +1025,29 @@ static void tusb_setup_cpu_interface(struct musb *musb)
+
+ static int tusb_musb_start(struct musb *musb)
+ {
++ struct tusb6010_glue *glue = dev_get_drvdata(musb->controller->parent);
+ void __iomem *tbase = musb->ctrl_base;
+- int ret = 0;
+ unsigned long flags;
+ u32 reg;
++ int i;
+
+- if (musb->board_set_power)
+- ret = musb->board_set_power(1);
+- if (ret != 0) {
+- printk(KERN_ERR "tusb: Cannot enable TUSB6010\n");
+- return ret;
++ /*
++ * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
++ * 1.5 V voltage regulators of PM companion chip. Companion chip will then
++ * provide then PGOOD signal to TUSB6010 which will release it from reset.
++ */
++ gpiod_set_value(glue->enable, 1);
++ msleep(1);
++
++ /* Wait for 100ms until TUSB6010 pulls INT pin down */
++ i = 100;
++ while (i && gpiod_get_value(glue->intpin)) {
++ msleep(1);
++ i--;
++ }
++ if (!i) {
++ pr_err("tusb: Powerup respones failed\n");
++ return -ENODEV;
+ }
+
+ spin_lock_irqsave(&musb->lock, flags);
+@@ -1083,8 +1100,8 @@ static int tusb_musb_start(struct musb *musb)
+ err:
+ spin_unlock_irqrestore(&musb->lock, flags);
+
+- if (musb->board_set_power)
+- musb->board_set_power(0);
++ gpiod_set_value(glue->enable, 0);
++ msleep(10);
+
+ return -ENODEV;
+ }
+@@ -1158,11 +1175,13 @@ static int tusb_musb_init(struct musb *musb)
+
+ static int tusb_musb_exit(struct musb *musb)
+ {
++ struct tusb6010_glue *glue = dev_get_drvdata(musb->controller->parent);
++
+ del_timer_sync(&musb->dev_timer);
+ the_musb = NULL;
+
+- if (musb->board_set_power)
+- musb->board_set_power(0);
++ gpiod_set_value(glue->enable, 0);
++ msleep(10);
+
+ iounmap(musb->sync_va);
+
+@@ -1218,6 +1237,15 @@ static int tusb_probe(struct platform_device *pdev)
+
+ glue->dev = &pdev->dev;
+
++ glue->enable = devm_gpiod_get(glue->dev, "enable", GPIOD_OUT_LOW);
++ if (IS_ERR(glue->enable))
++ return dev_err_probe(glue->dev, PTR_ERR(glue->enable),
++ "could not obtain power on/off GPIO\n");
++ glue->intpin = devm_gpiod_get(glue->dev, "int", GPIOD_IN);
++ if (IS_ERR(glue->intpin))
++ return dev_err_probe(glue->dev, PTR_ERR(glue->intpin),
++ "could not obtain INT GPIO\n");
++
+ pdata->platform_ops = &tusb_ops;
+
+ usb_phy_generic_register();
+@@ -1236,10 +1264,7 @@ static int tusb_probe(struct platform_device *pdev)
+ musb_resources[1].end = pdev->resource[1].end;
+ musb_resources[1].flags = pdev->resource[1].flags;
+
+- musb_resources[2].name = pdev->resource[2].name;
+- musb_resources[2].start = pdev->resource[2].start;
+- musb_resources[2].end = pdev->resource[2].end;
+- musb_resources[2].flags = pdev->resource[2].flags;
++ musb_resources[2] = DEFINE_RES_IRQ_NAMED(gpiod_to_irq(glue->intpin), "mc");
+
+ pinfo = tusb_dev_info;
+ pinfo.parent = &pdev->dev;
+diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
+index e4a3ad3c800f5..3963e55e88a31 100644
+--- a/include/linux/usb/musb.h
++++ b/include/linux/usb/musb.h
+@@ -99,9 +99,6 @@ struct musb_hdrc_platform_data {
+ /* (HOST or OTG) program PHY for external Vbus */
+ unsigned extvbus:1;
+
+- /* Power the device on or off */
+- int (*set_power)(int state);
+-
+ /* MUSB configuration-specific details */
+ const struct musb_hdrc_config *config;
+
+@@ -135,14 +132,4 @@ static inline int musb_mailbox(enum musb_vbus_id_status status)
+ #define TUSB6010_REFCLK_24 41667 /* psec/clk @ 24.0 MHz XI */
+ #define TUSB6010_REFCLK_19 52083 /* psec/clk @ 19.2 MHz CLKIN */
+
+-#ifdef CONFIG_ARCH_OMAP2
+-
+-extern int __init tusb6010_setup_interface(
+- struct musb_hdrc_platform_data *data,
+- unsigned ps_refclk, unsigned waitpin,
+- unsigned async_cs, unsigned sync_cs,
+- unsigned irq, unsigned dmachan);
+-
+-#endif /* OMAP2 */
+-
+ #endif /* __LINUX_USB_MUSB_H */
+--
+2.39.2
+
--- /dev/null
+From 6aff4f5bca5fda2de67e9730c024fc73d1b6137e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Apr 2023 11:40:28 +0200
+Subject: ARM: omap1: Drop header on AMS Delta
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit fa1ae0cd897b089b5cc05ab471518ad13db2d567 ]
+
+The AMS Delta board uses GPIO descriptors exclusively and
+does not have any dependencies on the legacy <linux/gpio.h>
+header, so just drop it.
+
+Acked-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
+Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base")
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap1/board-ams-delta.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
+index 0f67ac4c6fd25..d9d2fef1b74a7 100644
+--- a/arch/arm/mach-omap1/board-ams-delta.c
++++ b/arch/arm/mach-omap1/board-ams-delta.c
+@@ -11,7 +11,6 @@
+ #include <linux/gpio/driver.h>
+ #include <linux/gpio/machine.h>
+ #include <linux/gpio/consumer.h>
+-#include <linux/gpio.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/input.h>
+--
+2.39.2
+
--- /dev/null
+From 182eacda642a37daf3a7472c091159b3f2bee9bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Apr 2023 19:56:37 +0200
+Subject: ARM: omap1: Exorcise the legacy GPIO header
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit c729baa8604226a8f878296bd145ab4046c80b12 ]
+
+After fixing all the offending users referencing the global GPIO
+numberspace in OMAP1, a few sites still remain including the
+legacy <linus/gpio.h> header for no reason.
+
+Delete the last remaining users, and OMAP1 is free from legacy
+GPIO dependencies.
+
+Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base")
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap1/devices.c | 1 -
+ arch/arm/mach-omap1/gpio15xx.c | 1 -
+ arch/arm/mach-omap1/gpio16xx.c | 1 -
+ arch/arm/mach-omap1/irq.c | 1 -
+ 4 files changed, 4 deletions(-)
+
+diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
+index 5304699c7a97e..8b2c5f911e973 100644
+--- a/arch/arm/mach-omap1/devices.c
++++ b/arch/arm/mach-omap1/devices.c
+@@ -6,7 +6,6 @@
+ */
+
+ #include <linux/dma-mapping.h>
+-#include <linux/gpio.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
+index 61fa26efd8653..6724af4925f24 100644
+--- a/arch/arm/mach-omap1/gpio15xx.c
++++ b/arch/arm/mach-omap1/gpio15xx.c
+@@ -8,7 +8,6 @@
+ * Charulatha V <charu@ti.com>
+ */
+
+-#include <linux/gpio.h>
+ #include <linux/platform_data/gpio-omap.h>
+ #include <linux/soc/ti/omap1-soc.h>
+ #include <asm/irq.h>
+diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
+index cf052714b3f8a..55acec22fef4e 100644
+--- a/arch/arm/mach-omap1/gpio16xx.c
++++ b/arch/arm/mach-omap1/gpio16xx.c
+@@ -8,7 +8,6 @@
+ * Charulatha V <charu@ti.com>
+ */
+
+-#include <linux/gpio.h>
+ #include <linux/platform_data/gpio-omap.h>
+ #include <linux/soc/ti/omap1-io.h>
+
+diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
+index 9ccc784fd6140..c780fa56bc638 100644
+--- a/arch/arm/mach-omap1/irq.c
++++ b/arch/arm/mach-omap1/irq.c
+@@ -35,7 +35,6 @@
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+-#include <linux/gpio.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/sched.h>
+--
+2.39.2
+
--- /dev/null
+From d0816bad3bb018430607ae6284f17ca24da1fd89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Apr 2023 11:56:23 +0200
+Subject: ARM: omap1: Remove reliance on GPIO numbers from PalmTE
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit 4c40db6249ff1da335b276bdd6c3c3462efbc2ab ]
+
+It appears this happens because the OMAP driver now
+allocates GPIO numbers dynamically, so all that is
+references by number is a bit up in the air.
+
+Utilize the NULL device to define some board-specific
+GPIO lookups and use these to immediately look up the
+same GPIOs, convert to IRQ numbers and pass as resources
+to the devices. This is ugly but should work.
+
+Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base")
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap1/board-palmte.c | 51 ++++++++++++++++++------------
+ 1 file changed, 31 insertions(+), 20 deletions(-)
+
+diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
+index f79c497f04d57..49b7757cb2fd3 100644
+--- a/arch/arm/mach-omap1/board-palmte.c
++++ b/arch/arm/mach-omap1/board-palmte.c
+@@ -13,7 +13,8 @@
+ *
+ * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
+ */
+-#include <linux/gpio.h>
++#include <linux/gpio/machine.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/input.h>
+@@ -187,23 +188,6 @@ static struct spi_board_info palmte_spi_info[] __initdata = {
+ },
+ };
+
+-static void __init palmte_misc_gpio_setup(void)
+-{
+- /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */
+- if (gpio_request(PALMTE_PINTDAV_GPIO, "TSC2102 PINTDAV") < 0) {
+- printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n");
+- return;
+- }
+- gpio_direction_input(PALMTE_PINTDAV_GPIO);
+-
+- /* Set USB-or-DC-IN pin as input (unused) */
+- if (gpio_request(PALMTE_USB_OR_DC_GPIO, "USB/DC-IN") < 0) {
+- printk(KERN_ERR "Could not reserve cable signal GPIO!\n");
+- return;
+- }
+- gpio_direction_input(PALMTE_USB_OR_DC_GPIO);
+-}
+-
+ #if IS_ENABLED(CONFIG_MMC_OMAP)
+
+ static struct omap_mmc_platform_data _palmte_mmc_config = {
+@@ -231,8 +215,23 @@ static void palmte_mmc_init(void)
+
+ #endif /* CONFIG_MMC_OMAP */
+
++static struct gpiod_lookup_table palmte_irq_gpio_table = {
++ .dev_id = NULL,
++ .table = {
++ /* GPIO used for TSC2102 PINTDAV IRQ */
++ GPIO_LOOKUP("gpio-0-15", PALMTE_PINTDAV_GPIO, "tsc2102_irq",
++ GPIO_ACTIVE_HIGH),
++ /* GPIO used for USB or DC input detection */
++ GPIO_LOOKUP("gpio-0-15", PALMTE_USB_OR_DC_GPIO, "usb_dc_irq",
++ GPIO_ACTIVE_HIGH),
++ { }
++ },
++};
++
+ static void __init omap_palmte_init(void)
+ {
++ struct gpio_desc *d;
++
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+@@ -243,9 +242,21 @@ static void __init omap_palmte_init(void)
+
+ platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
+
+- palmte_spi_info[0].irq = gpio_to_irq(PALMTE_PINTDAV_GPIO);
++ gpiod_add_lookup_table(&palmte_irq_gpio_table);
++ d = gpiod_get(NULL, "tsc2102_irq", GPIOD_IN);
++ if (IS_ERR(d))
++ pr_err("Unable to get TSC2102 IRQ GPIO descriptor\n");
++ else
++ palmte_spi_info[0].irq = gpiod_to_irq(d);
+ spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
+- palmte_misc_gpio_setup();
++
++ /* We are getting this just to set it up as input */
++ d = gpiod_get(NULL, "usb_dc_irq", GPIOD_IN);
++ if (IS_ERR(d))
++ pr_err("Unable to get USB/DC IRQ GPIO descriptor\n");
++ else
++ gpiod_put(d);
++
+ omap_serial_init();
+ omap1_usb_init(&palmte_usb_config);
+ omap_register_i2c_bus(1, 100, NULL, 0);
+--
+2.39.2
+
--- /dev/null
+From f435876b9f66d361fbc1897902cdbf7643d28acc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Apr 2023 17:45:29 +0200
+Subject: ARM: omap1: Remove reliance on GPIO numbers from SX1
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit 480c82daa3e41873421dc2c9e2918ad7e21d7a0b ]
+
+It appears this happens because the OMAP driver now
+allocates GPIO numbers dynamically, so all that is
+references by number is a bit up in the air.
+
+Utilize the NULL device to define some board-specific
+GPIO lookups and use these to immediately look up the
+same GPIOs, convert to IRQ numbers and pass as resources
+to the devices. This is ugly but should work.
+
+Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base")
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap1/board-sx1.c | 40 +++++++++++++++++++++++++++------
+ 1 file changed, 33 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
+index 0c0cdd5e77c79..a13c630be7b7f 100644
+--- a/arch/arm/mach-omap1/board-sx1.c
++++ b/arch/arm/mach-omap1/board-sx1.c
+@@ -11,7 +11,8 @@
+ * Maintainters : Vladimir Ananiev (aka Vovan888), Sergge
+ * oslik.ru
+ */
+-#include <linux/gpio.h>
++#include <linux/gpio/machine.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/input.h>
+@@ -304,8 +305,23 @@ static struct platform_device *sx1_devices[] __initdata = {
+
+ /*-----------------------------------------*/
+
++static struct gpiod_lookup_table sx1_gpio_table = {
++ .dev_id = NULL,
++ .table = {
++ GPIO_LOOKUP("gpio-0-15", 1, "irda_off",
++ GPIO_ACTIVE_HIGH),
++ GPIO_LOOKUP("gpio-0-15", 11, "switch",
++ GPIO_ACTIVE_HIGH),
++ GPIO_LOOKUP("gpio-0-15", 15, "usb_on",
++ GPIO_ACTIVE_HIGH),
++ { }
++ },
++};
++
+ static void __init omap_sx1_init(void)
+ {
++ struct gpio_desc *d;
++
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+@@ -320,15 +336,25 @@ static void __init omap_sx1_init(void)
+ omap_register_i2c_bus(1, 100, NULL, 0);
+ omap1_usb_init(&sx1_usb_config);
+ sx1_mmc_init();
++ gpiod_add_lookup_table(&sx1_gpio_table);
+
+ /* turn on USB power */
+ /* sx1_setusbpower(1); can't do it here because i2c is not ready */
+- gpio_request(1, "A_IRDA_OFF");
+- gpio_request(11, "A_SWITCH");
+- gpio_request(15, "A_USB_ON");
+- gpio_direction_output(1, 1); /*A_IRDA_OFF = 1 */
+- gpio_direction_output(11, 0); /*A_SWITCH = 0 */
+- gpio_direction_output(15, 0); /*A_USB_ON = 0 */
++ d = gpiod_get(NULL, "irda_off", GPIOD_OUT_HIGH);
++ if (IS_ERR(d))
++ pr_err("Unable to get IRDA OFF GPIO descriptor\n");
++ else
++ gpiod_put(d);
++ d = gpiod_get(NULL, "switch", GPIOD_OUT_LOW);
++ if (IS_ERR(d))
++ pr_err("Unable to get SWITCH GPIO descriptor\n");
++ else
++ gpiod_put(d);
++ d = gpiod_get(NULL, "usb_on", GPIOD_OUT_LOW);
++ if (IS_ERR(d))
++ pr_err("Unable to get USB ON GPIO descriptor\n");
++ else
++ gpiod_put(d);
+
+ omapfb_set_lcd_config(&sx1_lcd_config);
+ }
+--
+2.39.2
+
--- /dev/null
+From b37397386a95e5491916298830df41e0e4f8b28c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 May 2023 17:31:04 +0200
+Subject: ARM: omap2: fix missing tick_broadcast() prototype
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 861bc1d2886d47bd57a2cbf2cda87fdbe3eb9d08 ]
+
+omap2 contains a hack to define tick_broadcast() on non-SMP
+configurations in place of the normal SMP definition. This one
+causes a warning because of a missing prototype:
+
+arch/arm/mach-omap2/board-generic.c:44:6: error: no previous prototype for 'tick_broadcast'
+
+Make sure to always include the header with the declaration.
+
+Fixes: d86ad463d670 ("ARM: OMAP2+: Fix regression for using local timer on non-SMP SoCs")
+Acked-by: Aaro Koskinen <aaro.koskinen@iki.fi>
+Link: https://lore.kernel.org/r/20230516153109.514251-9-arnd@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/board-generic.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
+index 1610c567a6a3a..10d2f078e4a8e 100644
+--- a/arch/arm/mach-omap2/board-generic.c
++++ b/arch/arm/mach-omap2/board-generic.c
+@@ -13,6 +13,7 @@
+ #include <linux/of_platform.h>
+ #include <linux/irqdomain.h>
+ #include <linux/clocksource.h>
++#include <linux/clockchips.h>
+
+ #include <asm/setup.h>
+ #include <asm/mach/arch.h>
+--
+2.39.2
+
--- /dev/null
+From 8be1a6ee5ce8410c1c44b3bc878ebe6d01c9f8a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Mar 2023 14:19:44 +0800
+Subject: arm64: dts: mediatek: Add cpufreq nodes for MT8192
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Allen-KH Cheng <allen-kh.cheng@mediatek.com>
+
+[ Upstream commit 9d498cce9298a71e3896e2d1aee24a1a4c531d81 ]
+
+Add the cpufreq nodes for MT8192 SoC.
+
+Signed-off-by: Allen-KH Cheng <allen-kh.cheng@mediatek.com>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230317061944.15434-1-allen-kh.cheng@mediatek.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Stable-dep-of: a4366b5695c9 ("arm64: dts: mediatek: mt8192: Fix CPUs capacity-dmips-mhz")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8192.dtsi | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+index 87b91c8feaf96..ba49f37933d6d 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+@@ -70,6 +70,7 @@ cpu0: cpu@0 {
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_0>;
++ performance-domains = <&performance 0>;
+ capacity-dmips-mhz = <530>;
+ };
+
+@@ -87,6 +88,7 @@ cpu1: cpu@100 {
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_0>;
++ performance-domains = <&performance 0>;
+ capacity-dmips-mhz = <530>;
+ };
+
+@@ -104,6 +106,7 @@ cpu2: cpu@200 {
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_0>;
++ performance-domains = <&performance 0>;
+ capacity-dmips-mhz = <530>;
+ };
+
+@@ -121,6 +124,7 @@ cpu3: cpu@300 {
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_0>;
++ performance-domains = <&performance 0>;
+ capacity-dmips-mhz = <530>;
+ };
+
+@@ -138,6 +142,7 @@ cpu4: cpu@400 {
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>;
+ next-level-cache = <&l2_1>;
++ performance-domains = <&performance 1>;
+ capacity-dmips-mhz = <1024>;
+ };
+
+@@ -155,6 +160,7 @@ cpu5: cpu@500 {
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>;
+ next-level-cache = <&l2_1>;
++ performance-domains = <&performance 1>;
+ capacity-dmips-mhz = <1024>;
+ };
+
+@@ -172,6 +178,7 @@ cpu6: cpu@600 {
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>;
+ next-level-cache = <&l2_1>;
++ performance-domains = <&performance 1>;
+ capacity-dmips-mhz = <1024>;
+ };
+
+@@ -189,6 +196,7 @@ cpu7: cpu@700 {
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>;
+ next-level-cache = <&l2_1>;
++ performance-domains = <&performance 1>;
+ capacity-dmips-mhz = <1024>;
+ };
+
+@@ -318,6 +326,12 @@ soc {
+ compatible = "simple-bus";
+ ranges;
+
++ performance: performance-controller@11bc10 {
++ compatible = "mediatek,cpufreq-hw";
++ reg = <0 0x0011bc10 0 0x120>, <0 0x0011bd30 0 0x120>;
++ #performance-domain-cells = <1>;
++ };
++
+ gic: interrupt-controller@c000000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <4>;
+--
+2.39.2
+
--- /dev/null
+From 291555a3d580c4b51a681f9c9ddb20a1626acaa7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 13:13:52 -0700
+Subject: arm64: dts: mediatek: mt8183: Add mediatek,broken-save-restore-fw to
+ kukui
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 42127f578ebde652d1373e0233356fbd351675c4 ]
+
+Firmware shipped on mt8183 Chromebooks is affected by the GICR
+save/restore issue as described by the patch ("dt-bindings:
+interrupt-controller: arm,gic-v3: Add quirk for Mediatek SoCs w/
+broken FW"). Add the quirk property.
+
+Fixes: cd894e274b74 ("arm64: dts: mt8183: Add krane-sku176 board")
+Reviewed-by: Julius Werner <jwerner@chromium.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230515131353.v2.3.I525a2ed4260046d43c885ee1275e91707743df1c@changeid
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+index fbe14b13051a6..4836ad55fd4ae 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+@@ -292,6 +292,10 @@ dsi_out: endpoint {
+ };
+ };
+
++&gic {
++ mediatek,broken-save-restore-fw;
++};
++
+ &gpu {
+ mali-supply = <&mt6358_vgpu_reg>;
+ sram-supply = <&mt6358_vsram_gpu_reg>;
+--
+2.39.2
+
--- /dev/null
+From 0fab7223de08e0252bb13fc1c2a34e88fe024082 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 14:35:15 -0400
+Subject: arm64: dts: mediatek: mt8192: Fix CPUs capacity-dmips-mhz
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit a4366b5695c984b8a3fc8b31de9e758c8f6d1aed ]
+
+The capacity-dmips-mhz parameter was miscalculated: this SoC runs
+the first (Cortex-A55) cluster at a maximum of 2000MHz and the
+second (Cortex-A76) cluster at a maximum of 2200MHz.
+
+In order to calculate the right capacity-dmips-mhz, the following
+test was performed:
+1. CPUFREQ governor was set to 'performance' on both clusters
+2. Ran dhrystone with 500000000 iterations for 10 times on each cluster
+3. Calculated the mean result for each cluster
+4. Calculated DMIPS/MHz: dmips_mhz = dmips_per_second / cpu_mhz
+5. Scaled results to 1024:
+ result_c0 = dmips_mhz_c0 / dmips_mhz_c1 * 1024
+
+The mean results for this SoC are:
+Cluster 0 (LITTLE): 12016411 Dhry/s
+Cluster 1 (BIG): 31702034 Dhry/s
+
+The calculated scaled results are:
+Cluster 0: 426.953226899238 (rounded to 427)
+Cluster 1: 1024
+
+Fixes: 48489980e27e ("arm64: dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230602183515.3778780-1-nfraprado@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8192.dtsi | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+index ba49f37933d6d..a3a2b7de54a7c 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+@@ -71,7 +71,7 @@ cpu0: cpu@0 {
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_0>;
+ performance-domains = <&performance 0>;
+- capacity-dmips-mhz = <530>;
++ capacity-dmips-mhz = <427>;
+ };
+
+ cpu1: cpu@100 {
+@@ -89,7 +89,7 @@ cpu1: cpu@100 {
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_0>;
+ performance-domains = <&performance 0>;
+- capacity-dmips-mhz = <530>;
++ capacity-dmips-mhz = <427>;
+ };
+
+ cpu2: cpu@200 {
+@@ -107,7 +107,7 @@ cpu2: cpu@200 {
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_0>;
+ performance-domains = <&performance 0>;
+- capacity-dmips-mhz = <530>;
++ capacity-dmips-mhz = <427>;
+ };
+
+ cpu3: cpu@300 {
+@@ -125,7 +125,7 @@ cpu3: cpu@300 {
+ d-cache-sets = <128>;
+ next-level-cache = <&l2_0>;
+ performance-domains = <&performance 0>;
+- capacity-dmips-mhz = <530>;
++ capacity-dmips-mhz = <427>;
+ };
+
+ cpu4: cpu@400 {
+--
+2.39.2
+
--- /dev/null
+From e15262d1d146f8c531a2f6a05e3da770da8f9bc9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Feb 2023 11:50:37 +0100
+Subject: arm64: dts: microchip: sparx5: do not use PSCI on reference boards
+
+From: Robert Marko <robert.marko@sartura.hr>
+
+[ Upstream commit 70be83708c925b3f72c508e4756e48ad2330c830 ]
+
+PSCI is not implemented on SparX-5 at all, there is no ATF and U-boot that
+is shipped does not implement it as well.
+
+I have tried flashing the latest BSP 2022.12 U-boot which did not work.
+After contacting Microchip, they confirmed that there is no ATF for the
+SoC nor PSCI implementation which is unfortunate in 2023.
+
+So, disable PSCI as otherwise kernel crashes as soon as it tries probing
+PSCI with, and the crash is only visible if earlycon is used.
+
+Since PSCI is not implemented, switch core bringup to use spin-tables
+which are implemented in the vendor U-boot and actually work.
+
+Tested on PCB134 with eMMC (VSC5640EV).
+
+Fixes: 6694aee00a4b ("arm64: dts: sparx5: Add basic cpu support")
+Signed-off-by: Robert Marko <robert.marko@sartura.hr>
+Acked-by: Steen Hegelund <Steen.Hegelund@microchip.com>
+Link: https://lore.kernel.org/r/20230221105039.316819-1-robert.marko@sartura.hr
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/microchip/sparx5.dtsi | 2 +-
+ arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi | 12 ++++++++++++
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi
+index 0367a00a269b3..5eae6e7fd248e 100644
+--- a/arch/arm64/boot/dts/microchip/sparx5.dtsi
++++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi
+@@ -61,7 +61,7 @@ arm-pmu {
+ interrupt-affinity = <&cpu0>, <&cpu1>;
+ };
+
+- psci {
++ psci: psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi
+index 9d1a082de3e29..32bb76b3202a0 100644
+--- a/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi
++++ b/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi
+@@ -6,6 +6,18 @@
+ /dts-v1/;
+ #include "sparx5.dtsi"
+
++&psci {
++ status = "disabled";
++};
++
++&cpu0 {
++ enable-method = "spin-table";
++};
++
++&cpu1 {
++ enable-method = "spin-table";
++};
++
+ &uart0 {
+ status = "okay";
+ };
+--
+2.39.2
+
--- /dev/null
+From bda3e1762165f46a15acab662254b38c671267b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 16:43:20 +0100
+Subject: arm64: dts: mt7986: increase bl2 partition on NAND of Bananapi R3
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+[ Upstream commit 3bfbff9b461e3506dfb5b2904e8c15a0aea39e07 ]
+
+The bootrom burned into the MT7986 SoC will try multiple locations on
+the SPI-NAND flash to load bl2 in case the bl2 image located at the the
+previously attempted offset is corrupt.
+
+Use 0x100000 instead of 0x80000 as partition size for bl2 on SPI-NAND,
+allowing for up to four redundant copies of bl2 (typically sized a
+bit less than 0x40000).
+
+Fixes: 8e01fb15b8157 ("arm64: dts: mt7986: add Bananapi R3")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/ZH9UGF99RgzrHZ88@makrotopia.org
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
+index 15ee8c568f3c3..543c13385d6e3 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
+@@ -29,13 +29,13 @@ partitions {
+
+ partition@0 {
+ label = "bl2";
+- reg = <0x0 0x80000>;
++ reg = <0x0 0x100000>;
+ read-only;
+ };
+
+- partition@80000 {
++ partition@100000 {
+ label = "reserved";
+- reg = <0x80000 0x300000>;
++ reg = <0x100000 0x280000>;
+ };
+
+ partition@380000 {
+--
+2.39.2
+
--- /dev/null
+From 7ca749d8f5690d156f37bae7e9e57a0674d66eb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 20:48:41 +0200
+Subject: arm64: dts: qcom: apq8016-sbc: Fix 1.8V power rail on LS expansion
+
+From: Stephan Gerhold <stephan@gerhold.net>
+
+[ Upstream commit 5500f823db38db073d30557af159b77fb1f2bf26 ]
+
+The 96Boards specification expects a 1.8V power rail on the low-speed
+expansion connector that is able to provide at least 0.18W / 100 mA.
+According to the DB410c hardware user manual this is done by connecting
+both L15 and L16 in parallel with up to 55mA each (for 110 mA total) [1].
+
+Unfortunately the current regulator setup in the DB410c device tree
+does not implement the specification correctly and only provides 5 mA:
+
+ - Only L15 is marked always-on, so L16 is never enabled.
+ - Without specifying a load the regulator is put into LPM where
+ it can only provide 5 mA.
+
+Fix this by:
+
+ - Adding proper voltage constraints for L16.
+ - Making L16 always-on.
+ - Adding regulator-system-load for both L15 and L16. 100 mA should be
+ available in total, so specify 50 mA for each. (The regulator
+ hardware can only be in normal (55 mA) or low-power mode (5 mA) so
+ this will actually result in the expected 110 mA total...)
+
+[1]: https://www.96boards.org/documentation/consumer/dragonboard/dragonboard410c/hardware-docs/hardware-user-manual.md.html#power-supplies
+
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Fixes: 828dd5d66f0f ("arm64: dts: apq8016-sbc: make 1.8v available on LS expansion")
+Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230510-msm8916-regulators-v1-2-54d4960a05fc@gerhold.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+index d7d7a826b8be4..dbdb8077857ef 100644
+--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
++++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+@@ -526,19 +526,27 @@ l14 {
+ regulator-max-microvolt = <3300000>;
+ };
+
+- /**
+- * 1.8v required on LS expansion
+- * for mezzanine boards
++ /*
++ * The 96Boards specification expects a 1.8V power rail on the low-speed
++ * expansion connector that is able to provide at least 0.18W / 100 mA.
++ * L15/L16 are connected in parallel to provide 55 mA each. A minimum load
++ * must be specified to ensure the regulators are not put in LPM where they
++ * would only provide 5 mA.
+ */
+ l15 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
++ regulator-system-load = <50000>;
++ regulator-allow-set-load;
+ regulator-always-on;
+ };
+
+ l16 {
+ regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-system-load = <50000>;
++ regulator-allow-set-load;
++ regulator-always-on;
+ };
+
+ l17 {
+--
+2.39.2
+
--- /dev/null
+From 1c11f99007c16c15160ea4cafababad1050ac64a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 20:48:40 +0200
+Subject: arm64: dts: qcom: apq8016-sbc: Fix regulator constraints
+
+From: Stephan Gerhold <stephan@gerhold.net>
+
+[ Upstream commit e27654df20d77ad7549a3cf6739ebaa3aa59a088 ]
+
+For some reason DB410c has completely bogus regulator constraints that
+actually just correspond to the programmable voltages which are already
+provided by the regulator driver. Some of them are not just outside the
+recommended operating conditions of the APQ8016E SoC but even exceed
+the absolute maximum ratings, potentially risking permanent device
+damage.
+
+In practice it's not quite as dangerous thanks to the RPM firmware:
+It turns out that it has its own voltage constraints and silently
+clamps all regulator requests. For example, requesting 3.3V for L5
+(allowed by the current regulator constraints!) still results in 1.8V
+being programmed in the actual regulator hardware.
+
+Experimentation with various voltages shows that the internal RPM
+voltage constraints roughly correspond to the safe "specified range"
+in the PM8916 Device Specification (rather than the "programmable
+range" used inside apq8016-sbc.dtsi right now).
+
+Combine those together with some fixed voltages used in the old
+msm-3.10 device tree from Qualcomm to give DB410c some actually valid
+voltage constraints.
+
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Fixes: 4c7d53d16d77 ("arm64: dts: apq8016-sbc: add regulators support")
+Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230510-msm8916-regulators-v1-1-54d4960a05fc@gerhold.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 64 ++++++++++++------------
+ 1 file changed, 32 insertions(+), 32 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+index 27ceaa94c8bda..d7d7a826b8be4 100644
+--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
++++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+@@ -447,21 +447,21 @@ &smd_rpm_regulators {
+ vdd_l7-supply = <&pm8916_s4>;
+
+ s3 {
+- regulator-min-microvolt = <375000>;
+- regulator-max-microvolt = <1562000>;
++ regulator-min-microvolt = <1250000>;
++ regulator-max-microvolt = <1350000>;
+ };
+
+ s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
++ regulator-min-microvolt = <1850000>;
++ regulator-max-microvolt = <2150000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ l1 {
+- regulator-min-microvolt = <375000>;
+- regulator-max-microvolt = <1525000>;
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
+ };
+
+ l2 {
+@@ -470,13 +470,13 @@ l2 {
+ };
+
+ l4 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <2050000>;
++ regulator-max-microvolt = <2050000>;
+ };
+
+ l5 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
+ };
+
+ l6 {
+@@ -485,45 +485,45 @@ l6 {
+ };
+
+ l7 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
+ };
+
+ l8 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <2900000>;
++ regulator-max-microvolt = <2900000>;
+ };
+
+ l9 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
+ };
+
+ l10 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
+ };
+
+ l11 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
+ regulator-allow-set-load;
+ regulator-system-load = <200000>;
+ };
+
+ l12 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
+ };
+
+ l13 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <3075000>;
++ regulator-max-microvolt = <3075000>;
+ };
+
+ l14 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
+ };
+
+ /**
+@@ -531,14 +531,14 @@ l14 {
+ * for mezzanine boards
+ */
+ l15 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ l16 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
+ };
+
+ l17 {
+@@ -547,8 +547,8 @@ l17 {
+ };
+
+ l18 {
+- regulator-min-microvolt = <1750000>;
+- regulator-max-microvolt = <3337000>;
++ regulator-min-microvolt = <2700000>;
++ regulator-max-microvolt = <2700000>;
+ };
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 3086485da011d1023b7a782f5ab19b273eba3843 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 May 2023 19:45:16 +0200
+Subject: arm64: dts: qcom: apq8096: fix fixed regulator name property
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit c77612a07d18d4425fd8ddd532a8a9b8e1970c53 ]
+
+Correct the typo in 'regulator-name' property.
+
+ apq8096-ifc6640.dtb: v1p05-regulator: 'regulator-name' is a required property
+ apq8096-ifc6640.dtb: v1p05-regulator: Unevaluated properties are not allowed ('reglator-name' was unexpected)
+
+Fixes: 6cbdec2d3ca6 ("arm64: dts: qcom: msm8996: Introduce IFC6640")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230507174516.264936-3-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
+index 71e0a500599c8..ed2e2f6c6775a 100644
+--- a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
++++ b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
+@@ -26,7 +26,7 @@ chosen {
+
+ v1p05: v1p05-regulator {
+ compatible = "regulator-fixed";
+- reglator-name = "v1p05";
++ regulator-name = "v1p05";
+ regulator-always-on;
+ regulator-boot-on;
+
+@@ -38,7 +38,7 @@ v1p05: v1p05-regulator {
+
+ v12_poe: v12-poe-regulator {
+ compatible = "regulator-fixed";
+- reglator-name = "v12_poe";
++ regulator-name = "v12_poe";
+ regulator-always-on;
+ regulator-boot-on;
+
+--
+2.39.2
+
--- /dev/null
+From 9abbffcf9b57aee33725177aefd23428fb65be5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:39 +0200
+Subject: arm64: dts: qcom: ipq6018: correct qrng unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 085058786a7890dd44ec623fe5ac74db870f6b93 ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc/qrng@e1000: simple-bus unit address format error, expected "e3000"
+
+Fixes: 5bf635621245 ("arm64: dts: ipq6018: Add a few device nodes")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+index 9ff4e9d45065b..8ec9e282b412c 100644
+--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+@@ -301,7 +301,7 @@ mdio: mdio@90000 {
+ status = "disabled";
+ };
+
+- prng: qrng@e1000 {
++ prng: qrng@e3000 {
+ compatible = "qcom,prng-ee";
+ reg = <0x0 0x000e3000 0x0 0x1000>;
+ clocks = <&gcc GCC_PRNG_AHB_CLK>;
+--
+2.39.2
+
--- /dev/null
+From a7775ede6505f95dc4db170d7307d0516eed4af3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:40 +0200
+Subject: arm64: dts: qcom: msm8916: correct camss unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 48798d992ce276cf0d57bf75318daf8eabd02aa4 ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc@0/camss@1b00000: simple-bus unit address format error, expected "1b0ac00"
+
+Fixes: 58f479f90a7c ("arm64: dts: qcom: msm8916: Add CAMSS support")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+index 0d5283805f42c..7f09b7f56dfa4 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -1161,7 +1161,7 @@ dsi_phy0: phy@1a98300 {
+ };
+ };
+
+- camss: camss@1b00000 {
++ camss: camss@1b0ac00 {
+ compatible = "qcom,msm8916-camss";
+ reg = <0x01b0ac00 0x200>,
+ <0x01b00030 0x4>,
+--
+2.39.2
+
--- /dev/null
+From 0dc57e3efb6de330ee59189fc3248d534c9eec04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:41 +0200
+Subject: arm64: dts: qcom: msm8916: correct MMC unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 72644bc76d5145c098c268829554a0b98fab1de1 ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc@0/mmc@7824000: simple-bus unit address format error, expected "7824900"
+ Warning (simple_bus_reg): /soc@0/mmc@7864000: simple-bus unit address format error, expected "7864900"
+
+Fixes: c4da5a561627 ("arm64: dts: qcom: Add msm8916 sdhci configuration nodes")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-3-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+index 7f09b7f56dfa4..9bbe97902f0fe 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -1553,7 +1553,7 @@ lpass_codec: audio-codec@771c000 {
+ #sound-dai-cells = <1>;
+ };
+
+- sdhc_1: mmc@7824000 {
++ sdhc_1: mmc@7824900 {
+ compatible = "qcom,msm8916-sdhci", "qcom,sdhci-msm-v4";
+ reg = <0x07824900 0x11c>, <0x07824000 0x800>;
+ reg-names = "hc", "core";
+@@ -1571,7 +1571,7 @@ sdhc_1: mmc@7824000 {
+ status = "disabled";
+ };
+
+- sdhc_2: mmc@7864000 {
++ sdhc_2: mmc@7864900 {
+ compatible = "qcom,msm8916-sdhci", "qcom,sdhci-msm-v4";
+ reg = <0x07864900 0x11c>, <0x07864000 0x800>;
+ reg-names = "hc", "core";
+--
+2.39.2
+
--- /dev/null
+From b4d85cd0c7f3144ec7b53ba4eeebfc5c026e04a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:42 +0200
+Subject: arm64: dts: qcom: msm8916: correct WCNSS unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 1f9a41bb0bba7b373c26a6f2cc8d35cc3159c861 ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc@0/remoteproc@a21b000: simple-bus unit address format error, expected "a204000"
+
+Fixes: 88106096cbf8 ("ARM: dts: msm8916: Add and enable wcnss node")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-4-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+index 80f210e55657c..7cc3d0d92cb9e 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -1870,7 +1870,7 @@ usb_hs_phy: phy {
+ };
+ };
+
+- wcnss: remoteproc@a21b000 {
++ wcnss: remoteproc@a204000 {
+ compatible = "qcom,pronto-v2-pil", "qcom,pronto";
+ reg = <0x0a204000 0x2000>, <0x0a202000 0x1000>, <0x0a21b000 0x3000>;
+ reg-names = "ccu", "dxe", "pmu";
+--
+2.39.2
+
--- /dev/null
+From 7f5a7517f09849ca180b9838c7355f6d1f8b847a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Mar 2023 10:14:52 +0100
+Subject: arm64: dts: qcom: msm8916: Move WCN compatible to boards
+
+From: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+
+[ Upstream commit 3244442406ff49e8f75a1f2def211c497710570f ]
+
+On MSM8916 the wireless connectivity functionality (WiFi/Bluetooth) is
+split into the digital part inside the SoC and the analog RF part inside
+a supplementary WCN36xx chip. For MSM8916, three different options
+exist:
+
+ - WCN3620 (WLAN 802.11 b/g/n 2.4 GHz + Bluetooth)
+ - WCN3660B (WLAN 802.11 a/b/g/n 2.4/5 GHz + Bluetooth)
+ - WCN3680B (WLAN 802.11ac 2.4/5 GHz + Bluetooth)
+
+Choosing one of these is up to the board vendor. This means that the
+compatible belongs into the board-specific DT part so people porting
+new boards pay attention to set the correct compatible.
+
+Right now msm8916.dtsi sets "qcom,wcn3620" as default compatible,
+which does not work at all for boards that have WCN3660B or WCN3680B.
+
+Remove the default compatible from msm8196.dtsi and move it to the board
+DT as follows:
+
+ - Boards with only &pronto { status = "okay"; } used the default
+ "qcom,wcn3620" so far. They now set this explicitly for &wcnss_iris.
+ - Boards with &pronto { ... iris { compatible = "qcom,wcn3660b"; }};
+ already had an override that just moves to &wcnss_iris now.
+ - For msm8916-samsung-a2015-common.dtsi the WCN compatible differs for
+ boards making use of it (a3u: wcn3620, a5u: wcn3660b, e2015: wcn3620)
+ so the definitions move to the board-specific DT part.
+
+Since this requires touching all the board DTs, use this as a chance to
+name the WCNSS-related labels consistently, so everything is grouped
+properly when sorted alphabetically.
+
+No functional change, just clean-up for more clarity & easier porting.
+Aside from ordering the generated DTBs are identical.
+
+Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230309091452.1011776-1-stephan.gerhold@kernkonzept.com
+Stable-dep-of: 1f9a41bb0bba ("arm64: dts: qcom: msm8916: correct WCNSS unit address")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 15 ++++++++-----
+ .../boot/dts/qcom/msm8916-acer-a1-724.dts | 12 ++++++----
+ .../boot/dts/qcom/msm8916-alcatel-idol347.dts | 12 ++++++----
+ .../arm64/boot/dts/qcom/msm8916-asus-z00l.dts | 12 ++++++----
+ .../boot/dts/qcom/msm8916-gplus-fl8005a.dts | 12 ++++++----
+ .../arm64/boot/dts/qcom/msm8916-huawei-g7.dts | 12 ++++++----
+ .../boot/dts/qcom/msm8916-longcheer-l8150.dts | 12 ++++++----
+ .../boot/dts/qcom/msm8916-longcheer-l8910.dts | 12 ++++++----
+ arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi | 22 +++++++++----------
+ .../qcom/msm8916-samsung-a2015-common.dtsi | 4 ----
+ .../boot/dts/qcom/msm8916-samsung-a3u-eur.dts | 8 +++++++
+ .../boot/dts/qcom/msm8916-samsung-a5u-eur.dts | 14 +++++++-----
+ .../qcom/msm8916-samsung-e2015-common.dtsi | 8 +++++++
+ .../dts/qcom/msm8916-samsung-gt5-common.dtsi | 16 +++++++-------
+ .../dts/qcom/msm8916-samsung-j5-common.dtsi | 12 ++++++----
+ .../dts/qcom/msm8916-samsung-serranove.dts | 16 +++++++-------
+ arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi | 12 ++++++----
+ .../dts/qcom/msm8916-wingtech-wt88047.dts | 12 ++++++----
+ arch/arm64/boot/dts/qcom/msm8916.dtsi | 13 +++++------
+ 19 files changed, 146 insertions(+), 90 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+index c52d79a55d80c..27ceaa94c8bda 100644
+--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
++++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+@@ -325,12 +325,6 @@ &pm8916_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
+-&pronto {
+- status = "okay";
+-
+- firmware-name = "qcom/apq8016/wcnss.mbn";
+-};
+-
+ &sdhc_1 {
+ status = "okay";
+
+@@ -411,10 +405,19 @@ &wcd_codec {
+ qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
+ };
+
++&wcnss {
++ status = "okay";
++ firmware-name = "qcom/apq8016/wcnss.mbn";
++};
++
+ &wcnss_ctrl {
+ firmware-name = "qcom/apq8016/WCNSS_qcom_wlan_nv_sbc.bin";
+ };
+
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ /* Enable CoreSight */
+ &cti0 { status = "okay"; };
+ &cti1 { status = "okay"; };
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
+index ed3fa7b3575b7..13cd9ad167df7 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-acer-a1-724.dts
+@@ -118,10 +118,6 @@ &pm8916_vib {
+ status = "okay";
+ };
+
+-&pronto {
+- status = "okay";
+-};
+-
+ &sdhc_1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>;
+@@ -149,6 +145,14 @@ &usb_hs_phy {
+ extcon = <&usb_id>;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ &smd_rpm_regulators {
+ vdd_l1_l2_l3-supply = <&pm8916_s3>;
+ vdd_l4_l5_l6-supply = <&pm8916_s4>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts b/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
+index 701a5585d77e4..fecb69944cfa3 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-alcatel-idol347.dts
+@@ -160,10 +160,6 @@ &pm8916_vib {
+ status = "okay";
+ };
+
+-&pronto {
+- status = "okay";
+-};
+-
+ &sdhc_1 {
+ status = "okay";
+
+@@ -191,6 +187,14 @@ &usb_hs_phy {
+ extcon = <&usb_id>;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ &smd_rpm_regulators {
+ vdd_l1_l2_l3-supply = <&pm8916_s3>;
+ vdd_l4_l5_l6-supply = <&pm8916_s4>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts b/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
+index 3618704a53309..91284a1d0966f 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-asus-z00l.dts
+@@ -128,10 +128,6 @@ &blsp1_uart2 {
+ status = "okay";
+ };
+
+-&pronto {
+- status = "okay";
+-};
+-
+ &sdhc_1 {
+ status = "okay";
+
+@@ -159,6 +155,14 @@ &usb_hs_phy {
+ extcon = <&usb_id>;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ &smd_rpm_regulators {
+ vdd_l1_l2_l3-supply = <&pm8916_s3>;
+ vdd_l4_l5_l6-supply = <&pm8916_s4>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
+index a0e520edde029..525ec76efeeb7 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-gplus-fl8005a.dts
+@@ -118,10 +118,6 @@ &pm8916_vib {
+ status = "okay";
+ };
+
+-&pronto {
+- status = "okay";
+-};
+-
+ &sdhc_1 {
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>;
+@@ -149,6 +145,14 @@ &usb_hs_phy {
+ extcon = <&usb_id>;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ &smd_rpm_regulators {
+ vdd_l1_l2_l3-supply = <&pm8916_s3>;
+ vdd_l4_l5_l6-supply = <&pm8916_s4>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
+index 8c07eca900d3f..5b1bac8f51220 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
+@@ -227,10 +227,6 @@ &pm8916_vib {
+ status = "okay";
+ };
+
+-&pronto {
+- status = "okay";
+-};
+-
+ &sdhc_1 {
+ status = "okay";
+
+@@ -312,6 +308,14 @@ &wcd_codec {
+ qcom,hphl-jack-type-normally-open;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ &smd_rpm_regulators {
+ vdd_l1_l2_l3-supply = <&pm8916_s3>;
+ vdd_l4_l5_l6-supply = <&pm8916_s4>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+index d1e8cf2f50c0d..f1dd625e18227 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+@@ -231,10 +231,6 @@ &pm8916_vib {
+ status = "okay";
+ };
+
+-&pronto {
+- status = "okay";
+-};
+-
+ &sdhc_1 {
+ status = "okay";
+
+@@ -263,6 +259,14 @@ &usb_hs_phy {
+ extcon = <&pm8916_usbin>;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ &smd_rpm_regulators {
+ vdd_l1_l2_l3-supply = <&pm8916_s3>;
+ vdd_l4_l5_l6-supply = <&pm8916_s4>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
+index 3899e11b9843b..b79e80913af9f 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8910.dts
+@@ -99,10 +99,6 @@ &pm8916_vib {
+ status = "okay";
+ };
+
+-&pronto {
+- status = "okay";
+-};
+-
+ &sdhc_1 {
+ status = "okay";
+
+@@ -130,6 +126,14 @@ &usb_hs_phy {
+ extcon = <&usb_id>;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ &smd_rpm_regulators {
+ vdd_l1_l2_l3-supply = <&pm8916_s3>;
+ vdd_l4_l5_l6-supply = <&pm8916_s4>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi
+index 8cac23b5240c6..6eb5e0a395100 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi
+@@ -20,17 +20,6 @@ &mpss {
+ pll-supply = <&pm8916_l7>;
+ };
+
+-&pronto {
+- vddpx-supply = <&pm8916_l7>;
+-
+- iris {
+- vddxo-supply = <&pm8916_l7>;
+- vddrfa-supply = <&pm8916_s3>;
+- vddpa-supply = <&pm8916_l9>;
+- vdddig-supply = <&pm8916_l5>;
+- };
+-};
+-
+ &sdhc_1 {
+ vmmc-supply = <&pm8916_l8>;
+ vqmmc-supply = <&pm8916_l5>;
+@@ -46,6 +35,17 @@ &usb_hs_phy {
+ v3p3-supply = <&pm8916_l13>;
+ };
+
++&wcnss {
++ vddpx-supply = <&pm8916_l7>;
++};
++
++&wcnss_iris {
++ vddxo-supply = <&pm8916_l7>;
++ vddrfa-supply = <&pm8916_s3>;
++ vddpa-supply = <&pm8916_l9>;
++ vdddig-supply = <&pm8916_l5>;
++};
++
+ &rpm_requests {
+ smd_rpm_regulators: regulators {
+ compatible = "qcom,rpm-pm8916-regulators";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
+index a2ed7bdbf528f..16d67749960e0 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
+@@ -252,10 +252,6 @@ &pm8916_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
+-&pronto {
+- status = "okay";
+-};
+-
+ &sdhc_1 {
+ status = "okay";
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
+index c691cca2eb459..a1ca4d8834201 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
+@@ -112,6 +112,14 @@ &vibrator {
+ status = "okay";
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ &msmgpio {
+ panel_vdd3_default: panel-vdd3-default-state {
+ pins = "gpio9";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
+index 3dd819458785d..4e10b8a5e9f9c 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
+@@ -54,12 +54,6 @@ &clk_pwm {
+ status = "okay";
+ };
+
+-&pronto {
+- iris {
+- compatible = "qcom,wcn3660b";
+- };
+-};
+-
+ &touchkey {
+ vcc-supply = <®_touch_key>;
+ vdd-supply = <®_touch_key>;
+@@ -69,6 +63,14 @@ &vibrator {
+ status = "okay";
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3660b";
++};
++
+ &msmgpio {
+ tkey_en_default: tkey-en-default-state {
+ pins = "gpio97";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
+index c95f0b4bc61f3..f6c4a011fdfd2 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
+@@ -58,6 +58,14 @@ &touchkey {
+ vdd-supply = <®_touch_key>;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ &msmgpio {
+ tkey_en_default: tkey-en-default-state {
+ pins = "gpio97";
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
+index d920b7247d823..74ffd04db8d84 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-gt5-common.dtsi
+@@ -125,14 +125,6 @@ &pm8916_usbin {
+ status = "okay";
+ };
+
+-&pronto {
+- status = "okay";
+-
+- iris {
+- compatible = "qcom,wcn3660b";
+- };
+-};
+-
+ &sdhc_1 {
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>;
+@@ -162,6 +154,14 @@ &usb_hs_phy {
+ extcon = <&pm8916_usbin>;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3660b";
++};
++
+ &smd_rpm_regulators {
+ vdd_l1_l2_l3-supply = <&pm8916_s3>;
+ vdd_l4_l5_l6-supply = <&pm8916_s4>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
+index f3b81b6f0a2f1..adeee0830e768 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5-common.dtsi
+@@ -93,10 +93,6 @@ &pm8916_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
+-&pronto {
+- status = "okay";
+-};
+-
+ &sdhc_1 {
+ status = "okay";
+
+@@ -124,6 +120,14 @@ &usb_hs_phy {
+ extcon = <&muic>;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ &smd_rpm_regulators {
+ vdd_l1_l2_l3-supply = <&pm8916_s3>;
+ vdd_l4_l5_l6-supply = <&pm8916_s4>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
+index d4984b3af8023..1a41a4db874da 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-serranove.dts
+@@ -272,14 +272,6 @@ &pm8916_vib {
+ status = "okay";
+ };
+
+-&pronto {
+- status = "okay";
+-
+- iris {
+- compatible = "qcom,wcn3660b";
+- };
+-};
+-
+ &sdhc_1 {
+ status = "okay";
+
+@@ -320,6 +312,14 @@ &usb_hs_phy {
+ extcon = <&muic>;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3660b";
++};
++
+ &smd_rpm_regulators {
+ vdd_l1_l2_l3-supply = <&pm8916_s3>;
+ vdd_l4_l5_l6-supply = <&pm8916_s4>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi b/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
+index cdf34b74fa8fa..50bae6f214f1f 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916-ufi.dtsi
+@@ -99,10 +99,6 @@ &pm8916_usbin {
+ status = "okay";
+ };
+
+-&pronto {
+- status = "okay";
+-};
+-
+ &sdhc_1 {
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>;
+@@ -122,6 +118,14 @@ &usb_hs_phy {
+ extcon = <&pm8916_usbin>;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ &smd_rpm_regulators {
+ vdd_l1_l2_l3-supply = <&pm8916_s3>;
+ vdd_l4_l5_l6-supply = <&pm8916_s4>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts b/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
+index a87be1d95b14b..ac56c7595f78a 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
++++ b/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
+@@ -153,10 +153,6 @@ &pm8916_vib {
+ status = "okay";
+ };
+
+-&pronto {
+- status = "okay";
+-};
+-
+ &sdhc_1 {
+ status = "okay";
+
+@@ -184,6 +180,14 @@ &usb_hs_phy {
+ extcon = <&usb_id>;
+ };
+
++&wcnss {
++ status = "okay";
++};
++
++&wcnss_iris {
++ compatible = "qcom,wcn3620";
++};
++
+ &smd_rpm_regulators {
+ vdd_l1_l2_l3-supply = <&pm8916_s3>;
+ vdd_l4_l5_l6-supply = <&pm8916_s4>;
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+index 9bbe97902f0fe..80f210e55657c 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -1870,7 +1870,7 @@ usb_hs_phy: phy {
+ };
+ };
+
+- pronto: remoteproc@a21b000 {
++ wcnss: remoteproc@a21b000 {
+ compatible = "qcom,pronto-v2-pil", "qcom,pronto";
+ reg = <0x0a204000 0x2000>, <0x0a202000 0x1000>, <0x0a21b000 0x3000>;
+ reg-names = "ccu", "dxe", "pmu";
+@@ -1896,9 +1896,8 @@ pronto: remoteproc@a21b000 {
+
+ status = "disabled";
+
+- iris {
+- compatible = "qcom,wcn3620";
+-
++ wcnss_iris: iris {
++ /* Separate chip, compatible is board-specific */
+ clocks = <&rpmcc RPM_SMD_RF_CLK2>;
+ clock-names = "xo";
+ };
+@@ -1916,13 +1915,13 @@ wcnss_ctrl: wcnss {
+ compatible = "qcom,wcnss";
+ qcom,smd-channels = "WCNSS_CTRL";
+
+- qcom,mmio = <&pronto>;
++ qcom,mmio = <&wcnss>;
+
+- bluetooth {
++ wcnss_bt: bluetooth {
+ compatible = "qcom,wcnss-bt";
+ };
+
+- wifi {
++ wcnss_wifi: wifi {
+ compatible = "qcom,wcnss-wlan";
+
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+--
+2.39.2
+
--- /dev/null
+From cf70fc664b73212bb90c33fe8b7a5b73c635c27b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:43 +0200
+Subject: arm64: dts: qcom: msm8953: correct IOMMU unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 1c06b93461ec9df8a5878947db4a9d2d1cb72855 ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc@0/iommu@1e00000: simple-bus unit address format error, expected "1e20000"
+
+Fixes: c0b9575a3606 ("arm64: dts: qcom: msm8953: add APPS IOMMU")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-5-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8953.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
+index 610f3e3fc0c22..7001f6b0b9f9a 100644
+--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
+@@ -878,7 +878,7 @@ dsi1_phy: phy@1a96400 {
+ };
+ };
+
+- apps_iommu: iommu@1e00000 {
++ apps_iommu: iommu@1e20000 {
+ compatible = "qcom,msm8953-iommu", "qcom,msm-iommu-v1";
+ ranges = <0 0x1e20000 0x20000>;
+
+--
+2.39.2
+
--- /dev/null
+From 439391fd427a42ef3c7a5a9947857784c85a0d8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:45 +0200
+Subject: arm64: dts: qcom: msm8976: correct MMC unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 80284797a4cb8ceae71e3c403bafc6648263a060 ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc@0/mmc@7824000: simple-bus unit address format error, expected "7824900"
+ Warning (simple_bus_reg): /soc@0/mmc@7864000: simple-bus unit address format error, expected "7864900"
+ Warning (simple_bus_reg): /soc@0/mmc@7a24000: simple-bus unit address format error, expected "7a24900"
+
+Fixes: 0484d3ce0902 ("arm64: dts: qcom: Add DTS for MSM8976 and MSM8956 SoCs")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-7-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8976.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8976.dtsi b/arch/arm64/boot/dts/qcom/msm8976.dtsi
+index e55baafd9efd0..e1617b9a73df2 100644
+--- a/arch/arm64/boot/dts/qcom/msm8976.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8976.dtsi
+@@ -821,7 +821,7 @@ spmi_bus: spmi@200f000 {
+ cell-index = <0>;
+ };
+
+- sdhc_1: mmc@7824000 {
++ sdhc_1: mmc@7824900 {
+ compatible = "qcom,msm8976-sdhci", "qcom,sdhci-msm-v4";
+ reg = <0x07824900 0x500>, <0x07824000 0x800>;
+ reg-names = "hc", "core";
+@@ -837,7 +837,7 @@ sdhc_1: mmc@7824000 {
+ status = "disabled";
+ };
+
+- sdhc_2: mmc@7864000 {
++ sdhc_2: mmc@7864900 {
+ compatible = "qcom,msm8976-sdhci", "qcom,sdhci-msm-v4";
+ reg = <0x07864900 0x11c>, <0x07864000 0x800>;
+ reg-names = "hc", "core";
+@@ -956,7 +956,7 @@ otg: usb@78db000 {
+ #reset-cells = <1>;
+ };
+
+- sdhc_3: mmc@7a24000 {
++ sdhc_3: mmc@7a24900 {
+ compatible = "qcom,msm8976-sdhci", "qcom,sdhci-msm-v4";
+ reg = <0x07a24900 0x11c>, <0x07a24000 0x800>;
+ reg-names = "hc", "core";
+--
+2.39.2
+
--- /dev/null
+From ee42a0e6b40999e5e95746fed70af71b2e98e55f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:46 +0200
+Subject: arm64: dts: qcom: msm8994: correct SPMI unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 24f0f6a8059c7108d4ee3476c95db1e7ff4feb79 ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc/spmi@fc4c0000: simple-bus unit address format error, expected "fc4cf000"
+
+Fixes: b0ad598f8ec0 ("arm64: dts: qcom: msm8994: Add SPMI PMIC arbiter device")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-8-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8994.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
+index 24c3fced8df71..5ce23306fd844 100644
+--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
+@@ -745,7 +745,7 @@ restart@fc4ab000 {
+ reg = <0xfc4ab000 0x4>;
+ };
+
+- spmi_bus: spmi@fc4c0000 {
++ spmi_bus: spmi@fc4cf000 {
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0xfc4cf000 0x1000>,
+ <0xfc4cb000 0x1000>,
+--
+2.39.2
+
--- /dev/null
+From 10b3f0868b7a5885e289df2352b88a155ce1cd56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:47 +0200
+Subject: arm64: dts: qcom: msm8996: correct camss unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit e959ced1d0e5ef0b1f66a0c2d0e1ae80790e5ca5 ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc/camss@a00000: simple-bus unit address format error, expected "a34000"
+
+Fixes: e0531312e78f ("arm64: dts: qcom: msm8996: Add CAMSS support")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-9-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+index 73da1a4d52462..771db923b2e33 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -2069,7 +2069,7 @@ ufsphy_lane: phy@627400 {
+ };
+ };
+
+- camss: camss@a00000 {
++ camss: camss@a34000 {
+ compatible = "qcom,msm8996-camss";
+ reg = <0x00a34000 0x1000>,
+ <0x00a00030 0x4>,
+--
+2.39.2
+
--- /dev/null
+From 299a95d6439c14b35f9b8d15d8e8a566053447bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Apr 2023 09:45:44 +0200
+Subject: arm64: dts: qcom: pm7250b: add missing spmi-vadc include
+
+From: Luca Weiss <luca.weiss@fairphone.com>
+
+[ Upstream commit 83022f6484b11a60dbf9a95a88c7ef8e59c4b19c ]
+
+This file is using definitions from the spmi-vadc header, so we need to
+include it.
+
+Fixes: 11975b9b8135 ("arm64: dts: qcom: Add pm7250b PMIC")
+Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230407-pm7250b-sid-v1-1-fc648478cc25@fairphone.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/pm7250b.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/pm7250b.dtsi b/arch/arm64/boot/dts/qcom/pm7250b.dtsi
+index d709d955a2f5a..daa6f1d30efa0 100644
+--- a/arch/arm64/boot/dts/qcom/pm7250b.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm7250b.dtsi
+@@ -3,6 +3,7 @@
+ * Copyright (C) 2022 Luca Weiss <luca.weiss@fairphone.com>
+ */
+
++#include <dt-bindings/iio/qcom,spmi-vadc.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/spmi/spmi.h>
+
+--
+2.39.2
+
--- /dev/null
+From c97e029641cfadc70fd28ac53e96f445a6b513eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Apr 2023 21:21:45 +0300
+Subject: arm64: dts: qcom: pm8998: don't use GIC_SPI for SPMI interrupts
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit d9ef7a805a709a0b07341857d97a25598a7f92da ]
+
+Unlike typical GIC interrupts, first cell for SPMI interrupts is the
+USID rather than GIC_SPI/GIC_PPI/GIC_LPI qualifier. Fix the resin
+interrupt to use USID value 0x0 rather than GIC_SPI define.
+
+Fixes: f86ae6f23a9e ("arm64: dts: qcom: sagit: add initial device tree for sagit")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230409182145.122895-1-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/pm8998.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi b/arch/arm64/boot/dts/qcom/pm8998.dtsi
+index adbba9f4089ab..13925ac44669d 100644
+--- a/arch/arm64/boot/dts/qcom/pm8998.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi
+@@ -55,7 +55,7 @@ pm8998_pwrkey: pwrkey {
+
+ pm8998_resin: resin {
+ compatible = "qcom,pm8941-resin";
+- interrupts = <GIC_SPI 0x8 1 IRQ_TYPE_EDGE_BOTH>;
++ interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
+ debounce = <15625>;
+ bias-pull-up;
+ status = "disabled";
+--
+2.39.2
+
--- /dev/null
+From 0adcc1acc2589d4e11fef6590055b255f5b815df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 May 2023 15:22:37 +0200
+Subject: arm64: dts: qcom: qdu1000: Flush RSC sleep & wake votes
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit ab033e7846f91953244d0626b28ce66412b813b3 ]
+
+The rpmh driver will cache sleep and wake votes until the cluster
+power-domain is about to enter idle, to avoid unnecessary writes. So
+associate the apps_rsc with the cluster pd, so that it can be notified
+about this event.
+
+Without this, only AMC votes are being commited.
+
+Fixes: 6bd20c54b589 ("arm64: dts: qcom: Add base QDU1000/QRU1000 DTSIs")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230531-topic-rsc-v1-3-b4a985f57b8b@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/qdu1000.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/qdu1000.dtsi b/arch/arm64/boot/dts/qcom/qdu1000.dtsi
+index c72a51c32a300..eeb4e51b31cfc 100644
+--- a/arch/arm64/boot/dts/qcom/qdu1000.dtsi
++++ b/arch/arm64/boot/dts/qcom/qdu1000.dtsi
+@@ -1238,6 +1238,7 @@ apps_rsc: rsc@17a00000 {
+ qcom,tcs-config = <ACTIVE_TCS 2>, <SLEEP_TCS 3>,
+ <WAKE_TCS 3>, <CONTROL_TCS 0>;
+ label = "apps_rsc";
++ power-domains = <&CLUSTER_PD>;
+
+ apps_bcm_voter: bcm-voter {
+ compatible = "qcom,bcm-voter";
+--
+2.39.2
+
--- /dev/null
+From 7e71cf6296154eefed71ecfe2be25c345718cdb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:48 +0200
+Subject: arm64: dts: qcom: sdm630: correct camss unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit c8b7faa7e9913a94444b3f00b6480e53a174fcfd ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc/camss@ca00000: simple-bus unit address format error, expected "ca00020"
+
+Fixes: f3d5d3cc6971 ("arm64: dts: qcom: sdm630: Configure the camera subsystem")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-10-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+index 5827cda270a0e..07c720c5721d4 100644
+--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+@@ -1893,7 +1893,7 @@ pil-reloc@94c {
+ };
+ };
+
+- camss: camss@ca00000 {
++ camss: camss@ca00020 {
+ compatible = "qcom,sdm660-camss";
+ reg = <0x0ca00020 0x10>,
+ <0x0ca30000 0x100>,
+--
+2.39.2
+
--- /dev/null
+From 8a7a231694f1338dd9b53218d5ee88940107b681 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 May 2023 15:22:39 +0200
+Subject: arm64: dts: qcom: sdm670: Flush RSC sleep & wake votes
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 7b04cbd81b0e60c5151a310e7b730dc4a951a211 ]
+
+The rpmh driver will cache sleep and wake votes until the cluster
+power-domain is about to enter idle, to avoid unnecessary writes. So
+associate the apps_rsc with the cluster pd, so that it can be notified
+about this event.
+
+Without this, only AMC votes are being commited.
+
+Fixes: 07c8ded6e373 ("arm64: dts: qcom: add sdm670 and pixel 3a device trees")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230531-topic-rsc-v1-5-b4a985f57b8b@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm670.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
+index 02f14692dd9da..50dd050eb132d 100644
+--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
+@@ -1155,6 +1155,7 @@ apps_rsc: rsc@179c0000 {
+ <SLEEP_TCS 3>,
+ <WAKE_TCS 3>,
+ <CONTROL_TCS 1>;
++ power-domains = <&CLUSTER_PD>;
+
+ apps_bcm_voter: bcm-voter {
+ compatible = "qcom,bcm-voter";
+--
+2.39.2
+
--- /dev/null
+From 97cf427fb334a03db1206f1fceca10dd82252870 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:49 +0200
+Subject: arm64: dts: qcom: sdm845: correct camss unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit a05b913a27e46926ba60ba2bcacc7ec7a8403e4c ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc@0/camss@a00000: simple-bus unit address format error, expected "acb3000"
+
+Fixes: d48a6698a6b7 ("arm64: dts: qcom: sdm845: Add CAMSS ISP node")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-11-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+index c5e92851a4f08..bc89a2b4bc258 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+@@ -4158,7 +4158,7 @@ videocc: clock-controller@ab00000 {
+ #reset-cells = <1>;
+ };
+
+- camss: camss@a00000 {
++ camss: camss@acb3000 {
+ compatible = "qcom,sdm845-camss";
+
+ reg = <0 0x0acb3000 0 0x1000>,
+--
+2.39.2
+
--- /dev/null
+From 227d76d1943d0e1d13a870c94b0fb8eb477c3c88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 May 2023 15:22:40 +0200
+Subject: arm64: dts: qcom: sdm845: Flush RSC sleep & wake votes
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 91e83140b5dd5598fbcfada3ee1f8b2b410c3731 ]
+
+The rpmh driver will cache sleep and wake votes until the cluster
+power-domain is about to enter idle, to avoid unnecessary writes. So
+associate the apps_rsc with the cluster pd, so that it can be notified
+about this event.
+
+Without this, only AMC votes are being commited.
+
+Fixes: c83545d95376 ("arm64: dts: sdm845: Add rpmh-rsc node")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230531-topic-rsc-v1-6-b4a985f57b8b@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+index bc89a2b4bc258..a818a81408dfb 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+@@ -5058,6 +5058,7 @@ apps_rsc: rsc@179c0000 {
+ <SLEEP_TCS 3>,
+ <WAKE_TCS 3>,
+ <CONTROL_TCS 1>;
++ power-domains = <&CLUSTER_PD>;
+
+ apps_bcm_voter: bcm-voter {
+ compatible = "qcom,bcm-voter";
+--
+2.39.2
+
--- /dev/null
+From cf43ba640e40fa4a44d9c2090d9ebd0358969dc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:56 +0200
+Subject: arm64: dts: qcom: sdm845-polaris: add missing touchscreen child node
+ reg
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 4a0156b8862665a3e31c8280607388e3001ace3d ]
+
+Add missing reg property to touchscreen child node to fix dtbs W=1 warnings:
+
+ Warning (unit_address_vs_reg): /soc@0/geniqup@ac0000/i2c@a98000/touchscreen@20/rmi4-f12@12: node has a unit name, but no reg or ranges property
+
+Fixes: be497abe19bf ("arm64: dts: qcom: Add support for Xiaomi Mi Mix2s")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Molly Sophia <mollysophia379@gmail.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-18-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+index 56f2d855df78d..406f0224581a7 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+@@ -483,6 +483,7 @@ rmi4-f01@1 {
+ };
+
+ rmi4-f12@12 {
++ reg = <0x12>;
+ syna,rezero-wait-ms = <0xc8>;
+ syna,clip-x-high = <0x438>;
+ syna,clip-y-high = <0x870>;
+--
+2.39.2
+
--- /dev/null
+From 2327fb7ece685fcce53860e7e242dcc3f1552bd9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:50 +0200
+Subject: arm64: dts: qcom: sm6115: correct thermal-sensor unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 2358b43256080459fcc5642265ed4fec75558f8c ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc@0/thermal-sensor@4410000: simple-bus unit address format error, expected "4411000"
+
+Fixes: 7b74cba6b13f ("arm64: dts: qcom: sm6115: Add TSENS node")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-12-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm6115.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm6115.dtsi b/arch/arm64/boot/dts/qcom/sm6115.dtsi
+index fbd67d2c8d781..62b1c1674a68d 100644
+--- a/arch/arm64/boot/dts/qcom/sm6115.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6115.dtsi
+@@ -693,7 +693,7 @@ spmi_bus: spmi@1c40000 {
+ #interrupt-cells = <4>;
+ };
+
+- tsens0: thermal-sensor@4410000 {
++ tsens0: thermal-sensor@4411000 {
+ compatible = "qcom,sm6115-tsens", "qcom,tsens-v2";
+ reg = <0x0 0x04411000 0x0 0x1ff>, /* TM */
+ <0x0 0x04410000 0x0 0x8>; /* SROT */
+--
+2.39.2
+
--- /dev/null
+From ed8f49e51ae1fd4eb107871739c3a70c89bc34e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 23:14:18 +0200
+Subject: arm64: dts: qcom: sm8250-edo: Panel framebuffer is 2.5k instead of 4k
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit 223ce29c8b7e5b00f01a68387aabeefd77d97f06 ]
+
+The framebuffer configuration for edo pdx203, written in edo dtsi (which
+is overwritten in pdx206 dts for its smaller panel) has to use a
+1096x2560 configuration as this is what the panel (and framebuffer area)
+has been initialized to. Downstream userspace also has access to (and
+uses) this 2.5k mode by default, and only switches the panel to 4k when
+requested.
+
+This is similar to commit be8de06dc397 ("arm64: dts: qcom:
+sm8150-kumano: Panel framebuffer is 2.5k instead of 4k") which fixed the
+same for the previous generation Sony platform.
+
+Fixes: 69cdb97ef652 ("arm64: dts: qcom: sm8250: Add support for SONY Xperia 1 II / 5 II (Edo platform)")
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230606211418.587676-1-marijn.suijten@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+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 b9c982a059dfb..c0f22a3bea5ce 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+@@ -26,9 +26,10 @@ chosen {
+ framebuffer: framebuffer@9c000000 {
+ compatible = "simple-framebuffer";
+ reg = <0 0x9c000000 0 0x2300000>;
+- width = <1644>;
+- height = <3840>;
+- stride = <(1644 * 4)>;
++ /* pdx203 BL initializes in 2.5k mode, not 4k */
++ width = <1096>;
++ height = <2560>;
++ stride = <(1096 * 4)>;
+ format = "a8r8g8b8";
+ /*
+ * That's a lot of clocks, but it's necessary due
+--
+2.39.2
+
--- /dev/null
+From 39277ceffd9de4cbf8708fffef3d65ded95f895a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:51 +0200
+Subject: arm64: dts: qcom: sm8350: correct DMA controller unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 41d6bca799b3f40d4d3c22dd4545aeac7c210e33 ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc@0/dma-controller@900000: simple-bus unit address format error, expected "9800000"
+
+Fixes: bc08fbf49bc8 ("arm64: dts: qcom: sm8350: Define GPI DMA engines")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-13-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+index 9cb52d7efdd8d..f0453730ab59b 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+@@ -892,7 +892,7 @@ spi19: spi@894000 {
+ };
+ };
+
+- gpi_dma0: dma-controller@900000 {
++ gpi_dma0: dma-controller@9800000 {
+ compatible = "qcom,sm8350-gpi-dma", "qcom,sm6350-gpi-dma";
+ reg = <0 0x09800000 0 0x60000>;
+ interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>,
+--
+2.39.2
+
--- /dev/null
+From 162584d70c65f1da6571bb6c0c640cfae576fda5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:52 +0200
+Subject: arm64: dts: qcom: sm8350: correct PCI phy unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit ab98c21bc9246f421a6ae70e69f1b73cea6f85e3 ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc@0/phy@1c0f000: simple-bus unit address format error, expected "1c0e000"
+
+Fixes: 6daee40678a0 ("arm64: dts: qcom: sm8350: add PCIe devices")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-14-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+index f0453730ab59b..1a258a5461acf 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+@@ -1625,7 +1625,7 @@ pcie1: pci@1c08000 {
+ status = "disabled";
+ };
+
+- pcie1_phy: phy@1c0f000 {
++ pcie1_phy: phy@1c0e000 {
+ compatible = "qcom,sm8350-qmp-gen3x2-pcie-phy";
+ reg = <0 0x01c0e000 0 0x2000>;
+ clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
+--
+2.39.2
+
--- /dev/null
+From 091b4417e6d78320adfae05abab959a632e07629 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 13:38:17 +0300
+Subject: arm64: dts: qcom: sm8550: Add missing interconnect path to USB HC
+
+From: Abel Vesa <abel.vesa@linaro.org>
+
+[ Upstream commit 11a1397bbf69e408223bb691858a0fcd295a8f76 ]
+
+The USB HC node is missing the interconnect paths, so add them.
+
+Fixes: 7f7e5c1b037f ("arm64: dts: qcom: sm8550: Add USB PHYs and controller nodes")
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230601103817.4066446-1-abel.vesa@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8550.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+index 429746447441f..75bd5f2ae681f 100644
+--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+@@ -2441,6 +2441,10 @@ usb_1: usb@a6f8800 {
+
+ resets = <&gcc GCC_USB30_PRIM_BCR>;
+
++ interconnects = <&aggre1_noc MASTER_USB3_0 0 &mc_virt SLAVE_EBI1 0>,
++ <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_0 0>;
++ interconnect-names = "usb-ddr", "apps-usb";
++
+ status = "disabled";
+
+ usb_1_dwc3: usb@a600000 {
+--
+2.39.2
+
--- /dev/null
+From d682fc8dc8f877f7ada1c2a3c4fe5adbb1ab52cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Feb 2023 19:22:37 +0200
+Subject: arm64: dts: qcom: sm8550: add QCE IP family compatible values
+
+From: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+
+[ Upstream commit e47a80784306a544a58f5c7febaaa3cc646f51a2 ]
+
+Add a family compatible for QCE IP on SM8550 SoC, which is equal to QCE IP
+found on SM8150 SoC and described in the recently updated device tree
+bindings documentation, as well add a generic QCE IP family compatible.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: 3cbf49ef1696 ("arm64: dts: qcom: sm8550: correct crypto unit address")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8550.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+index 90e3fb11e6e70..b451e94f2b4c0 100644
+--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+@@ -1844,7 +1844,7 @@ cryptobam: dma-controller@1dc4000 {
+ };
+
+ crypto: crypto@1de0000 {
+- compatible = "qcom,sm8550-qce";
++ compatible = "qcom,sm8550-qce", "qcom,sm8150-qce", "qcom,qce";
+ reg = <0x0 0x01dfa000 0x0 0x6000>;
+ dmas = <&cryptobam 4>, <&cryptobam 5>;
+ dma-names = "rx", "tx";
+--
+2.39.2
+
--- /dev/null
+From 1fdb2ee5e3be20ba6bb78189793206e66135d204 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:54 +0200
+Subject: arm64: dts: qcom: sm8550: correct crypto unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 3cbf49ef16962ab6d99a3659cb34a33c5f147b50 ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc@0/crypto@1de0000: simple-bus unit address format error, expected "1dfa000"
+
+Fixes: 433477c3bf0b ("arm64: dts: qcom: sm8550: add QCrypto nodes")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-16-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8550.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+index b451e94f2b4c0..3af9da58f65c6 100644
+--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+@@ -1843,7 +1843,7 @@ cryptobam: dma-controller@1dc4000 {
+ <&apps_smmu 0x481 0x0>;
+ };
+
+- crypto: crypto@1de0000 {
++ crypto: crypto@1dfa000 {
+ compatible = "qcom,sm8550-qce", "qcom,sm8150-qce", "qcom,qce";
+ reg = <0x0 0x01dfa000 0x0 0x6000>;
+ dmas = <&cryptobam 4>, <&cryptobam 5>;
+--
+2.39.2
+
--- /dev/null
+From 4375ea1b195fc5450221d4c2c039ef4ec86ca003 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 23:18:55 +0200
+Subject: arm64: dts: qcom: sm8550: correct pinctrl unit address
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 950a4fe6ec8498799d1c7bd31a489a718f94a87e ]
+
+Match unit-address to reg entry to fix dtbs W=1 warnings:
+
+ Warning (simple_bus_reg): /soc@0/pinctrl@f000000: simple-bus unit address format error, expected "f100000"
+
+Fixes: ffc50b2d3828 ("arm64: dts: qcom: Add base SM8550 dtsi")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230419211856.79332-17-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8550.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+index 3af9da58f65c6..5f254a4675265 100644
+--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+@@ -2536,7 +2536,7 @@ spmi_bus: spmi@c400000 {
+ #interrupt-cells = <4>;
+ };
+
+- tlmm: pinctrl@f000000 {
++ tlmm: pinctrl@f100000 {
+ compatible = "qcom,sm8550-tlmm";
+ reg = <0 0x0f100000 0 0x300000>;
+ interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+--
+2.39.2
+
--- /dev/null
+From e14d6c1c698c6e20e5f609777babc1181ceb5908 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 May 2023 15:22:42 +0200
+Subject: arm64: dts: qcom: sm8550: Flush RSC sleep & wake votes
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 4b2c7ac8e469ab7f92e50c34ad4012a77e79d078 ]
+
+The rpmh driver will cache sleep and wake votes until the cluster
+power-domain is about to enter idle, to avoid unnecessary writes. So
+associate the apps_rsc with the cluster pd, so that it can be notified
+about this event.
+
+Without this, only AMC votes are being commited.
+
+Fixes: ffc50b2d3828 ("arm64: dts: qcom: Add base SM8550 dtsi")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230531-topic-rsc-v1-8-b4a985f57b8b@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8550.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+index 5f254a4675265..429746447441f 100644
+--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+@@ -3250,6 +3250,7 @@ apps_rsc: rsc@17a00000 {
+ qcom,drv-id = <2>;
+ qcom,tcs-config = <ACTIVE_TCS 3>, <SLEEP_TCS 2>,
+ <WAKE_TCS 2>, <CONTROL_TCS 0>;
++ power-domains = <&CLUSTER_PD>;
+
+ apps_bcm_voter: bcm-voter {
+ compatible = "qcom,bcm-voter";
+--
+2.39.2
+
--- /dev/null
+From de76aca3acb352239029e85c19bb2a6ab11c882b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 May 2023 10:48:22 +0200
+Subject: arm64: dts: renesas: ulcb-kf: Remove flow control for SCIF1
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 1a2c4e5635177939a088d22fa35c6a7032725663 ]
+
+The schematics are misleading, the flow control is for HSCIF1. We need
+SCIF1 for GNSS/GPS which does not use flow control.
+
+Fixes: c6c816e22bc8 ("arm64: dts: ulcb-kf: enable SCIF1")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20230525084823.4195-2-wsa+renesas@sang-engineering.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+index efc80960380f4..c78b7a5c2e2aa 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -367,7 +367,7 @@ hscif0_pins: hscif0 {
+ };
+
+ scif1_pins: scif1 {
+- groups = "scif1_data_b", "scif1_ctrl";
++ groups = "scif1_data_b";
+ function = "scif1";
+ };
+
+@@ -397,7 +397,6 @@ &sound_clk_pins
+ &scif1 {
+ pinctrl-0 = <&scif1_pins>;
+ pinctrl-names = "default";
+- uart-has-rtscts;
+
+ status = "okay";
+ };
+--
+2.39.2
+
--- /dev/null
+From 01aa826b731ecbd55a8215084d685d70050e204a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 16:49:33 -0500
+Subject: arm64: dts: ti: k3-am69-sk: Fix main_i2c0 alias
+
+From: Nishanth Menon <nm@ti.com>
+
+[ Upstream commit b38c6ced4ec5b3f6260ff6cc2b71e8a3d8c897d7 ]
+
+main_i2c0 is aliased as i2c0 which creates a problem for u-boot R5
+SPL attempting to reuse the same definition in the common board
+detection logic as it looks for the first i2c instance as the bus on
+which to detect the eeprom to understand the board variant involved.
+Switch main_i2c0 to i2c3 alias allowing us to introduce wkup_i2c0
+and potentially space for mcu_i2c instances in the gap for follow on
+patches.
+
+Fixes: 635fb18ba008 ("arch: arm64: dts: Add support for AM69 Starter Kit")
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Reviewed-by: Udit Kumar <u-kumar1@ti.com>
+Link: https://lore.kernel.org/r/20230602214937.2349545-5-nm@ti.com
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-am69-sk.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+index bc49ba534790e..f364b7803115d 100644
+--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
++++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+@@ -23,7 +23,7 @@ chosen {
+ aliases {
+ serial2 = &main_uart8;
+ mmc1 = &main_sdhci1;
+- i2c0 = &main_i2c0;
++ i2c3 = &main_i2c0;
+ };
+
+ memory@80000000 {
+--
+2.39.2
+
--- /dev/null
+From dd9005b3bb59f81eb5aa22237b4834988350bdee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 09:30:06 +0530
+Subject: arm64: dts: ti: k3-j7200: Fix physical address of pin
+
+From: Keerthy <j-keerthy@ti.com>
+
+[ Upstream commit 3d011933000ed9054c649952d83162d24f020a93 ]
+
+wkup_pmx splits into multiple regions. Like
+
+ wkup_pmx0 -> 13 pins (WKUP_PADCONFIG 0 - 12)
+ wkup_pmx1 -> 2 pins (WKUP_PADCONFIG 14 - 15)
+ wkup_pmx2 -> 59 pins (WKUP_PADCONFIG 26 - 84)
+ wkup_pmx3 -> 8 pins (WKUP_PADCONFIG 93 - 100)
+
+With this split, pin offset needs to be adjusted to
+match with new pmx for all pins above wkup_pmx0.
+
+Example a pin under wkup_pmx1 should start from 0 instead of
+old offset(0x38 WKUP_PADCONFIG 14 offset)
+
+J7200 Datasheet (Table 6-106, Section 6.4 Pin Multiplexing) :
+https://www.ti.com/lit/ds/symlink/dra821u.pdf
+
+Fixes: 9ae21ac445e9 ("arm64: dts: ti: k3-j7200: Fix wakeup pinmux range")
+
+Signed-off-by: Keerthy <j-keerthy@ti.com>
+Signed-off-by: Udit Kumar <u-kumar1@ti.com>
+Link: https://lore.kernel.org/r/20230419040007.3022780-2-u-kumar1@ti.com
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dts/ti/k3-j7200-common-proc-board.dts | 28 +++++++++----------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+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 0d39d6b8cc0ca..63633e4f6c59f 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
+@@ -83,25 +83,25 @@ vdd_sd_dv: gpio-regulator-TLV71033 {
+ &wkup_pmx2 {
+ mcu_cpsw_pins_default: mcu-cpsw-pins-default {
+ pinctrl-single,pins = <
+- J721E_WKUP_IOPAD(0x0068, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
+- J721E_WKUP_IOPAD(0x006c, PIN_INPUT, 0) /* MCU_RGMII1_RX_CTL */
+- J721E_WKUP_IOPAD(0x0070, PIN_OUTPUT, 0) /* MCU_RGMII1_TD3 */
+- J721E_WKUP_IOPAD(0x0074, PIN_OUTPUT, 0) /* MCU_RGMII1_TD2 */
+- J721E_WKUP_IOPAD(0x0078, PIN_OUTPUT, 0) /* MCU_RGMII1_TD1 */
+- J721E_WKUP_IOPAD(0x007c, PIN_OUTPUT, 0) /* MCU_RGMII1_TD0 */
+- J721E_WKUP_IOPAD(0x0088, PIN_INPUT, 0) /* MCU_RGMII1_RD3 */
+- J721E_WKUP_IOPAD(0x008c, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */
+- J721E_WKUP_IOPAD(0x0090, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */
+- J721E_WKUP_IOPAD(0x0094, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */
+- J721E_WKUP_IOPAD(0x0080, PIN_OUTPUT, 0) /* MCU_RGMII1_TXC */
+- J721E_WKUP_IOPAD(0x0084, PIN_INPUT, 0) /* MCU_RGMII1_RXC */
++ J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
++ J721E_WKUP_IOPAD(0x0004, PIN_INPUT, 0) /* MCU_RGMII1_RX_CTL */
++ J721E_WKUP_IOPAD(0x0008, PIN_OUTPUT, 0) /* MCU_RGMII1_TD3 */
++ J721E_WKUP_IOPAD(0x000c, PIN_OUTPUT, 0) /* MCU_RGMII1_TD2 */
++ J721E_WKUP_IOPAD(0x0010, PIN_OUTPUT, 0) /* MCU_RGMII1_TD1 */
++ J721E_WKUP_IOPAD(0x0014, PIN_OUTPUT, 0) /* MCU_RGMII1_TD0 */
++ J721E_WKUP_IOPAD(0x0020, PIN_INPUT, 0) /* MCU_RGMII1_RD3 */
++ J721E_WKUP_IOPAD(0x0024, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */
++ J721E_WKUP_IOPAD(0x0028, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */
++ J721E_WKUP_IOPAD(0x002c, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */
++ J721E_WKUP_IOPAD(0x0018, PIN_OUTPUT, 0) /* MCU_RGMII1_TXC */
++ J721E_WKUP_IOPAD(0x001c, PIN_INPUT, 0) /* MCU_RGMII1_RXC */
+ >;
+ };
+
+ mcu_mdio_pins_default: mcu-mdio1-pins-default {
+ pinctrl-single,pins = <
+- J721E_WKUP_IOPAD(0x009c, PIN_OUTPUT, 0) /* (L1) MCU_MDIO0_MDC */
+- J721E_WKUP_IOPAD(0x0098, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */
++ J721E_WKUP_IOPAD(0x0034, PIN_OUTPUT, 0) /* (L1) MCU_MDIO0_MDC */
++ J721E_WKUP_IOPAD(0x0030, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */
+ >;
+ };
+ };
+--
+2.39.2
+
--- /dev/null
+From c37545e4a17dbed1cde7eb9bc0aed08545a70f54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 12:21:33 -0500
+Subject: arm64: dts: ti: k3-j721e-beagleboneai64: Fix mailbox node status
+
+From: Andrew Davis <afd@ti.com>
+
+[ Upstream commit 155e7635ed1f3814d94d12556a3a0fed41d05b76 ]
+
+Mailbox nodes are now disabled by default. The BeagleBoard AI64 DT
+addition went in at around the same time and must have missed that
+change so the mailboxes are not re-enabled. Do that here.
+
+Fixes: fae14a1cb8dd ("arm64: dts: ti: Add k3-j721e-beagleboneai64")
+Signed-off-by: Andrew Davis <afd@ti.com>
+Reviewed-by: Nishanth Menon <nm@ti.com>
+Link: https://lore.kernel.org/r/20230515172137.474626-1-afd@ti.com
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
+index 37c24b077b6aa..8a62ac263b89a 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
++++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
+@@ -936,6 +936,7 @@ &ufs_wrapper {
+ };
+
+ &mailbox0_cluster0 {
++ status = "okay";
+ interrupts = <436>;
+
+ mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
+@@ -950,6 +951,7 @@ mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
+ };
+
+ &mailbox0_cluster1 {
++ status = "okay";
+ interrupts = <432>;
+
+ mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
+@@ -964,6 +966,7 @@ mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
+ };
+
+ &mailbox0_cluster2 {
++ status = "okay";
+ interrupts = <428>;
+
+ mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
+@@ -978,6 +981,7 @@ mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
+ };
+
+ &mailbox0_cluster3 {
++ status = "okay";
+ interrupts = <424>;
+
+ mbox_c66_0: mbox-c66-0 {
+@@ -992,6 +996,7 @@ mbox_c66_1: mbox-c66-1 {
+ };
+
+ &mailbox0_cluster4 {
++ status = "okay";
+ interrupts = <420>;
+
+ mbox_c71_0: mbox-c71-0 {
+--
+2.39.2
+
--- /dev/null
+From 0fa31df5845483317114850b524477ca824b9ca4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Mar 2023 09:55:48 +0530
+Subject: arm64: dts: ti: k3-j784s4-evm: Enable MCU CPSW2G
+
+From: Siddharth Vadapalli <s-vadapalli@ti.com>
+
+[ Upstream commit 6cd4b7cfbcca4a45f06a8031f299c4019221a4ce ]
+
+Add device tree support to enable MCU CPSW with J784S4 EVM.
+
+Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
+Reviewed-by: Andrew Davis <afd@ti.com>
+Link: https://lore.kernel.org/r/20230315042548.1500528-1-s-vadapalli@ti.com
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Stable-dep-of: 14462bd0b247 ("arm64: dts: ti: k3-j784s4: Fix wakeup pinmux range and pinctrl node offsets")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 50 ++++++++++++++++++++++++
+ 1 file changed, 50 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+index 6b2d93d3c5e27..0c4ee83fc9d75 100644
+--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
++++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+@@ -140,6 +140,32 @@ J784S4_IOPAD(0x020, PIN_INPUT, 7) /* (AJ35) MCAN15_RX.GPIO0_8 */
+ };
+ };
+
++&wkup_pmx0 {
++ mcu_cpsw_pins_default: mcu-cpsw-pins-default {
++ pinctrl-single,pins = <
++ J784S4_WKUP_IOPAD(0x094, PIN_INPUT, 0) /* (A35) MCU_RGMII1_RD0 */
++ J784S4_WKUP_IOPAD(0x090, PIN_INPUT, 0) /* (B36) MCU_RGMII1_RD1 */
++ J784S4_WKUP_IOPAD(0x08c, PIN_INPUT, 0) /* (C36) MCU_RGMII1_RD2 */
++ J784S4_WKUP_IOPAD(0x088, PIN_INPUT, 0) /* (D36) MCU_RGMII1_RD3 */
++ J784S4_WKUP_IOPAD(0x084, PIN_INPUT, 0) /* (B37) MCU_RGMII1_RXC */
++ J784S4_WKUP_IOPAD(0x06c, PIN_INPUT, 0) /* (C37) MCU_RGMII1_RX_CTL */
++ J784S4_WKUP_IOPAD(0x07c, PIN_OUTPUT, 0) /* (D37) MCU_RGMII1_TD0 */
++ J784S4_WKUP_IOPAD(0x078, PIN_OUTPUT, 0) /* (D38) MCU_RGMII1_TD1 */
++ J784S4_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (E37) MCU_RGMII1_TD2 */
++ J784S4_WKUP_IOPAD(0x070, PIN_OUTPUT, 0) /* (E38) MCU_RGMII1_TD3 */
++ J784S4_WKUP_IOPAD(0x080, PIN_OUTPUT, 0) /* (E36) MCU_RGMII1_TXC */
++ J784S4_WKUP_IOPAD(0x068, PIN_OUTPUT, 0) /* (C38) MCU_RGMII1_TX_CTL */
++ >;
++ };
++
++ mcu_mdio_pins_default: mcu-mdio-pins-default {
++ pinctrl-single,pins = <
++ J784S4_WKUP_IOPAD(0x09c, PIN_OUTPUT, 0) /* (A36) MCU_MDIO0_MDC */
++ J784S4_WKUP_IOPAD(0x098, PIN_INPUT, 0) /* (B35) MCU_MDIO0_MDIO */
++ >;
++ };
++};
++
+ &main_uart8 {
+ status = "okay";
+ pinctrl-names = "default";
+@@ -194,3 +220,27 @@ &main_sdhci1 {
+ &main_gpio0 {
+ status = "okay";
+ };
++
++&mcu_cpsw {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&mcu_cpsw_pins_default>;
++};
++
++&davinci_mdio {
++ pinctrl-names = "default";
++ pinctrl-0 = <&mcu_mdio_pins_default>;
++
++ mcu_phy0: ethernet-phy@0 {
++ reg = <0>;
++ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
++ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
++ ti,min-output-impedance;
++ };
++};
++
++&mcu_cpsw_port1 {
++ status = "okay";
++ phy-mode = "rgmii-rxid";
++ phy-handle = <&mcu_phy0>;
++};
+--
+2.39.2
+
--- /dev/null
+From e38ee524b990553180a0394b7682e1a80805cda7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 16:49:30 -0500
+Subject: arm64: dts: ti: k3-j784s4-evm: Fix main_i2c0 alias
+
+From: Nishanth Menon <nm@ti.com>
+
+[ Upstream commit c10a9df30e3401bd5a5ee43f1afd6c2b2ca75ad7 ]
+
+main_i2c0 is aliased as i2c0 which creates a problem for u-boot R5
+SPL attempting to reuse the same definition in the common board
+detection logic as it looks for the first i2c instance as the bus on
+which to detect the eeprom to understand the board variant involved.
+Switch main_i2c0 to i2c3 alias allowing us to introduce wkup_i2c0
+and potentially space for mcu_i2c instances in the gap for follow on
+patches.
+
+Fixes: e20a06aca5c9 ("arm64: dts: ti: Add support for J784S4 EVM board")
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Reviewed-by: Udit Kumar <u-kumar1@ti.com>
+Link: https://lore.kernel.org/r/20230602214937.2349545-2-nm@ti.com
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+index 8cd4a7ecc121e..6b2d93d3c5e27 100644
+--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
++++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+@@ -22,7 +22,7 @@ chosen {
+ aliases {
+ serial2 = &main_uart8;
+ mmc1 = &main_sdhci1;
+- i2c0 = &main_i2c0;
++ i2c3 = &main_i2c0;
+ };
+
+ memory@80000000 {
+--
+2.39.2
+
--- /dev/null
+From 6f9f3348ba5bfe469ee88c013c3f344df41662d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 May 2023 14:01:43 +0530
+Subject: arm64: dts: ti: k3-j784s4: Fix wakeup pinmux range and pinctrl node
+ offsets
+
+From: Thejasvi Konduru <t-konduru@ti.com>
+
+[ Upstream commit 14462bd0b247d05070d48d0f02eb7ca2680ab7bd ]
+
+The wkup_pmx register region in j784s4 has multiple non-addressable
+regions, hence the existing wkup_pmx region is split as follows to
+avoid the non-addressable regions. The pinctrl node offsets are
+also corrected as per the newly split wkup_pmx* nodes.
+
+wkup_pmx0 -> 13 pins (WKUP_PADCONFIG 0 - 12)
+wkup_pmx1 -> 11 pins (WKUP_PADCONFIG 14 - 24)
+wkup_pmx2 -> 72 pins (WKUP_PADCONFIG 26 - 97)
+wkup_pmx3 -> 1 pin (WKUP_PADCONFIG 100)
+
+Fixes: 4664ebd8346a ("arm64: dts: ti: Add initial support for J784S4 SoC")
+Signed-off-by: Thejasvi Konduru <t-konduru@ti.com>
+Reviewed-by: Nishanth Menon <nm@ti.com>
+Link: https://lore.kernel.org/r/20230503083143.32369-1-t-konduru@ti.com
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 30 +++++++++----------
+ .../boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi | 29 +++++++++++++++++-
+ 2 files changed, 43 insertions(+), 16 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+index 0c4ee83fc9d75..ed575f17935b6 100644
+--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
++++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+@@ -140,28 +140,28 @@ J784S4_IOPAD(0x020, PIN_INPUT, 7) /* (AJ35) MCAN15_RX.GPIO0_8 */
+ };
+ };
+
+-&wkup_pmx0 {
++&wkup_pmx2 {
+ mcu_cpsw_pins_default: mcu-cpsw-pins-default {
+ pinctrl-single,pins = <
+- J784S4_WKUP_IOPAD(0x094, PIN_INPUT, 0) /* (A35) MCU_RGMII1_RD0 */
+- J784S4_WKUP_IOPAD(0x090, PIN_INPUT, 0) /* (B36) MCU_RGMII1_RD1 */
+- J784S4_WKUP_IOPAD(0x08c, PIN_INPUT, 0) /* (C36) MCU_RGMII1_RD2 */
+- J784S4_WKUP_IOPAD(0x088, PIN_INPUT, 0) /* (D36) MCU_RGMII1_RD3 */
+- J784S4_WKUP_IOPAD(0x084, PIN_INPUT, 0) /* (B37) MCU_RGMII1_RXC */
+- J784S4_WKUP_IOPAD(0x06c, PIN_INPUT, 0) /* (C37) MCU_RGMII1_RX_CTL */
+- J784S4_WKUP_IOPAD(0x07c, PIN_OUTPUT, 0) /* (D37) MCU_RGMII1_TD0 */
+- J784S4_WKUP_IOPAD(0x078, PIN_OUTPUT, 0) /* (D38) MCU_RGMII1_TD1 */
+- J784S4_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (E37) MCU_RGMII1_TD2 */
+- J784S4_WKUP_IOPAD(0x070, PIN_OUTPUT, 0) /* (E38) MCU_RGMII1_TD3 */
+- J784S4_WKUP_IOPAD(0x080, PIN_OUTPUT, 0) /* (E36) MCU_RGMII1_TXC */
+- J784S4_WKUP_IOPAD(0x068, PIN_OUTPUT, 0) /* (C38) MCU_RGMII1_TX_CTL */
++ J784S4_WKUP_IOPAD(0x02c, PIN_INPUT, 0) /* (A35) MCU_RGMII1_RD0 */
++ J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (B36) MCU_RGMII1_RD1 */
++ J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (C36) MCU_RGMII1_RD2 */
++ J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (D36) MCU_RGMII1_RD3 */
++ J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (B37) MCU_RGMII1_RXC */
++ J784S4_WKUP_IOPAD(0x004, PIN_INPUT, 0) /* (C37) MCU_RGMII1_RX_CTL */
++ J784S4_WKUP_IOPAD(0x014, PIN_OUTPUT, 0) /* (D37) MCU_RGMII1_TD0 */
++ J784S4_WKUP_IOPAD(0x010, PIN_OUTPUT, 0) /* (D38) MCU_RGMII1_TD1 */
++ J784S4_WKUP_IOPAD(0x00c, PIN_OUTPUT, 0) /* (E37) MCU_RGMII1_TD2 */
++ J784S4_WKUP_IOPAD(0x008, PIN_OUTPUT, 0) /* (E38) MCU_RGMII1_TD3 */
++ J784S4_WKUP_IOPAD(0x018, PIN_OUTPUT, 0) /* (E36) MCU_RGMII1_TXC */
++ J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (C38) MCU_RGMII1_TX_CTL */
+ >;
+ };
+
+ mcu_mdio_pins_default: mcu-mdio-pins-default {
+ pinctrl-single,pins = <
+- J784S4_WKUP_IOPAD(0x09c, PIN_OUTPUT, 0) /* (A36) MCU_MDIO0_MDC */
+- J784S4_WKUP_IOPAD(0x098, PIN_INPUT, 0) /* (B35) MCU_MDIO0_MDIO */
++ J784S4_WKUP_IOPAD(0x034, PIN_OUTPUT, 0) /* (A36) MCU_MDIO0_MDC */
++ J784S4_WKUP_IOPAD(0x030, PIN_INPUT, 0) /* (B35) MCU_MDIO0_MDIO */
+ >;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
+index 64bd3dee14aa6..8a2350f2c82d0 100644
+--- a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
+@@ -50,7 +50,34 @@ mcu_ram: sram@41c00000 {
+ wkup_pmx0: pinctrl@4301c000 {
+ compatible = "pinctrl-single";
+ /* Proxy 0 addressing */
+- reg = <0x00 0x4301c000 0x00 0x178>;
++ reg = <0x00 0x4301c000 0x00 0x034>;
++ #pinctrl-cells = <1>;
++ pinctrl-single,register-width = <32>;
++ pinctrl-single,function-mask = <0xffffffff>;
++ };
++
++ wkup_pmx1: pinctrl@4301c038 {
++ compatible = "pinctrl-single";
++ /* Proxy 0 addressing */
++ reg = <0x00 0x4301c038 0x00 0x02c>;
++ #pinctrl-cells = <1>;
++ pinctrl-single,register-width = <32>;
++ pinctrl-single,function-mask = <0xffffffff>;
++ };
++
++ wkup_pmx2: pinctrl@4301c068 {
++ compatible = "pinctrl-single";
++ /* Proxy 0 addressing */
++ reg = <0x00 0x4301c068 0x00 0x120>;
++ #pinctrl-cells = <1>;
++ pinctrl-single,register-width = <32>;
++ pinctrl-single,function-mask = <0xffffffff>;
++ };
++
++ wkup_pmx3: pinctrl@4301c190 {
++ compatible = "pinctrl-single";
++ /* Proxy 0 addressing */
++ reg = <0x00 0x4301c190 0x00 0x004>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffffffff>;
+--
+2.39.2
+
--- /dev/null
+From 9381108c991a3bb85613e5562a621249809f157a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Jun 2023 16:56:05 +0100
+Subject: arm64: sme: Use STR P to clear FFR context field in streaming SVE
+ mode
+
+From: Will Deacon <will@kernel.org>
+
+[ Upstream commit 893b24181b4c4bf1fa2841b1ed192e5413a97cb1 ]
+
+The FFR is a predicate register which can vary between 16 and 256 bits
+in size depending upon the configured vector length. When saving the
+SVE state in streaming SVE mode, the FFR register is inaccessible and
+so commit 9f5848665788 ("arm64/sve: Make access to FFR optional") simply
+clears the FFR field of the in-memory context structure. Unfortunately,
+it achieves this using an unconditional 8-byte store and so if the SME
+vector length is anything other than 64 bytes in size we will either
+fail to clear the entire field or, worse, we will corrupt memory
+immediately following the structure. This has led to intermittent kfence
+splats in CI [1] and can trigger kmalloc Redzone corruption messages
+when running the 'fp-stress' kselftest:
+
+ | =============================================================================
+ | BUG kmalloc-1k (Not tainted): kmalloc Redzone overwritten
+ | -----------------------------------------------------------------------------
+ |
+ | 0xffff000809bf1e22-0xffff000809bf1e27 @offset=7714. First byte 0x0 instead of 0xcc
+ | Allocated in do_sme_acc+0x9c/0x220 age=2613 cpu=1 pid=531
+ | __kmalloc+0x8c/0xcc
+ | do_sme_acc+0x9c/0x220
+ | ...
+
+Replace the 8-byte store with a store of a predicate register which has
+been zero-initialised with PFALSE, ensuring that the entire field is
+cleared in memory.
+
+[1] https://lore.kernel.org/r/CA+G9fYtU7HsV0R0dp4XEH5xXHSJFw8KyDf5VQrLLfMxWfxQkag@mail.gmail.com
+
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Naresh Kamboju <naresh.kamboju@linaro.org>
+Fixes: 9f5848665788 ("arm64/sve: Make access to FFR optional")
+Reported-by: Linux Kernel Functional Testing <lkft@linaro.org>
+Signed-off-by: Will Deacon <will@kernel.org>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Tested-by: Anders Roxell <anders.roxell@linaro.org>
+Link: https://lore.kernel.org/r/20230628155605.22296-1-will@kernel.org
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/fpsimdmacros.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h
+index cd03819a3b686..cdf6a35e39944 100644
+--- a/arch/arm64/include/asm/fpsimdmacros.h
++++ b/arch/arm64/include/asm/fpsimdmacros.h
+@@ -316,12 +316,12 @@
+ _for n, 0, 15, _sve_str_p \n, \nxbase, \n - 16
+ cbz \save_ffr, 921f
+ _sve_rdffr 0
+- _sve_str_p 0, \nxbase
+- _sve_ldr_p 0, \nxbase, -16
+ b 922f
+ 921:
+- str xzr, [x\nxbase] // Zero out FFR
++ _sve_pfalse 0 // Zero out FFR
+ 922:
++ _sve_str_p 0, \nxbase
++ _sve_ldr_p 0, \nxbase, -16
+ mrs x\nxtmp, fpsr
+ str w\nxtmp, [\xpfpsr]
+ mrs x\nxtmp, fpcr
+--
+2.39.2
+
--- /dev/null
+From 953fc9ddadbbe2d7284fecfbff205f2ccd9fcec7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 20:53:38 +0530
+Subject: ASoC: amd: acp: clear pdm dma interrupt mask
+
+From: Syed Saba Kareem <Syed.SabaKareem@amd.com>
+
+[ Upstream commit ad60672394bd1f95c58d3d9336902f47e05126fc ]
+
+Clear pdm dma interrupt mask in acp_dmic_shutdown().
+
+'Fixes: c32bd332ce5c9 ("ASoC: amd: acp: Add generic support for
+PDM controller on ACP")'
+
+Signed-off-by: Syed Saba Kareem <Syed.SabaKareem@amd.com>
+Link: https://lore.kernel.org/r/Message-Id: <20230622152406.3709231-1-Syed.SabaKareem@amd.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/acp/acp-pdm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/amd/acp/acp-pdm.c b/sound/soc/amd/acp/acp-pdm.c
+index 66ec6b6a59723..f8030b79ac17c 100644
+--- a/sound/soc/amd/acp/acp-pdm.c
++++ b/sound/soc/amd/acp/acp-pdm.c
+@@ -176,7 +176,7 @@ static void acp_dmic_dai_shutdown(struct snd_pcm_substream *substream,
+
+ /* Disable DMIC interrupts */
+ ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0));
+- ext_int_ctrl |= ~PDM_DMA_INTR_MASK;
++ ext_int_ctrl &= ~PDM_DMA_INTR_MASK;
+ writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0));
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 2189175d7712c5b22caf2968be4ce71e0b0c913f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 May 2023 11:55:25 +0800
+Subject: ASoC: dt-bindings: mediatek,mt8188-afe: correct clock name
+
+From: Trevor Wu <trevor.wu@mediatek.com>
+
+[ Upstream commit 1e4fe75e9746be8e40c57132bb3fba1ce3dd24af ]
+
+The original clock names are different from the list in driver code.
+Correct the mismatched binding names in the patch.
+
+Because no mt8188 upstream dts exists, it doesn't affect the existing
+dts file.
+
+Fixes: 692d25b67e10 ("ASoC: dt-bindings: mediatek,mt8188-afe: add audio afe document")
+Signed-off-by: Trevor Wu <trevor.wu@mediatek.com
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org
+Link: https://lore.kernel.org/r/20230510035526.18137-9-trevor.wu@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../bindings/sound/mediatek,mt8188-afe.yaml | 36 +++++++++----------
+ 1 file changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
+index 82ccb32f08f27..9e877f0d19fbb 100644
+--- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
++++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
+@@ -63,15 +63,15 @@ properties:
+ - const: apll12_div2
+ - const: apll12_div3
+ - const: apll12_div9
+- - const: a1sys_hp_sel
+- - const: aud_intbus_sel
+- - const: audio_h_sel
+- - const: audio_local_bus_sel
+- - const: dptx_m_sel
+- - const: i2so1_m_sel
+- - const: i2so2_m_sel
+- - const: i2si1_m_sel
+- - const: i2si2_m_sel
++ - const: top_a1sys_hp
++ - const: top_aud_intbus
++ - const: top_audio_h
++ - const: top_audio_local_bus
++ - const: top_dptx
++ - const: top_i2so1
++ - const: top_i2so2
++ - const: top_i2si1
++ - const: top_i2si2
+ - const: adsp_audio_26m
+
+ mediatek,etdm-in1-cowork-source:
+@@ -193,15 +193,15 @@ examples:
+ "apll12_div2",
+ "apll12_div3",
+ "apll12_div9",
+- "a1sys_hp_sel",
+- "aud_intbus_sel",
+- "audio_h_sel",
+- "audio_local_bus_sel",
+- "dptx_m_sel",
+- "i2so1_m_sel",
+- "i2so2_m_sel",
+- "i2si1_m_sel",
+- "i2si2_m_sel",
++ "top_a1sys_hp",
++ "top_aud_intbus",
++ "top_audio_h",
++ "top_audio_local_bus",
++ "top_dptx",
++ "top_i2so1",
++ "top_i2so2",
++ "top_i2si1",
++ "top_i2si2",
+ "adsp_audio_26m";
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 224d92fb017ae834aa9bb2ee716bd4b436a4c393 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 21:11:39 +0300
+Subject: ASoC: es8316: Do not set rate constraints for unsupported MCLKs
+
+From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+
+[ Upstream commit 60413129ee2b38a80347489270af7f6e1c1de4d0 ]
+
+When using the codec through the generic audio graph card, there are at
+least two calls of es8316_set_dai_sysclk(), with the effect of limiting
+the allowed sample rates according to the MCLK/LRCK ratios supported by
+the codec:
+
+1. During audio card setup, to set the initial MCLK - see
+ asoc_simple_init_dai().
+
+2. Before opening a stream, to update MCLK, according to the stream
+ sample rate and the multiplication factor - see
+ asoc_simple_hw_params().
+
+In some cases the initial MCLK might be set to a frequency that doesn't
+match any of the supported ratios, e.g. 12287999 instead of 12288000,
+which is only 1 Hz below the supported clock, as that is what the
+hardware reports. This creates an empty list of rate constraints, which
+is further passed to snd_pcm_hw_constraint_list() via
+es8316_pcm_startup(), and causes the following error on the very first
+access of the sound card:
+
+ $ speaker-test -D hw:Analog,0 -F S16_LE -c 2 -t wav
+ Broken configuration for playback: no configurations available: Invalid argument
+ Setting of hwparams failed: Invalid argument
+
+Note that all subsequent retries succeed thanks to the updated MCLK set
+at point 2 above, which uses a computed frequency value instead of a
+reading from the hardware registers. Normally this would have mitigated
+the issue, but es8316_pcm_startup() executes before the 2nd call to
+es8316_set_dai_sysclk(), hence it cannot make use of the updated
+constraints.
+
+Since es8316_pcm_hw_params() performs anyway a final validation of MCLK
+against the stream sample rate and the supported MCLK/LRCK ratios, fix
+the issue by ensuring that sysclk_constraints list is only set when at
+least one supported sample rate is autodetected by the codec.
+
+Fixes: b8b88b70875a ("ASoC: add es8316 codec driver")
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Link: https://lore.kernel.org/r/20230530181140.483936-3-cristian.ciocaltea@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/es8316.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
+index 2bfcd9af39172..87775378362e7 100644
+--- a/sound/soc/codecs/es8316.c
++++ b/sound/soc/codecs/es8316.c
+@@ -369,13 +369,11 @@ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int count = 0;
+
+ es8316->sysclk = freq;
++ es8316->sysclk_constraints.list = NULL;
++ es8316->sysclk_constraints.count = 0;
+
+- if (freq == 0) {
+- es8316->sysclk_constraints.list = NULL;
+- es8316->sysclk_constraints.count = 0;
+-
++ if (freq == 0)
+ return 0;
+- }
+
+ ret = clk_set_rate(es8316->mclk, freq);
+ if (ret)
+@@ -391,8 +389,10 @@ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ es8316->allowed_rates[count++] = freq / ratio;
+ }
+
+- es8316->sysclk_constraints.list = es8316->allowed_rates;
+- es8316->sysclk_constraints.count = count;
++ if (count) {
++ es8316->sysclk_constraints.list = es8316->allowed_rates;
++ es8316->sysclk_constraints.count = count;
++ }
+
+ return 0;
+ }
+--
+2.39.2
+
--- /dev/null
+From 87eb266e4e873a6cb39f7b131850dba064003aee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 21:11:38 +0300
+Subject: ASoC: es8316: Increment max value for ALC Capture Target Volume
+ control
+
+From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+
+[ Upstream commit 6f073429037cd79d7311cd8236311c53f5ea8f01 ]
+
+The following error occurs when trying to restore a previously saved
+ALSA mixer state (tested on a Rock 5B board):
+
+ $ alsactl --no-ucm -f /tmp/asound.state store hw:Analog
+ $ alsactl --no-ucm -I -f /tmp/asound.state restore hw:Analog
+ alsactl: set_control:1475: Cannot write control '2:0:0:ALC Capture Target Volume:0' : Invalid argument
+
+According to ES8316 datasheet, the register at address 0x2B, which is
+related to the above mixer control, contains by default the value 0xB0.
+Considering the corresponding ALC target bits (ALCLVL) are 7:4, the
+control is initialized with 11, which is one step above the maximum
+value allowed by the driver:
+
+ ALCLVL | dB gain
+ -------+--------
+ 0000 | -16.5
+ 0001 | -15.0
+ 0010 | -13.5
+ .... | .....
+ 0111 | -6.0
+ 1000 | -4.5
+ 1001 | -3.0
+ 1010 | -1.5
+ .... | .....
+ 1111 | -1.5
+
+The tests performed using the VU meter feature (--vumeter=TYPE) of
+arecord/aplay confirm the specs are correct and there is no measured
+gain if the 1011-1111 range would have been mapped to 0 dB:
+
+ dB gain | VU meter %
+ --------+-----------
+ -6.0 | 30-31
+ -4.5 | 35-36
+ -3.0 | 42-43
+ -1.5 | 50-51
+ 0.0 | 50-51
+
+Increment the max value allowed for ALC Capture Target Volume control,
+so that it matches the hardware default. Additionally, update the
+related TLV to prevent an artificial extension of the dB gain range.
+
+Fixes: b8b88b70875a ("ASoC: add es8316 codec driver")
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Link: https://lore.kernel.org/r/20230530181140.483936-2-cristian.ciocaltea@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/es8316.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
+index f7d7a9c91e04c..2bfcd9af39172 100644
+--- a/sound/soc/codecs/es8316.c
++++ b/sound/soc/codecs/es8316.c
+@@ -52,7 +52,12 @@ static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9600, 50, 1);
+ static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9600, 50, 1);
+ static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv, -650, 150, 0);
+ static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv, -1200, 150, 0);
+-static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_target_tlv, -1650, 150, 0);
++
++static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(alc_target_tlv,
++ 0, 10, TLV_DB_SCALE_ITEM(-1650, 150, 0),
++ 11, 11, TLV_DB_SCALE_ITEM(-150, 0, 0),
++);
++
+ static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpmixer_gain_tlv,
+ 0, 4, TLV_DB_SCALE_ITEM(-1200, 150, 0),
+ 8, 11, TLV_DB_SCALE_ITEM(-450, 150, 0),
+@@ -115,7 +120,7 @@ static const struct snd_kcontrol_new es8316_snd_controls[] = {
+ alc_max_gain_tlv),
+ SOC_SINGLE_TLV("ALC Capture Min Volume", ES8316_ADC_ALC2, 0, 28, 0,
+ alc_min_gain_tlv),
+- SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 10, 0,
++ SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 11, 0,
+ alc_target_tlv),
+ SOC_SINGLE("ALC Capture Hold Time", ES8316_ADC_ALC3, 0, 10, 0),
+ SOC_SINGLE("ALC Capture Decay Time", ES8316_ADC_ALC4, 4, 10, 0),
+--
+2.39.2
+
--- /dev/null
+From b3cb99b546169ed0d83895a0c735db934f46ea5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 15:15:09 +0300
+Subject: ASoC: imx-audmix: check return value of devm_kasprintf()
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit 2f76e1d6ca524a888d29aafe29f2ad2003857971 ]
+
+devm_kasprintf() returns a pointer to dynamically allocated memory.
+Pointer could be NULL in case allocation fails. Check pointer validity.
+Identified with coccinelle (kmerr.cocci script).
+
+Fixes: b86ef5367761 ("ASoC: fsl: Add Audio Mixer machine driver")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230614121509.443926-1-claudiu.beznea@microchip.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/imx-audmix.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
+index 1292a845c4244..d8e99b263ab21 100644
+--- a/sound/soc/fsl/imx-audmix.c
++++ b/sound/soc/fsl/imx-audmix.c
+@@ -228,6 +228,8 @@ static int imx_audmix_probe(struct platform_device *pdev)
+
+ dai_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%s",
+ fe_name_pref, args.np->full_name + 1);
++ if (!dai_name)
++ return -ENOMEM;
+
+ dev_info(pdev->dev.parent, "DAI FE name:%s\n", dai_name);
+
+@@ -236,6 +238,8 @@ static int imx_audmix_probe(struct platform_device *pdev)
+ capture_dai_name =
+ devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
+ dai_name, "CPU-Capture");
++ if (!capture_dai_name)
++ return -ENOMEM;
+ }
+
+ priv->dai[i].cpus = &dlc[0];
+@@ -266,6 +270,8 @@ static int imx_audmix_probe(struct platform_device *pdev)
+ "AUDMIX-Playback-%d", i);
+ be_cp = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+ "AUDMIX-Capture-%d", i);
++ if (!be_name || !be_pb || !be_cp)
++ return -ENOMEM;
+
+ priv->dai[num_dai + i].cpus = &dlc[3];
+ priv->dai[num_dai + i].codecs = &dlc[4];
+@@ -293,6 +299,9 @@ static int imx_audmix_probe(struct platform_device *pdev)
+ priv->dapm_routes[i].source =
+ devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
+ dai_name, "CPU-Playback");
++ if (!priv->dapm_routes[i].source)
++ return -ENOMEM;
++
+ priv->dapm_routes[i].sink = be_pb;
+ priv->dapm_routes[num_dai + i].source = be_pb;
+ priv->dapm_routes[num_dai + i].sink = be_cp;
+--
+2.39.2
+
--- /dev/null
+From 49ebc49dca49b922c48d038fe07c69a2483ee6aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 12:32:59 -0500
+Subject: ASoC: Intel: sof_sdw: remove SOF_SDW_TGL_HDMI for MeteorLake devices
+
+From: Bard Liao <yung-chuan.liao@linux.intel.com>
+
+[ Upstream commit 0db94947c9d3da16aa31d152b7d26fab78b02cb9 ]
+
+Topologies support three HDMI links on MeteorLake devices only.
+
+Fixes: 18489174e4fb ("ASoC: intel: sof_sdw: add RT711 SDCA card for MTL platform")
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com
+Link: https://lore.kernel.org/r/20230512173305.65399-3-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_sdw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index 767fa89d08708..1ac5abc721c68 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -413,7 +413,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_mtlrvp"),
+ },
+- .driver_data = (void *)(RT711_JD1 | SOF_SDW_TGL_HDMI),
++ .driver_data = (void *)(RT711_JD1),
+ },
+ {}
+ };
+--
+2.39.2
+
--- /dev/null
+From b0f4b8a8649e70caf3cc866d238ad1bce952dee2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 14:07:24 -0400
+Subject: blk-cgroup: Reinit blkg_iostat_set after clearing in
+ blkcg_reset_stats()
+
+From: Waiman Long <longman@redhat.com>
+
+[ Upstream commit 3d2af77e31ade05ff7ccc3658c3635ec1bea0979 ]
+
+When blkg_alloc() is called to allocate a blkcg_gq structure
+with the associated blkg_iostat_set's, there are 2 fields within
+blkg_iostat_set that requires proper initialization - blkg & sync.
+The former field was introduced by commit 3b8cc6298724 ("blk-cgroup:
+Optimize blkcg_rstat_flush()") while the later one was introduced by
+commit f73316482977 ("blk-cgroup: reimplement basic IO stats using
+cgroup rstat").
+
+Unfortunately those fields in the blkg_iostat_set's are not properly
+re-initialized when they are cleared in v1's blkcg_reset_stats(). This
+can lead to a kernel panic due to NULL pointer access of the blkg
+pointer. The missing initialization of sync is less problematic and
+can be a problem in a debug kernel due to missing lockdep initialization.
+
+Fix these problems by re-initializing them after memory clearing.
+
+Fixes: 3b8cc6298724 ("blk-cgroup: Optimize blkcg_rstat_flush()")
+Fixes: f73316482977 ("blk-cgroup: reimplement basic IO stats using cgroup rstat")
+Signed-off-by: Waiman Long <longman@redhat.com>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Link: https://lore.kernel.org/r/20230606180724.2455066-1-longman@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-cgroup.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index ad0cd992a6519..c50da8b3af029 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -585,8 +585,13 @@ static int blkcg_reset_stats(struct cgroup_subsys_state *css,
+ struct blkg_iostat_set *bis =
+ per_cpu_ptr(blkg->iostat_cpu, cpu);
+ memset(bis, 0, sizeof(*bis));
++
++ /* Re-initialize the cleared blkg_iostat_set */
++ u64_stats_init(&bis->sync);
++ bis->blkg = blkg;
+ }
+ memset(&blkg->iostat, 0, sizeof(blkg->iostat));
++ u64_stats_init(&blkg->iostat.sync);
+
+ for (i = 0; i < BLKCG_MAX_POLS; i++) {
+ struct blkcg_policy *pol = blkcg_policy[i];
+--
+2.39.2
+
--- /dev/null
+From 8510a0735d33de52a12fc8c400603ba6f3bcd0e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 May 2023 17:19:04 +0800
+Subject: blk-iocost: use spin_lock_irqsave in adjust_inuse_and_calc_cost
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 8d211554679d0b23702bd32ba04aeac0c1c4f660 ]
+
+adjust_inuse_and_calc_cost() use spin_lock_irq() and IRQ will be enabled
+when unlock. DEADLOCK might happen if we have held other locks and disabled
+IRQ before invoking it.
+
+Fix it by using spin_lock_irqsave() instead, which can keep IRQ state
+consistent with before when unlock.
+
+ ================================
+ WARNING: inconsistent lock state
+ 5.10.0-02758-g8e5f91fd772f #26 Not tainted
+ --------------------------------
+ inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
+ kworker/2:3/388 [HC0[0]:SC0[0]:HE0:SE1] takes:
+ ffff888118c00c28 (&bfqd->lock){?.-.}-{2:2}, at: spin_lock_irq
+ ffff888118c00c28 (&bfqd->lock){?.-.}-{2:2}, at: bfq_bio_merge+0x141/0x390
+ {IN-HARDIRQ-W} state was registered at:
+ __lock_acquire+0x3d7/0x1070
+ lock_acquire+0x197/0x4a0
+ __raw_spin_lock_irqsave
+ _raw_spin_lock_irqsave+0x3b/0x60
+ bfq_idle_slice_timer_body
+ bfq_idle_slice_timer+0x53/0x1d0
+ __run_hrtimer+0x477/0xa70
+ __hrtimer_run_queues+0x1c6/0x2d0
+ hrtimer_interrupt+0x302/0x9e0
+ local_apic_timer_interrupt
+ __sysvec_apic_timer_interrupt+0xfd/0x420
+ run_sysvec_on_irqstack_cond
+ sysvec_apic_timer_interrupt+0x46/0xa0
+ asm_sysvec_apic_timer_interrupt+0x12/0x20
+ irq event stamp: 837522
+ hardirqs last enabled at (837521): [<ffffffff84b9419d>] __raw_spin_unlock_irqrestore
+ hardirqs last enabled at (837521): [<ffffffff84b9419d>] _raw_spin_unlock_irqrestore+0x3d/0x40
+ hardirqs last disabled at (837522): [<ffffffff84b93fa3>] __raw_spin_lock_irq
+ hardirqs last disabled at (837522): [<ffffffff84b93fa3>] _raw_spin_lock_irq+0x43/0x50
+ softirqs last enabled at (835852): [<ffffffff84e00558>] __do_softirq+0x558/0x8ec
+ softirqs last disabled at (835845): [<ffffffff84c010ff>] asm_call_irq_on_stack+0xf/0x20
+
+ other info that might help us debug this:
+ Possible unsafe locking scenario:
+
+ CPU0
+ ----
+ lock(&bfqd->lock);
+ <Interrupt>
+ lock(&bfqd->lock);
+
+ *** DEADLOCK ***
+
+ 3 locks held by kworker/2:3/388:
+ #0: ffff888107af0f38 ((wq_completion)kthrotld){+.+.}-{0:0}, at: process_one_work+0x742/0x13f0
+ #1: ffff8881176bfdd8 ((work_completion)(&td->dispatch_work)){+.+.}-{0:0}, at: process_one_work+0x777/0x13f0
+ #2: ffff888118c00c28 (&bfqd->lock){?.-.}-{2:2}, at: spin_lock_irq
+ #2: ffff888118c00c28 (&bfqd->lock){?.-.}-{2:2}, at: bfq_bio_merge+0x141/0x390
+
+ stack backtrace:
+ CPU: 2 PID: 388 Comm: kworker/2:3 Not tainted 5.10.0-02758-g8e5f91fd772f #26
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
+ Workqueue: kthrotld blk_throtl_dispatch_work_fn
+ Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x107/0x167
+ print_usage_bug
+ valid_state
+ mark_lock_irq.cold+0x32/0x3a
+ mark_lock+0x693/0xbc0
+ mark_held_locks+0x9e/0xe0
+ __trace_hardirqs_on_caller
+ lockdep_hardirqs_on_prepare.part.0+0x151/0x360
+ trace_hardirqs_on+0x5b/0x180
+ __raw_spin_unlock_irq
+ _raw_spin_unlock_irq+0x24/0x40
+ spin_unlock_irq
+ adjust_inuse_and_calc_cost+0x4fb/0x970
+ ioc_rqos_merge+0x277/0x740
+ __rq_qos_merge+0x62/0xb0
+ rq_qos_merge
+ bio_attempt_back_merge+0x12c/0x4a0
+ blk_mq_sched_try_merge+0x1b6/0x4d0
+ bfq_bio_merge+0x24a/0x390
+ __blk_mq_sched_bio_merge+0xa6/0x460
+ blk_mq_sched_bio_merge
+ blk_mq_submit_bio+0x2e7/0x1ee0
+ __submit_bio_noacct_mq+0x175/0x3b0
+ submit_bio_noacct+0x1fb/0x270
+ blk_throtl_dispatch_work_fn+0x1ef/0x2b0
+ process_one_work+0x83e/0x13f0
+ process_scheduled_works
+ worker_thread+0x7e3/0xd80
+ kthread+0x353/0x470
+ ret_from_fork+0x1f/0x30
+
+Fixes: b0853ab4a238 ("blk-iocost: revamp in-period donation snapbacks")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20230527091904.3001833-1-linan666@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-iocost.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/block/blk-iocost.c b/block/blk-iocost.c
+index 285ced3467abb..6084a9519883e 100644
+--- a/block/blk-iocost.c
++++ b/block/blk-iocost.c
+@@ -2455,6 +2455,7 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime,
+ u32 hwi, adj_step;
+ s64 margin;
+ u64 cost, new_inuse;
++ unsigned long flags;
+
+ current_hweight(iocg, NULL, &hwi);
+ old_hwi = hwi;
+@@ -2473,11 +2474,11 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime,
+ iocg->inuse == iocg->active)
+ return cost;
+
+- spin_lock_irq(&ioc->lock);
++ spin_lock_irqsave(&ioc->lock, flags);
+
+ /* we own inuse only when @iocg is in the normal active state */
+ if (iocg->abs_vdebt || list_empty(&iocg->active_list)) {
+- spin_unlock_irq(&ioc->lock);
++ spin_unlock_irqrestore(&ioc->lock, flags);
+ return cost;
+ }
+
+@@ -2498,7 +2499,7 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime,
+ } while (time_after64(vtime + cost, now->vnow) &&
+ iocg->inuse != iocg->active);
+
+- spin_unlock_irq(&ioc->lock);
++ spin_unlock_irqrestore(&ioc->lock, flags);
+
+ TRACE_IOCG_PATH(inuse_adjust, iocg, now,
+ old_inuse, iocg->inuse, old_hwi, hwi);
+--
+2.39.2
+
--- /dev/null
+From d74e29b02e06af5636acb504e0771b64f38b2a4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Jun 2023 10:30:43 +0800
+Subject: blk-mq: fix potential io hang by wrong 'wake_batch'
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 4f1731df60f9033669f024d06ae26a6301260b55 ]
+
+In __blk_mq_tag_busy/idle(), updating 'active_queues' and calculating
+'wake_batch' is not atomic:
+
+t1: t2:
+_blk_mq_tag_busy blk_mq_tag_busy
+inc active_queues
+// assume 1->2
+ inc active_queues
+ // 2 -> 3
+ blk_mq_update_wake_batch
+ // calculate based on 3
+blk_mq_update_wake_batch
+/* calculate based on 2, while active_queues is actually 3. */
+
+Fix this problem by protecting them wih 'tags->lock', this is not a hot
+path, so performance should not be concerned. And now that all writers
+are inside the lock, switch 'actives_queues' from atomic to unsigned
+int.
+
+Fixes: 180dccb0dba4 ("blk-mq: fix tag_get wait task can't be awakened")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20230610023043.2559121-1-yukuai1@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq-debugfs.c | 2 +-
+ block/blk-mq-tag.c | 15 ++++++++++-----
+ block/blk-mq.h | 3 +--
+ include/linux/blk-mq.h | 3 +--
+ 4 files changed, 13 insertions(+), 10 deletions(-)
+
+diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
+index b01818f8e216e..c152276736832 100644
+--- a/block/blk-mq-debugfs.c
++++ b/block/blk-mq-debugfs.c
+@@ -427,7 +427,7 @@ static void blk_mq_debugfs_tags_show(struct seq_file *m,
+ seq_printf(m, "nr_tags=%u\n", tags->nr_tags);
+ seq_printf(m, "nr_reserved_tags=%u\n", tags->nr_reserved_tags);
+ seq_printf(m, "active_queues=%d\n",
+- atomic_read(&tags->active_queues));
++ READ_ONCE(tags->active_queues));
+
+ seq_puts(m, "\nbitmap_tags:\n");
+ sbitmap_queue_show(&tags->bitmap_tags, m);
+diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
+index a80d7c62bdfe6..100889c276c3f 100644
+--- a/block/blk-mq-tag.c
++++ b/block/blk-mq-tag.c
+@@ -40,6 +40,7 @@ static void blk_mq_update_wake_batch(struct blk_mq_tags *tags,
+ void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx)
+ {
+ unsigned int users;
++ struct blk_mq_tags *tags = hctx->tags;
+
+ /*
+ * calling test_bit() prior to test_and_set_bit() is intentional,
+@@ -57,9 +58,11 @@ void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx)
+ return;
+ }
+
+- users = atomic_inc_return(&hctx->tags->active_queues);
+-
+- blk_mq_update_wake_batch(hctx->tags, users);
++ spin_lock_irq(&tags->lock);
++ users = tags->active_queues + 1;
++ WRITE_ONCE(tags->active_queues, users);
++ blk_mq_update_wake_batch(tags, users);
++ spin_unlock_irq(&tags->lock);
+ }
+
+ /*
+@@ -92,9 +95,11 @@ void __blk_mq_tag_idle(struct blk_mq_hw_ctx *hctx)
+ return;
+ }
+
+- users = atomic_dec_return(&tags->active_queues);
+-
++ spin_lock_irq(&tags->lock);
++ users = tags->active_queues - 1;
++ WRITE_ONCE(tags->active_queues, users);
+ blk_mq_update_wake_batch(tags, users);
++ spin_unlock_irq(&tags->lock);
+
+ blk_mq_tag_wakeup_all(tags, false);
+ }
+diff --git a/block/blk-mq.h b/block/blk-mq.h
+index a7482d2cc82e7..4542308c8e62f 100644
+--- a/block/blk-mq.h
++++ b/block/blk-mq.h
+@@ -362,8 +362,7 @@ static inline bool hctx_may_queue(struct blk_mq_hw_ctx *hctx,
+ return true;
+ }
+
+- users = atomic_read(&hctx->tags->active_queues);
+-
++ users = READ_ONCE(hctx->tags->active_queues);
+ if (!users)
+ return true;
+
+diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
+index de0b0c3e7395a..4110d6e99b2b9 100644
+--- a/include/linux/blk-mq.h
++++ b/include/linux/blk-mq.h
+@@ -748,8 +748,7 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
+ struct blk_mq_tags {
+ unsigned int nr_tags;
+ unsigned int nr_reserved_tags;
+-
+- atomic_t active_queues;
++ unsigned int active_queues;
+
+ struct sbitmap_queue bitmap_tags;
+ struct sbitmap_queue breserved_tags;
+--
+2.39.2
+
--- /dev/null
+From 448882aff59adf56490282387c8f02bc4a2b5097 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Apr 2023 14:06:46 -1000
+Subject: blkcg: Drop unnecessary RCU read [un]locks from
+ blkg_conf_prep/finish()
+
+From: Tejun Heo <tj@kernel.org>
+
+[ Upstream commit 83462a6c971cdc550475b672cf29bd3b53bedf84 ]
+
+Now that all RCU flavors have been combined either holding a spin lock,
+disabling irq or disabling preemption implies RCU read lock, so there's no
+need to use rcu_read_[un]lock() explicitly while holding queue_lock. This
+shouldn't cause any behavior changes.
+
+v2: Description updated. Leave __acquires/release on queue_lock alone.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20230413000649.115785-2-tj@kernel.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: a13bd91be223 ("block/rq_qos: protect rq_qos apis with a new lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-cgroup.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index 581aa08e34a8e..b2bdf76ec931d 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -716,12 +716,12 @@ struct block_device *blkcg_conf_open_bdev(char **inputp)
+ *
+ * Parse per-blkg config update from @input and initialize @ctx with the
+ * result. @ctx->blkg points to the blkg to be updated and @ctx->body the
+- * part of @input following MAJ:MIN. This function returns with RCU read
+- * lock and queue lock held and must be paired with blkg_conf_finish().
++ * part of @input following MAJ:MIN. This function returns with queue lock
++ * held and must be paired with blkg_conf_finish().
+ */
+ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+ char *input, struct blkg_conf_ctx *ctx)
+- __acquires(rcu) __acquires(&bdev->bd_queue->queue_lock)
++ __acquires(&bdev->bd_queue->queue_lock)
+ {
+ struct block_device *bdev;
+ struct gendisk *disk;
+@@ -743,7 +743,6 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+ if (ret)
+ goto fail;
+
+- rcu_read_lock();
+ spin_lock_irq(&q->queue_lock);
+
+ if (!blkcg_policy_enabled(q, pol)) {
+@@ -772,7 +771,6 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+
+ /* Drop locks to do new blkg allocation with GFP_KERNEL. */
+ spin_unlock_irq(&q->queue_lock);
+- rcu_read_unlock();
+
+ new_blkg = blkg_alloc(pos, disk, GFP_KERNEL);
+ if (unlikely(!new_blkg)) {
+@@ -786,7 +784,6 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+ goto fail_exit_queue;
+ }
+
+- rcu_read_lock();
+ spin_lock_irq(&q->queue_lock);
+
+ if (!blkcg_policy_enabled(q, pol)) {
+@@ -822,7 +819,6 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+ radix_tree_preload_end();
+ fail_unlock:
+ spin_unlock_irq(&q->queue_lock);
+- rcu_read_unlock();
+ fail_exit_queue:
+ blk_queue_exit(q);
+ fail:
+@@ -849,10 +845,9 @@ EXPORT_SYMBOL_GPL(blkg_conf_prep);
+ * with blkg_conf_prep().
+ */
+ void blkg_conf_finish(struct blkg_conf_ctx *ctx)
+- __releases(&ctx->bdev->bd_queue->queue_lock) __releases(rcu)
++ __releases(&ctx->bdev->bd_queue->queue_lock)
+ {
+ spin_unlock_irq(&bdev_get_queue(ctx->bdev)->queue_lock);
+- rcu_read_unlock();
+ blkdev_put_no_open(ctx->bdev);
+ }
+ EXPORT_SYMBOL_GPL(blkg_conf_finish);
+--
+2.39.2
+
--- /dev/null
+From fea7599e8ae67d2b97701b84eff819c150b392b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Apr 2023 14:06:47 -1000
+Subject: blkcg: Restructure blkg_conf_prep() and friends
+
+From: Tejun Heo <tj@kernel.org>
+
+[ Upstream commit faffaab2895914a803e011600164683bf747fee3 ]
+
+We want to support lazy init of rq-qos policies so that iolatency is enabled
+lazily on configuration instead of gendisk initialization. The way blkg
+config helpers are structured now is a bit awkward for that. Let's
+restructure:
+
+* blkcg_conf_open_bdev() is renamed to blkg_conf_open_bdev(). The blkcg_
+ prefix was used because the bdev opening step is blkg-independent.
+ However, the distinction is too subtle and confuses more than helps. Let's
+ switch to blkg prefix so that it's consistent with the type and other
+ helper names.
+
+* struct blkg_conf_ctx now remembers the original input string and is always
+ initialized by the new blkg_conf_init().
+
+* blkg_conf_open_bdev() is updated to take a pointer to blkg_conf_ctx like
+ blkg_conf_prep() and can be called multiple times safely. Instead of
+ modifying the double pointer to input string directly,
+ blkg_conf_open_bdev() now sets blkg_conf_ctx->body.
+
+* blkg_conf_finish() is renamed to blkg_conf_exit() for symmetry and now
+ must be called on all blkg_conf_ctx's which were initialized with
+ blkg_conf_init().
+
+Combined, this allows the users to either open the bdev first or do it
+altogether with blkg_conf_prep() which will help implementing lazy init of
+rq-qos policies.
+
+blkg_conf_init/exit() will also be used implement synchronization against
+device removal. This is necessary because iolat / iocost are configured
+through cgroupfs instead of one of the files under /sys/block/DEVICE. As
+cgroupfs operations aren't synchronized with block layer, the lazy init and
+other configuration operations may race against device removal. This patch
+makes blkg_conf_init/exit() used consistently for all cgroup-orginating
+configurations making them a good place to implement explicit
+synchronization.
+
+Users are updated accordingly. No behavior change is intended by this patch.
+
+v2: bfq wasn't updated in v1 causing a build error. Fixed.
+
+v3: Update the description to include future use of blkg_conf_init/exit() as
+ synchronization points.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Cc: Josef Bacik <josef@toxicpanda.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Yu Kuai <yukuai1@huaweicloud.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20230413000649.115785-3-tj@kernel.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: a13bd91be223 ("block/rq_qos: protect rq_qos apis with a new lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bfq-cgroup.c | 8 ++--
+ block/blk-cgroup.c | 105 +++++++++++++++++++++++++++---------------
+ block/blk-cgroup.h | 10 ++--
+ block/blk-iocost.c | 58 +++++++++++++----------
+ block/blk-iolatency.c | 8 ++--
+ block/blk-throttle.c | 16 ++++---
+ 6 files changed, 127 insertions(+), 78 deletions(-)
+
+diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
+index 89ffb3aa992c1..05e57b467bd97 100644
+--- a/block/bfq-cgroup.c
++++ b/block/bfq-cgroup.c
+@@ -1111,9 +1111,11 @@ static ssize_t bfq_io_set_device_weight(struct kernfs_open_file *of,
+ struct bfq_group *bfqg;
+ u64 v;
+
+- ret = blkg_conf_prep(blkcg, &blkcg_policy_bfq, buf, &ctx);
++ blkg_conf_init(&ctx, buf);
++
++ ret = blkg_conf_prep(blkcg, &blkcg_policy_bfq, &ctx);
+ if (ret)
+- return ret;
++ goto out;
+
+ if (sscanf(ctx.body, "%llu", &v) == 1) {
+ /* require "default" on dfl */
+@@ -1135,7 +1137,7 @@ static ssize_t bfq_io_set_device_weight(struct kernfs_open_file *of,
+ ret = 0;
+ }
+ out:
+- blkg_conf_finish(&ctx);
++ blkg_conf_exit(&ctx);
+ return ret ?: nbytes;
+ }
+
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index b2bdf76ec931d..0399b6e644b28 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -670,69 +670,93 @@ u64 __blkg_prfill_u64(struct seq_file *sf, struct blkg_policy_data *pd, u64 v)
+ EXPORT_SYMBOL_GPL(__blkg_prfill_u64);
+
+ /**
+- * blkcg_conf_open_bdev - parse and open bdev for per-blkg config update
+- * @inputp: input string pointer
++ * blkg_conf_init - initialize a blkg_conf_ctx
++ * @ctx: blkg_conf_ctx to initialize
++ * @input: input string
+ *
+- * Parse the device node prefix part, MAJ:MIN, of per-blkg config update
+- * from @input and get and return the matching bdev. *@inputp is
+- * updated to point past the device node prefix. Returns an ERR_PTR()
+- * value on error.
++ * Initialize @ctx which can be used to parse blkg config input string @input.
++ * Once initialized, @ctx can be used with blkg_conf_open_bdev() and
++ * blkg_conf_prep(), and must be cleaned up with blkg_conf_exit().
++ */
++void blkg_conf_init(struct blkg_conf_ctx *ctx, char *input)
++{
++ *ctx = (struct blkg_conf_ctx){ .input = input };
++}
++EXPORT_SYMBOL_GPL(blkg_conf_init);
++
++/**
++ * blkg_conf_open_bdev - parse and open bdev for per-blkg config update
++ * @ctx: blkg_conf_ctx initialized with blkg_conf_init()
+ *
+- * Use this function iff blkg_conf_prep() can't be used for some reason.
++ * Parse the device node prefix part, MAJ:MIN, of per-blkg config update from
++ * @ctx->input and get and store the matching bdev in @ctx->bdev. @ctx->body is
++ * set to point past the device node prefix.
++ *
++ * This function may be called multiple times on @ctx and the extra calls become
++ * NOOPs. blkg_conf_prep() implicitly calls this function. Use this function
++ * explicitly if bdev access is needed without resolving the blkcg / policy part
++ * of @ctx->input. Returns -errno on error.
+ */
+-struct block_device *blkcg_conf_open_bdev(char **inputp)
++int blkg_conf_open_bdev(struct blkg_conf_ctx *ctx)
+ {
+- char *input = *inputp;
++ char *input = ctx->input;
+ unsigned int major, minor;
+ struct block_device *bdev;
+ int key_len;
+
++ if (ctx->bdev)
++ return 0;
++
+ if (sscanf(input, "%u:%u%n", &major, &minor, &key_len) != 2)
+- return ERR_PTR(-EINVAL);
++ return -EINVAL;
+
+ input += key_len;
+ if (!isspace(*input))
+- return ERR_PTR(-EINVAL);
++ return -EINVAL;
+ input = skip_spaces(input);
+
+ bdev = blkdev_get_no_open(MKDEV(major, minor));
+ if (!bdev)
+- return ERR_PTR(-ENODEV);
++ return -ENODEV;
+ if (bdev_is_partition(bdev)) {
+ blkdev_put_no_open(bdev);
+- return ERR_PTR(-ENODEV);
++ return -ENODEV;
+ }
+
+- *inputp = input;
+- return bdev;
++ ctx->body = input;
++ ctx->bdev = bdev;
++ return 0;
+ }
+
+ /**
+ * blkg_conf_prep - parse and prepare for per-blkg config update
+ * @blkcg: target block cgroup
+ * @pol: target policy
+- * @input: input string
+- * @ctx: blkg_conf_ctx to be filled
++ * @ctx: blkg_conf_ctx initialized with blkg_conf_init()
++ *
++ * Parse per-blkg config update from @ctx->input and initialize @ctx
++ * accordingly. On success, @ctx->body points to the part of @ctx->input
++ * following MAJ:MIN, @ctx->bdev points to the target block device and
++ * @ctx->blkg to the blkg being configured.
+ *
+- * Parse per-blkg config update from @input and initialize @ctx with the
+- * result. @ctx->blkg points to the blkg to be updated and @ctx->body the
+- * part of @input following MAJ:MIN. This function returns with queue lock
+- * held and must be paired with blkg_conf_finish().
++ * blkg_conf_open_bdev() may be called on @ctx beforehand. On success, this
++ * function returns with queue lock held and must be followed by
++ * blkg_conf_exit().
+ */
+ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+- char *input, struct blkg_conf_ctx *ctx)
++ struct blkg_conf_ctx *ctx)
+ __acquires(&bdev->bd_queue->queue_lock)
+ {
+- struct block_device *bdev;
+ struct gendisk *disk;
+ struct request_queue *q;
+ struct blkcg_gq *blkg;
+ int ret;
+
+- bdev = blkcg_conf_open_bdev(&input);
+- if (IS_ERR(bdev))
+- return PTR_ERR(bdev);
+- disk = bdev->bd_disk;
++ ret = blkg_conf_open_bdev(ctx);
++ if (ret)
++ return ret;
++
++ disk = ctx->bdev->bd_disk;
+ q = disk->queue;
+
+ /*
+@@ -810,9 +834,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+ }
+ success:
+ blk_queue_exit(q);
+- ctx->bdev = bdev;
+ ctx->blkg = blkg;
+- ctx->body = input;
+ return 0;
+
+ fail_preloaded:
+@@ -822,7 +844,6 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+ fail_exit_queue:
+ blk_queue_exit(q);
+ fail:
+- blkdev_put_no_open(bdev);
+ /*
+ * If queue was bypassing, we should retry. Do so after a
+ * short msleep(). It isn't strictly necessary but queue
+@@ -838,19 +859,27 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+ EXPORT_SYMBOL_GPL(blkg_conf_prep);
+
+ /**
+- * blkg_conf_finish - finish up per-blkg config update
+- * @ctx: blkg_conf_ctx initialized by blkg_conf_prep()
++ * blkg_conf_exit - clean up per-blkg config update
++ * @ctx: blkg_conf_ctx initialized with blkg_conf_init()
+ *
+- * Finish up after per-blkg config update. This function must be paired
+- * with blkg_conf_prep().
++ * Clean up after per-blkg config update. This function must be called on all
++ * blkg_conf_ctx's initialized with blkg_conf_init().
+ */
+-void blkg_conf_finish(struct blkg_conf_ctx *ctx)
++void blkg_conf_exit(struct blkg_conf_ctx *ctx)
+ __releases(&ctx->bdev->bd_queue->queue_lock)
+ {
+- spin_unlock_irq(&bdev_get_queue(ctx->bdev)->queue_lock);
+- blkdev_put_no_open(ctx->bdev);
++ if (ctx->blkg) {
++ spin_unlock_irq(&bdev_get_queue(ctx->bdev)->queue_lock);
++ ctx->blkg = NULL;
++ }
++
++ if (ctx->bdev) {
++ blkdev_put_no_open(ctx->bdev);
++ ctx->body = NULL;
++ ctx->bdev = NULL;
++ }
+ }
+-EXPORT_SYMBOL_GPL(blkg_conf_finish);
++EXPORT_SYMBOL_GPL(blkg_conf_exit);
+
+ static void blkg_iostat_set(struct blkg_iostat *dst, struct blkg_iostat *src)
+ {
+diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h
+index 9c5078755e5e1..39b07ef6a3d9a 100644
+--- a/block/blk-cgroup.h
++++ b/block/blk-cgroup.h
+@@ -208,15 +208,17 @@ void blkcg_print_blkgs(struct seq_file *sf, struct blkcg *blkcg,
+ u64 __blkg_prfill_u64(struct seq_file *sf, struct blkg_policy_data *pd, u64 v);
+
+ struct blkg_conf_ctx {
++ char *input;
++ char *body;
+ struct block_device *bdev;
+ struct blkcg_gq *blkg;
+- char *body;
+ };
+
+-struct block_device *blkcg_conf_open_bdev(char **inputp);
++void blkg_conf_init(struct blkg_conf_ctx *ctx, char *input);
++int blkg_conf_open_bdev(struct blkg_conf_ctx *ctx);
+ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+- char *input, struct blkg_conf_ctx *ctx);
+-void blkg_conf_finish(struct blkg_conf_ctx *ctx);
++ struct blkg_conf_ctx *ctx);
++void blkg_conf_exit(struct blkg_conf_ctx *ctx);
+
+ /**
+ * bio_issue_as_root_blkg - see if this bio needs to be issued as root blkg
+diff --git a/block/blk-iocost.c b/block/blk-iocost.c
+index 4442c7a851125..285ced3467abb 100644
+--- a/block/blk-iocost.c
++++ b/block/blk-iocost.c
+@@ -3106,9 +3106,11 @@ static ssize_t ioc_weight_write(struct kernfs_open_file *of, char *buf,
+ return nbytes;
+ }
+
+- ret = blkg_conf_prep(blkcg, &blkcg_policy_iocost, buf, &ctx);
++ blkg_conf_init(&ctx, buf);
++
++ ret = blkg_conf_prep(blkcg, &blkcg_policy_iocost, &ctx);
+ if (ret)
+- return ret;
++ goto err;
+
+ iocg = blkg_to_iocg(ctx.blkg);
+
+@@ -3127,12 +3129,14 @@ static ssize_t ioc_weight_write(struct kernfs_open_file *of, char *buf,
+ weight_updated(iocg, &now);
+ spin_unlock(&iocg->ioc->lock);
+
+- blkg_conf_finish(&ctx);
++ blkg_conf_exit(&ctx);
+ return nbytes;
+
+ einval:
+- blkg_conf_finish(&ctx);
+- return -EINVAL;
++ ret = -EINVAL;
++err:
++ blkg_conf_exit(&ctx);
++ return ret;
+ }
+
+ static u64 ioc_qos_prfill(struct seq_file *sf, struct blkg_policy_data *pd,
+@@ -3189,19 +3193,22 @@ static const match_table_t qos_tokens = {
+ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
+ size_t nbytes, loff_t off)
+ {
+- struct block_device *bdev;
++ struct blkg_conf_ctx ctx;
+ struct gendisk *disk;
+ struct ioc *ioc;
+ u32 qos[NR_QOS_PARAMS];
+ bool enable, user;
+- char *p;
++ char *body, *p;
+ int ret;
+
+- bdev = blkcg_conf_open_bdev(&input);
+- if (IS_ERR(bdev))
+- return PTR_ERR(bdev);
++ blkg_conf_init(&ctx, input);
+
+- disk = bdev->bd_disk;
++ ret = blkg_conf_open_bdev(&ctx);
++ if (ret)
++ goto err;
++
++ body = ctx.body;
++ disk = ctx.bdev->bd_disk;
+ if (!queue_is_mq(disk->queue)) {
+ ret = -EOPNOTSUPP;
+ goto err;
+@@ -3223,7 +3230,7 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
+ enable = ioc->enabled;
+ user = ioc->user_qos_params;
+
+- while ((p = strsep(&input, " \t\n"))) {
++ while ((p = strsep(&body, " \t\n"))) {
+ substring_t args[MAX_OPT_ARGS];
+ char buf[32];
+ int tok;
+@@ -3313,7 +3320,7 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
+ blk_mq_unquiesce_queue(disk->queue);
+ blk_mq_unfreeze_queue(disk->queue);
+
+- blkdev_put_no_open(bdev);
++ blkg_conf_exit(&ctx);
+ return nbytes;
+ einval:
+ spin_unlock_irq(&ioc->lock);
+@@ -3323,7 +3330,7 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
+
+ ret = -EINVAL;
+ err:
+- blkdev_put_no_open(bdev);
++ blkg_conf_exit(&ctx);
+ return ret;
+ }
+
+@@ -3376,19 +3383,22 @@ static const match_table_t i_lcoef_tokens = {
+ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
+ size_t nbytes, loff_t off)
+ {
+- struct block_device *bdev;
++ struct blkg_conf_ctx ctx;
+ struct request_queue *q;
+ struct ioc *ioc;
+ u64 u[NR_I_LCOEFS];
+ bool user;
+- char *p;
++ char *body, *p;
+ int ret;
+
+- bdev = blkcg_conf_open_bdev(&input);
+- if (IS_ERR(bdev))
+- return PTR_ERR(bdev);
++ blkg_conf_init(&ctx, input);
++
++ ret = blkg_conf_open_bdev(&ctx);
++ if (ret)
++ goto err;
+
+- q = bdev_get_queue(bdev);
++ body = ctx.body;
++ q = bdev_get_queue(ctx.bdev);
+ if (!queue_is_mq(q)) {
+ ret = -EOPNOTSUPP;
+ goto err;
+@@ -3396,7 +3406,7 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
+
+ ioc = q_to_ioc(q);
+ if (!ioc) {
+- ret = blk_iocost_init(bdev->bd_disk);
++ ret = blk_iocost_init(ctx.bdev->bd_disk);
+ if (ret)
+ goto err;
+ ioc = q_to_ioc(q);
+@@ -3409,7 +3419,7 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
+ memcpy(u, ioc->params.i_lcoefs, sizeof(u));
+ user = ioc->user_cost_model;
+
+- while ((p = strsep(&input, " \t\n"))) {
++ while ((p = strsep(&body, " \t\n"))) {
+ substring_t args[MAX_OPT_ARGS];
+ char buf[32];
+ int tok;
+@@ -3456,7 +3466,7 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
+ blk_mq_unquiesce_queue(q);
+ blk_mq_unfreeze_queue(q);
+
+- blkdev_put_no_open(bdev);
++ blkg_conf_exit(&ctx);
+ return nbytes;
+
+ einval:
+@@ -3467,7 +3477,7 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
+
+ ret = -EINVAL;
+ err:
+- blkdev_put_no_open(bdev);
++ blkg_conf_exit(&ctx);
+ return ret;
+ }
+
+diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c
+index 0dc910568b314..6707164c37f1e 100644
+--- a/block/blk-iolatency.c
++++ b/block/blk-iolatency.c
+@@ -836,9 +836,11 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf,
+ u64 oldval;
+ int ret;
+
+- ret = blkg_conf_prep(blkcg, &blkcg_policy_iolatency, buf, &ctx);
++ blkg_conf_init(&ctx, buf);
++
++ ret = blkg_conf_prep(blkcg, &blkcg_policy_iolatency, &ctx);
+ if (ret)
+- return ret;
++ goto out;
+
+ iolat = blkg_to_lat(ctx.blkg);
+ p = ctx.body;
+@@ -874,7 +876,7 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf,
+ iolatency_clear_scaling(blkg);
+ ret = 0;
+ out:
+- blkg_conf_finish(&ctx);
++ blkg_conf_exit(&ctx);
+ return ret ?: nbytes;
+ }
+
+diff --git a/block/blk-throttle.c b/block/blk-throttle.c
+index 47e9d8be68f30..9bac95343ba02 100644
+--- a/block/blk-throttle.c
++++ b/block/blk-throttle.c
+@@ -1368,9 +1368,11 @@ static ssize_t tg_set_conf(struct kernfs_open_file *of,
+ int ret;
+ u64 v;
+
+- ret = blkg_conf_prep(blkcg, &blkcg_policy_throtl, buf, &ctx);
++ blkg_conf_init(&ctx, buf);
++
++ ret = blkg_conf_prep(blkcg, &blkcg_policy_throtl, &ctx);
+ if (ret)
+- return ret;
++ goto out_finish;
+
+ ret = -EINVAL;
+ if (sscanf(ctx.body, "%llu", &v) != 1)
+@@ -1389,7 +1391,7 @@ static ssize_t tg_set_conf(struct kernfs_open_file *of,
+ tg_conf_updated(tg, false);
+ ret = 0;
+ out_finish:
+- blkg_conf_finish(&ctx);
++ blkg_conf_exit(&ctx);
+ return ret ?: nbytes;
+ }
+
+@@ -1561,9 +1563,11 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of,
+ int ret;
+ int index = of_cft(of)->private;
+
+- ret = blkg_conf_prep(blkcg, &blkcg_policy_throtl, buf, &ctx);
++ blkg_conf_init(&ctx, buf);
++
++ ret = blkg_conf_prep(blkcg, &blkcg_policy_throtl, &ctx);
+ if (ret)
+- return ret;
++ goto out_finish;
+
+ tg = blkg_to_tg(ctx.blkg);
+ tg_update_carryover(tg);
+@@ -1662,7 +1666,7 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of,
+ tg->td->limit_valid[LIMIT_LOW]);
+ ret = 0;
+ out_finish:
+- blkg_conf_finish(&ctx);
++ blkg_conf_exit(&ctx);
+ return ret ?: nbytes;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 979c25b082e5a44862d5aa8a78031e9f5efe9d84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Jun 2023 10:20:03 +0800
+Subject: block: fix blktrace debugfs entries leakage
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit dd7de3704af9989b780693d51eaea49a665bd9c2 ]
+
+Commit 99d055b4fd4b ("block: remove per-disk debugfs files in
+blk_unregister_queue") moves blk_trace_shutdown() from
+blk_release_queue() to blk_unregister_queue(), this is safe if blktrace
+is created through sysfs, however, there is a regression in corner
+case.
+
+blktrace can still be enabled after del_gendisk() through ioctl if
+the disk is opened before del_gendisk(), and if blktrace is not shutdown
+through ioctl before closing the disk, debugfs entries will be leaked.
+
+Fix this problem by shutdown blktrace in disk_release(), this is safe
+because blk_trace_remove() is reentrant.
+
+Fixes: 99d055b4fd4b ("block: remove per-disk debugfs files in blk_unregister_queue")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20230610022003.2557284-4-yukuai1@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/genhd.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/block/genhd.c b/block/genhd.c
+index 7f874737af682..c5a35e1b462fa 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -25,8 +25,9 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/badblocks.h>
+ #include <linux/part_stat.h>
+-#include "blk-throttle.h"
++#include <linux/blktrace_api.h>
+
++#include "blk-throttle.h"
+ #include "blk.h"
+ #include "blk-mq-sched.h"
+ #include "blk-rq-qos.h"
+@@ -1183,6 +1184,8 @@ static void disk_release(struct device *dev)
+ might_sleep();
+ WARN_ON_ONCE(disk_live(disk));
+
++ blk_trace_remove(disk->queue);
++
+ /*
+ * To undo the all initialization from blk_mq_init_allocated_queue in
+ * case of a probe failure where add_disk is never called we have to
+--
+2.39.2
+
--- /dev/null
+From 2de3d475fd66b13fbbf2764bfbc4965df047d83c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 10:42:21 -0700
+Subject: block: Fix the type of the second bdev_op_is_zoned_write() argument
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 3ddbe2a7e0d4a155a805f69c906c9beed30d4cc4 ]
+
+Change the type of the second argument of bdev_op_is_zoned_write() from
+blk_opf_t into enum req_op because this function expects an operation
+without flags as second argument.
+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Cc: Ming Lei <ming.lei@redhat.com>
+Fixes: 8cafdb5ab94c ("block: adapt blk_mq_plug() to not plug for writes that require a zone lock")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20230517174230.897144-4-bvanassche@acm.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/blkdev.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 941304f17492f..3d620f298aebd 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -1297,7 +1297,7 @@ static inline unsigned int bdev_zone_no(struct block_device *bdev, sector_t sec)
+ }
+
+ static inline bool bdev_op_is_zoned_write(struct block_device *bdev,
+- blk_opf_t op)
++ enum req_op op)
+ {
+ if (!bdev_is_zoned(bdev))
+ return false;
+--
+2.39.2
+
--- /dev/null
+From c2881f89038161eb2aa8189e93d3cd6114f7fde8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Apr 2023 16:40:08 +0800
+Subject: block/rq_qos: protect rq_qos apis with a new lock
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit a13bd91be22318768d55470cbc0b0f4488ef9edf ]
+
+commit 50e34d78815e ("block: disable the elevator int del_gendisk")
+move rq_qos_exit() from disk_release() to del_gendisk(), this will
+introduce some problems:
+
+1) If rq_qos_add() is triggered by enabling iocost/iolatency through
+ cgroupfs, then it can concurrent with del_gendisk(), it's not safe to
+ write 'q->rq_qos' concurrently.
+
+2) Activate cgroup policy that is relied on rq_qos will call
+ rq_qos_add() and blkcg_activate_policy(), and if rq_qos_exit() is
+ called in the middle, null-ptr-dereference will be triggered in
+ blkcg_activate_policy().
+
+3) blkg_conf_open_bdev() can call blkdev_get_no_open() first to find the
+ disk, then if rq_qos_exit() from del_gendisk() is done before
+ rq_qos_add(), then memory will be leaked.
+
+This patch add a new disk level mutex 'rq_qos_mutex':
+
+1) The lock will protect rq_qos_exit() directly.
+
+2) For wbt that doesn't relied on blk-cgroup, rq_qos_add() can only be
+ called from disk initialization for now because wbt can't be
+ destructed until rq_qos_exit(), so it's safe not to protect wbt for
+ now. Hoever, in case that rq_qos dynamically destruction is supported
+ in the furture, this patch also protect rq_qos_add() from wbt_init()
+ directly, this is enough because blk-sysfs already synchronize
+ writers with disk removal.
+
+3) For iocost and iolatency, in order to synchronize disk removal and
+ cgroup configuration, the lock is held after blkdev_get_no_open()
+ from blkg_conf_open_bdev(), and is released in blkg_conf_exit().
+ In order to fix the above memory leak, disk_live() is checked after
+ holding the new lock.
+
+Fixes: 50e34d78815e ("block: disable the elevator int del_gendisk")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Link: https://lore.kernel.org/r/20230414084008.2085155-1-yukuai1@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-cgroup.c | 9 +++++++++
+ block/blk-core.c | 1 +
+ block/blk-rq-qos.c | 20 ++++++--------------
+ block/blk-wbt.c | 2 ++
+ include/linux/blkdev.h | 1 +
+ 5 files changed, 19 insertions(+), 14 deletions(-)
+
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index 0399b6e644b28..ad0cd992a6519 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -723,6 +723,13 @@ int blkg_conf_open_bdev(struct blkg_conf_ctx *ctx)
+ return -ENODEV;
+ }
+
++ mutex_lock(&bdev->bd_queue->rq_qos_mutex);
++ if (!disk_live(bdev->bd_disk)) {
++ blkdev_put_no_open(bdev);
++ mutex_unlock(&bdev->bd_queue->rq_qos_mutex);
++ return -ENODEV;
++ }
++
+ ctx->body = input;
+ ctx->bdev = bdev;
+ return 0;
+@@ -867,6 +874,7 @@ EXPORT_SYMBOL_GPL(blkg_conf_prep);
+ */
+ void blkg_conf_exit(struct blkg_conf_ctx *ctx)
+ __releases(&ctx->bdev->bd_queue->queue_lock)
++ __releases(&ctx->bdev->bd_queue->rq_qos_mutex)
+ {
+ if (ctx->blkg) {
+ spin_unlock_irq(&bdev_get_queue(ctx->bdev)->queue_lock);
+@@ -874,6 +882,7 @@ void blkg_conf_exit(struct blkg_conf_ctx *ctx)
+ }
+
+ if (ctx->bdev) {
++ mutex_unlock(&ctx->bdev->bd_queue->rq_qos_mutex);
+ blkdev_put_no_open(ctx->bdev);
+ ctx->body = NULL;
+ ctx->bdev = NULL;
+diff --git a/block/blk-core.c b/block/blk-core.c
+index 42926e6cb83c8..5675f711643ae 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -426,6 +426,7 @@ struct request_queue *blk_alloc_queue(int node_id)
+ mutex_init(&q->debugfs_mutex);
+ mutex_init(&q->sysfs_lock);
+ mutex_init(&q->sysfs_dir_lock);
++ mutex_init(&q->rq_qos_mutex);
+ spin_lock_init(&q->queue_lock);
+
+ init_waitqueue_head(&q->mq_freeze_wq);
+diff --git a/block/blk-rq-qos.c b/block/blk-rq-qos.c
+index d8cc820a365e3..167be74df4eec 100644
+--- a/block/blk-rq-qos.c
++++ b/block/blk-rq-qos.c
+@@ -288,11 +288,13 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data,
+
+ void rq_qos_exit(struct request_queue *q)
+ {
++ mutex_lock(&q->rq_qos_mutex);
+ while (q->rq_qos) {
+ struct rq_qos *rqos = q->rq_qos;
+ q->rq_qos = rqos->next;
+ rqos->ops->exit(rqos);
+ }
++ mutex_unlock(&q->rq_qos_mutex);
+ }
+
+ int rq_qos_add(struct rq_qos *rqos, struct gendisk *disk, enum rq_qos_id id,
+@@ -300,6 +302,8 @@ int rq_qos_add(struct rq_qos *rqos, struct gendisk *disk, enum rq_qos_id id,
+ {
+ struct request_queue *q = disk->queue;
+
++ lockdep_assert_held(&q->rq_qos_mutex);
++
+ rqos->disk = disk;
+ rqos->id = id;
+ rqos->ops = ops;
+@@ -307,18 +311,13 @@ int rq_qos_add(struct rq_qos *rqos, struct gendisk *disk, enum rq_qos_id id,
+ /*
+ * No IO can be in-flight when adding rqos, so freeze queue, which
+ * is fine since we only support rq_qos for blk-mq queue.
+- *
+- * Reuse ->queue_lock for protecting against other concurrent
+- * rq_qos adding/deleting
+ */
+ blk_mq_freeze_queue(q);
+
+- spin_lock_irq(&q->queue_lock);
+ if (rq_qos_id(q, rqos->id))
+ goto ebusy;
+ rqos->next = q->rq_qos;
+ q->rq_qos = rqos;
+- spin_unlock_irq(&q->queue_lock);
+
+ blk_mq_unfreeze_queue(q);
+
+@@ -330,7 +329,6 @@ int rq_qos_add(struct rq_qos *rqos, struct gendisk *disk, enum rq_qos_id id,
+
+ return 0;
+ ebusy:
+- spin_unlock_irq(&q->queue_lock);
+ blk_mq_unfreeze_queue(q);
+ return -EBUSY;
+ }
+@@ -340,21 +338,15 @@ void rq_qos_del(struct rq_qos *rqos)
+ struct request_queue *q = rqos->disk->queue;
+ struct rq_qos **cur;
+
+- /*
+- * See comment in rq_qos_add() about freezing queue & using
+- * ->queue_lock.
+- */
+- blk_mq_freeze_queue(q);
++ lockdep_assert_held(&q->rq_qos_mutex);
+
+- spin_lock_irq(&q->queue_lock);
++ blk_mq_freeze_queue(q);
+ for (cur = &q->rq_qos; *cur; cur = &(*cur)->next) {
+ if (*cur == rqos) {
+ *cur = rqos->next;
+ break;
+ }
+ }
+- spin_unlock_irq(&q->queue_lock);
+-
+ blk_mq_unfreeze_queue(q);
+
+ mutex_lock(&q->debugfs_mutex);
+diff --git a/block/blk-wbt.c b/block/blk-wbt.c
+index 9ec2a2f1eda38..7a87506ff8e1c 100644
+--- a/block/blk-wbt.c
++++ b/block/blk-wbt.c
+@@ -944,7 +944,9 @@ int wbt_init(struct gendisk *disk)
+ /*
+ * Assign rwb and add the stats callback.
+ */
++ mutex_lock(&q->rq_qos_mutex);
+ ret = rq_qos_add(&rwb->rqos, disk, RQ_QOS_WBT, &wbt_rqos_ops);
++ mutex_unlock(&q->rq_qos_mutex);
+ if (ret)
+ goto err_free;
+
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 3d620f298aebd..ce4e8063b32b2 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -401,6 +401,7 @@ struct request_queue {
+
+ struct blk_queue_stats *stats;
+ struct rq_qos *rq_qos;
++ struct mutex rq_qos_mutex;
+
+ const struct blk_mq_ops *mq_ops;
+
+--
+2.39.2
+
--- /dev/null
+From 705650d0c10e1f530732eba2c059ab9a8edaac37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 15:23:04 +0000
+Subject: bonding: do not assume skb mac_header is set
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 6a940abdef3162e5723f1495b8a49859d1708f79 ]
+
+Drivers must not assume in their ndo_start_xmit() that
+skbs have their mac_header set. skb->data is all what is needed.
+
+bonding seems to be one of the last offender as caught by syzbot:
+
+WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 skb_mac_offset include/linux/skbuff.h:2913 [inline]
+WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 bond_xmit_hash drivers/net/bonding/bond_main.c:4170 [inline]
+WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 bond_xmit_3ad_xor_slave_get drivers/net/bonding/bond_main.c:5149 [inline]
+WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 bond_3ad_xor_xmit drivers/net/bonding/bond_main.c:5186 [inline]
+WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 __bond_start_xmit drivers/net/bonding/bond_main.c:5442 [inline]
+WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 bond_start_xmit+0x14ab/0x19d0 drivers/net/bonding/bond_main.c:5470
+Modules linked in:
+CPU: 1 PID: 12155 Comm: syz-executor.3 Not tainted 6.1.30-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/25/2023
+RIP: 0010:skb_mac_header include/linux/skbuff.h:2907 [inline]
+RIP: 0010:skb_mac_offset include/linux/skbuff.h:2913 [inline]
+RIP: 0010:bond_xmit_hash drivers/net/bonding/bond_main.c:4170 [inline]
+RIP: 0010:bond_xmit_3ad_xor_slave_get drivers/net/bonding/bond_main.c:5149 [inline]
+RIP: 0010:bond_3ad_xor_xmit drivers/net/bonding/bond_main.c:5186 [inline]
+RIP: 0010:__bond_start_xmit drivers/net/bonding/bond_main.c:5442 [inline]
+RIP: 0010:bond_start_xmit+0x14ab/0x19d0 drivers/net/bonding/bond_main.c:5470
+Code: 8b 7c 24 30 e8 76 dd 1a 01 48 85 c0 74 0d 48 89 c3 e8 29 67 2e fe e9 15 ef ff ff e8 1f 67 2e fe e9 10 ef ff ff e8 15 67 2e fe <0f> 0b e9 45 f8 ff ff e8 09 67 2e fe e9 dc fa ff ff e8 ff 66 2e fe
+RSP: 0018:ffffc90002fff6e0 EFLAGS: 00010283
+RAX: ffffffff835874db RBX: 000000000000ffff RCX: 0000000000040000
+RDX: ffffc90004dcf000 RSI: 00000000000000b5 RDI: 00000000000000b6
+RBP: ffffc90002fff8b8 R08: ffffffff83586d16 R09: ffffffff83586584
+R10: 0000000000000007 R11: ffff8881599fc780 R12: ffff88811b6a7b7e
+R13: 1ffff110236d4f6f R14: ffff88811b6a7ac0 R15: 1ffff110236d4f76
+FS: 00007f2e9eb47700(0000) GS:ffff8881f6b00000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000001b2e421000 CR3: 000000010e6d4000 CR4: 00000000003526e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+<TASK>
+[<ffffffff8471a49f>] netdev_start_xmit include/linux/netdevice.h:4925 [inline]
+[<ffffffff8471a49f>] __dev_direct_xmit+0x4ef/0x850 net/core/dev.c:4380
+[<ffffffff851d845b>] dev_direct_xmit include/linux/netdevice.h:3043 [inline]
+[<ffffffff851d845b>] packet_direct_xmit+0x18b/0x300 net/packet/af_packet.c:284
+[<ffffffff851c7472>] packet_snd net/packet/af_packet.c:3112 [inline]
+[<ffffffff851c7472>] packet_sendmsg+0x4a22/0x64d0 net/packet/af_packet.c:3143
+[<ffffffff8467a4b2>] sock_sendmsg_nosec net/socket.c:716 [inline]
+[<ffffffff8467a4b2>] sock_sendmsg net/socket.c:736 [inline]
+[<ffffffff8467a4b2>] __sys_sendto+0x472/0x5f0 net/socket.c:2139
+[<ffffffff8467a715>] __do_sys_sendto net/socket.c:2151 [inline]
+[<ffffffff8467a715>] __se_sys_sendto net/socket.c:2147 [inline]
+[<ffffffff8467a715>] __x64_sys_sendto+0xe5/0x100 net/socket.c:2147
+[<ffffffff8553071f>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+[<ffffffff8553071f>] do_syscall_64+0x2f/0x50 arch/x86/entry/common.c:80
+[<ffffffff85600087>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Fixes: 7b8fc0103bb5 ("bonding: add a vlan+srcmac tx hashing option")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Jarod Wilson <jarod@redhat.com>
+Cc: Moshe Tal <moshet@nvidia.com>
+Cc: Jussi Maki <joamaki@gmail.com>
+Cc: Jay Vosburgh <j.vosburgh@gmail.com>
+Cc: Andy Gospodarek <andy@greyhouse.net>
+Cc: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://lore.kernel.org/r/20230622152304.2137482-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 806d33d9f7124..172939e275a3b 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -4171,7 +4171,7 @@ u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb)
+ return skb->hash;
+
+ return __bond_xmit_hash(bond, skb, skb->data, skb->protocol,
+- skb_mac_offset(skb), skb_network_offset(skb),
++ 0, skb_network_offset(skb),
+ skb_headlen(skb));
+ }
+
+--
+2.39.2
+
--- /dev/null
+From a49c7e79ff105798cd5352b66dfe3814d2dc2b01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 13:42:09 +0300
+Subject: bpf: Call __bpf_sk_lookup()/__bpf_skc_lookup() directly via TC
+ hookpoint
+
+From: Gilad Sever <gilad9366@gmail.com>
+
+[ Upstream commit 97fbfeb86917bdbe9c41d5143e335a929147f405 ]
+
+skb->dev always exists in the tc flow. There is no need to use
+bpf_skc_lookup(), bpf_sk_lookup() from this code path.
+
+This change facilitates fixing the tc flow to be VRF aware.
+
+Signed-off-by: Gilad Sever <gilad9366@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
+Reviewed-by: Eyal Birger <eyal.birger@gmail.com>
+Acked-by: Stanislav Fomichev <sdf@google.com>
+Link: https://lore.kernel.org/bpf/20230621104211.301902-3-gilad9366@gmail.com
+Stable-dep-of: 9a5cb79762e0 ("bpf: Fix bpf socket lookup from tc/xdp to respect socket VRF bindings")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 5910956f4e0db..f43f86fc12356 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -6704,8 +6704,12 @@ static const struct bpf_func_proto bpf_sk_lookup_udp_proto = {
+ BPF_CALL_5(bpf_tc_skc_lookup_tcp, struct sk_buff *, skb,
+ struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
+ {
+- return (unsigned long)bpf_skc_lookup(skb, tuple, len, IPPROTO_TCP,
+- netns_id, flags);
++ struct net *caller_net = dev_net(skb->dev);
++ int ifindex = skb->dev->ifindex;
++
++ return (unsigned long)__bpf_skc_lookup(skb, tuple, len, caller_net,
++ ifindex, IPPROTO_TCP, netns_id,
++ flags);
+ }
+
+ static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = {
+@@ -6723,8 +6727,12 @@ static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = {
+ BPF_CALL_5(bpf_tc_sk_lookup_tcp, struct sk_buff *, skb,
+ struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
+ {
+- return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_TCP,
+- netns_id, flags);
++ struct net *caller_net = dev_net(skb->dev);
++ int ifindex = skb->dev->ifindex;
++
++ return (unsigned long)__bpf_sk_lookup(skb, tuple, len, caller_net,
++ ifindex, IPPROTO_TCP, netns_id,
++ flags);
+ }
+
+ static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = {
+@@ -6742,8 +6750,12 @@ static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = {
+ BPF_CALL_5(bpf_tc_sk_lookup_udp, struct sk_buff *, skb,
+ struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
+ {
+- return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_UDP,
+- netns_id, flags);
++ struct net *caller_net = dev_net(skb->dev);
++ int ifindex = skb->dev->ifindex;
++
++ return (unsigned long)__bpf_sk_lookup(skb, tuple, len, caller_net,
++ ifindex, IPPROTO_UDP, netns_id,
++ flags);
+ }
+
+ static const struct bpf_func_proto bpf_tc_sk_lookup_udp_proto = {
+--
+2.39.2
+
--- /dev/null
+From 57f6d816f92a0c8be23a4bececcabab802bbe333 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 May 2023 10:04:53 -0700
+Subject: bpf: Don't EFAULT for {g,s}setsockopt with wrong optlen
+
+From: Stanislav Fomichev <sdf@google.com>
+
+[ Upstream commit 29ebbba7d46136cba324264e513a1e964ca16c0a ]
+
+With the way the hooks implemented right now, we have a special
+condition: optval larger than PAGE_SIZE will expose only first 4k into
+BPF; any modifications to the optval are ignored. If the BPF program
+doesn't handle this condition by resetting optlen to 0,
+the userspace will get EFAULT.
+
+The intention of the EFAULT was to make it apparent to the
+developers that the program is doing something wrong.
+However, this inadvertently might affect production workloads
+with the BPF programs that are not too careful (i.e., returning EFAULT
+for perfectly valid setsockopt/getsockopt calls).
+
+Let's try to minimize the chance of BPF program screwing up userspace
+by ignoring the output of those BPF programs (instead of returning
+EFAULT to the userspace). pr_info_once those cases to
+the dmesg to help with figuring out what's going wrong.
+
+Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks")
+Suggested-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Stanislav Fomichev <sdf@google.com>
+Link: https://lore.kernel.org/r/20230511170456.1759459-2-sdf@google.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/cgroup.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
+index b86b907e566ca..bb70f400c25eb 100644
+--- a/kernel/bpf/cgroup.c
++++ b/kernel/bpf/cgroup.c
+@@ -1826,6 +1826,12 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level,
+ ret = 1;
+ } else if (ctx.optlen > max_optlen || ctx.optlen < -1) {
+ /* optlen is out of bounds */
++ if (*optlen > PAGE_SIZE && ctx.optlen >= 0) {
++ pr_info_once("bpf setsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n",
++ ctx.optlen, max_optlen);
++ ret = 0;
++ goto out;
++ }
+ ret = -EFAULT;
+ } else {
+ /* optlen within bounds, run kernel handler */
+@@ -1881,8 +1887,10 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
+ .optname = optname,
+ .current_task = current,
+ };
++ int orig_optlen;
+ int ret;
+
++ orig_optlen = max_optlen;
+ ctx.optlen = max_optlen;
+ max_optlen = sockopt_alloc_buf(&ctx, max_optlen, &buf);
+ if (max_optlen < 0)
+@@ -1905,6 +1913,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
+ ret = -EFAULT;
+ goto out;
+ }
++ orig_optlen = ctx.optlen;
+
+ if (copy_from_user(ctx.optval, optval,
+ min(ctx.optlen, max_optlen)) != 0) {
+@@ -1922,6 +1931,12 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
+ goto out;
+
+ if (optval && (ctx.optlen > max_optlen || ctx.optlen < 0)) {
++ if (orig_optlen > PAGE_SIZE && ctx.optlen >= 0) {
++ pr_info_once("bpf getsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n",
++ ctx.optlen, max_optlen);
++ ret = retval;
++ goto out;
++ }
+ ret = -EFAULT;
+ goto out;
+ }
+--
+2.39.2
+
--- /dev/null
+From 58f9499074c280f66c439cc95dd2dd47fc72b0cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 13:42:08 +0300
+Subject: bpf: Factor out socket lookup functions for the TC hookpoint.
+
+From: Gilad Sever <gilad9366@gmail.com>
+
+[ Upstream commit 6e98730bc0b44acaf86eccc75f823128aa9c9e79 ]
+
+Change BPF helper socket lookup functions to use TC specific variants:
+bpf_tc_sk_lookup_tcp() / bpf_tc_sk_lookup_udp() / bpf_tc_skc_lookup_tcp()
+instead of sharing implementation with the cg / sk_skb hooking points.
+This allows introducing a separate logic for the TC flow.
+
+The tc functions are identical to the original code.
+
+Signed-off-by: Gilad Sever <gilad9366@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
+Reviewed-by: Eyal Birger <eyal.birger@gmail.com>
+Acked-by: Stanislav Fomichev <sdf@google.com>
+Link: https://lore.kernel.org/bpf/20230621104211.301902-2-gilad9366@gmail.com
+Stable-dep-of: 9a5cb79762e0 ("bpf: Fix bpf socket lookup from tc/xdp to respect socket VRF bindings")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 63 ++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 60 insertions(+), 3 deletions(-)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 1d6f165923bff..5910956f4e0db 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -6701,6 +6701,63 @@ static const struct bpf_func_proto bpf_sk_lookup_udp_proto = {
+ .arg5_type = ARG_ANYTHING,
+ };
+
++BPF_CALL_5(bpf_tc_skc_lookup_tcp, struct sk_buff *, skb,
++ struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
++{
++ return (unsigned long)bpf_skc_lookup(skb, tuple, len, IPPROTO_TCP,
++ netns_id, flags);
++}
++
++static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = {
++ .func = bpf_tc_skc_lookup_tcp,
++ .gpl_only = false,
++ .pkt_access = true,
++ .ret_type = RET_PTR_TO_SOCK_COMMON_OR_NULL,
++ .arg1_type = ARG_PTR_TO_CTX,
++ .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY,
++ .arg3_type = ARG_CONST_SIZE,
++ .arg4_type = ARG_ANYTHING,
++ .arg5_type = ARG_ANYTHING,
++};
++
++BPF_CALL_5(bpf_tc_sk_lookup_tcp, struct sk_buff *, skb,
++ struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
++{
++ return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_TCP,
++ netns_id, flags);
++}
++
++static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = {
++ .func = bpf_tc_sk_lookup_tcp,
++ .gpl_only = false,
++ .pkt_access = true,
++ .ret_type = RET_PTR_TO_SOCKET_OR_NULL,
++ .arg1_type = ARG_PTR_TO_CTX,
++ .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY,
++ .arg3_type = ARG_CONST_SIZE,
++ .arg4_type = ARG_ANYTHING,
++ .arg5_type = ARG_ANYTHING,
++};
++
++BPF_CALL_5(bpf_tc_sk_lookup_udp, struct sk_buff *, skb,
++ struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
++{
++ return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_UDP,
++ netns_id, flags);
++}
++
++static const struct bpf_func_proto bpf_tc_sk_lookup_udp_proto = {
++ .func = bpf_tc_sk_lookup_udp,
++ .gpl_only = false,
++ .pkt_access = true,
++ .ret_type = RET_PTR_TO_SOCKET_OR_NULL,
++ .arg1_type = ARG_PTR_TO_CTX,
++ .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY,
++ .arg3_type = ARG_CONST_SIZE,
++ .arg4_type = ARG_ANYTHING,
++ .arg5_type = ARG_ANYTHING,
++};
++
+ BPF_CALL_1(bpf_sk_release, struct sock *, sk)
+ {
+ if (sk && sk_is_refcounted(sk))
+@@ -7954,9 +8011,9 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
+ #endif
+ #ifdef CONFIG_INET
+ case BPF_FUNC_sk_lookup_tcp:
+- return &bpf_sk_lookup_tcp_proto;
++ return &bpf_tc_sk_lookup_tcp_proto;
+ case BPF_FUNC_sk_lookup_udp:
+- return &bpf_sk_lookup_udp_proto;
++ return &bpf_tc_sk_lookup_udp_proto;
+ case BPF_FUNC_sk_release:
+ return &bpf_sk_release_proto;
+ case BPF_FUNC_tcp_sock:
+@@ -7964,7 +8021,7 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
+ case BPF_FUNC_get_listener_sock:
+ return &bpf_get_listener_sock_proto;
+ case BPF_FUNC_skc_lookup_tcp:
+- return &bpf_skc_lookup_tcp_proto;
++ return &bpf_tc_skc_lookup_tcp_proto;
+ case BPF_FUNC_tcp_check_syncookie:
+ return &bpf_tcp_check_syncookie_proto;
+ case BPF_FUNC_skb_ecn_set_ce:
+--
+2.39.2
+
--- /dev/null
+From e14594d2c01cce19a9574720b85555acd2adc710 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 13:42:10 +0300
+Subject: bpf: Fix bpf socket lookup from tc/xdp to respect socket VRF bindings
+
+From: Gilad Sever <gilad9366@gmail.com>
+
+[ Upstream commit 9a5cb79762e0eda17ca15c2a6eaca4622383c21c ]
+
+When calling bpf_sk_lookup_tcp(), bpf_sk_lookup_udp() or
+bpf_skc_lookup_tcp() from tc/xdp ingress, VRF socket bindings aren't
+respoected, i.e. unbound sockets are returned, and bound sockets aren't
+found.
+
+VRF binding is determined by the sdif argument to sk_lookup(), however
+when called from tc the IP SKB control block isn't initialized and thus
+inet{,6}_sdif() always returns 0.
+
+Fix by calculating sdif for the tc/xdp flows by observing the device's
+l3 enslaved state.
+
+The cg/sk_skb hooking points which are expected to support
+inet{,6}_sdif() pass sdif=-1 which makes __bpf_skc_lookup() use the
+existing logic.
+
+Fixes: 6acc9b432e67 ("bpf: Add helper to retrieve socket in BPF")
+Signed-off-by: Gilad Sever <gilad9366@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
+Reviewed-by: Eyal Birger <eyal.birger@gmail.com>
+Acked-by: Stanislav Fomichev <sdf@google.com>
+Cc: David Ahern <dsahern@kernel.org>
+Link: https://lore.kernel.org/bpf/20230621104211.301902-4-gilad9366@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netdevice.h | 9 +++++
+ net/core/filter.c | 69 ++++++++++++++++++++++-----------------
+ 2 files changed, 48 insertions(+), 30 deletions(-)
+
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 7ed63f5bbe056..02ac3a058c09f 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -5063,6 +5063,15 @@ static inline bool netif_is_l3_slave(const struct net_device *dev)
+ return dev->priv_flags & IFF_L3MDEV_SLAVE;
+ }
+
++static inline int dev_sdif(const struct net_device *dev)
++{
++#ifdef CONFIG_NET_L3_MASTER_DEV
++ if (netif_is_l3_slave(dev))
++ return dev->ifindex;
++#endif
++ return 0;
++}
++
+ static inline bool netif_is_bridge_master(const struct net_device *dev)
+ {
+ return dev->priv_flags & IFF_EBRIDGE;
+diff --git a/net/core/filter.c b/net/core/filter.c
+index f43f86fc12356..ebbab8c24beaf 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -6529,12 +6529,11 @@ static struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple,
+ static struct sock *
+ __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
+ struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id,
+- u64 flags)
++ u64 flags, int sdif)
+ {
+ struct sock *sk = NULL;
+ struct net *net;
+ u8 family;
+- int sdif;
+
+ if (len == sizeof(tuple->ipv4))
+ family = AF_INET;
+@@ -6546,10 +6545,12 @@ __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
+ if (unlikely(flags || !((s32)netns_id < 0 || netns_id <= S32_MAX)))
+ goto out;
+
+- if (family == AF_INET)
+- sdif = inet_sdif(skb);
+- else
+- sdif = inet6_sdif(skb);
++ if (sdif < 0) {
++ if (family == AF_INET)
++ sdif = inet_sdif(skb);
++ else
++ sdif = inet6_sdif(skb);
++ }
+
+ if ((s32)netns_id < 0) {
+ net = caller_net;
+@@ -6569,10 +6570,11 @@ __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
+ static struct sock *
+ __bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
+ struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id,
+- u64 flags)
++ u64 flags, int sdif)
+ {
+ struct sock *sk = __bpf_skc_lookup(skb, tuple, len, caller_net,
+- ifindex, proto, netns_id, flags);
++ ifindex, proto, netns_id, flags,
++ sdif);
+
+ if (sk) {
+ struct sock *sk2 = sk_to_full_sk(sk);
+@@ -6612,7 +6614,7 @@ bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
+ }
+
+ return __bpf_skc_lookup(skb, tuple, len, caller_net, ifindex, proto,
+- netns_id, flags);
++ netns_id, flags, -1);
+ }
+
+ static struct sock *
+@@ -6704,12 +6706,13 @@ static const struct bpf_func_proto bpf_sk_lookup_udp_proto = {
+ BPF_CALL_5(bpf_tc_skc_lookup_tcp, struct sk_buff *, skb,
+ struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
+ {
+- struct net *caller_net = dev_net(skb->dev);
+- int ifindex = skb->dev->ifindex;
++ struct net_device *dev = skb->dev;
++ int ifindex = dev->ifindex, sdif = dev_sdif(dev);
++ struct net *caller_net = dev_net(dev);
+
+ return (unsigned long)__bpf_skc_lookup(skb, tuple, len, caller_net,
+ ifindex, IPPROTO_TCP, netns_id,
+- flags);
++ flags, sdif);
+ }
+
+ static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = {
+@@ -6727,12 +6730,13 @@ static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = {
+ BPF_CALL_5(bpf_tc_sk_lookup_tcp, struct sk_buff *, skb,
+ struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
+ {
+- struct net *caller_net = dev_net(skb->dev);
+- int ifindex = skb->dev->ifindex;
++ struct net_device *dev = skb->dev;
++ int ifindex = dev->ifindex, sdif = dev_sdif(dev);
++ struct net *caller_net = dev_net(dev);
+
+ return (unsigned long)__bpf_sk_lookup(skb, tuple, len, caller_net,
+ ifindex, IPPROTO_TCP, netns_id,
+- flags);
++ flags, sdif);
+ }
+
+ static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = {
+@@ -6750,12 +6754,13 @@ static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = {
+ BPF_CALL_5(bpf_tc_sk_lookup_udp, struct sk_buff *, skb,
+ struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
+ {
+- struct net *caller_net = dev_net(skb->dev);
+- int ifindex = skb->dev->ifindex;
++ struct net_device *dev = skb->dev;
++ int ifindex = dev->ifindex, sdif = dev_sdif(dev);
++ struct net *caller_net = dev_net(dev);
+
+ return (unsigned long)__bpf_sk_lookup(skb, tuple, len, caller_net,
+ ifindex, IPPROTO_UDP, netns_id,
+- flags);
++ flags, sdif);
+ }
+
+ static const struct bpf_func_proto bpf_tc_sk_lookup_udp_proto = {
+@@ -6787,12 +6792,13 @@ static const struct bpf_func_proto bpf_sk_release_proto = {
+ BPF_CALL_5(bpf_xdp_sk_lookup_udp, struct xdp_buff *, ctx,
+ struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
+ {
+- struct net *caller_net = dev_net(ctx->rxq->dev);
+- int ifindex = ctx->rxq->dev->ifindex;
++ struct net_device *dev = ctx->rxq->dev;
++ int ifindex = dev->ifindex, sdif = dev_sdif(dev);
++ struct net *caller_net = dev_net(dev);
+
+ return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, caller_net,
+ ifindex, IPPROTO_UDP, netns_id,
+- flags);
++ flags, sdif);
+ }
+
+ static const struct bpf_func_proto bpf_xdp_sk_lookup_udp_proto = {
+@@ -6810,12 +6816,13 @@ static const struct bpf_func_proto bpf_xdp_sk_lookup_udp_proto = {
+ BPF_CALL_5(bpf_xdp_skc_lookup_tcp, struct xdp_buff *, ctx,
+ struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
+ {
+- struct net *caller_net = dev_net(ctx->rxq->dev);
+- int ifindex = ctx->rxq->dev->ifindex;
++ struct net_device *dev = ctx->rxq->dev;
++ int ifindex = dev->ifindex, sdif = dev_sdif(dev);
++ struct net *caller_net = dev_net(dev);
+
+ return (unsigned long)__bpf_skc_lookup(NULL, tuple, len, caller_net,
+ ifindex, IPPROTO_TCP, netns_id,
+- flags);
++ flags, sdif);
+ }
+
+ static const struct bpf_func_proto bpf_xdp_skc_lookup_tcp_proto = {
+@@ -6833,12 +6840,13 @@ static const struct bpf_func_proto bpf_xdp_skc_lookup_tcp_proto = {
+ BPF_CALL_5(bpf_xdp_sk_lookup_tcp, struct xdp_buff *, ctx,
+ struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
+ {
+- struct net *caller_net = dev_net(ctx->rxq->dev);
+- int ifindex = ctx->rxq->dev->ifindex;
++ struct net_device *dev = ctx->rxq->dev;
++ int ifindex = dev->ifindex, sdif = dev_sdif(dev);
++ struct net *caller_net = dev_net(dev);
+
+ return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, caller_net,
+ ifindex, IPPROTO_TCP, netns_id,
+- flags);
++ flags, sdif);
+ }
+
+ static const struct bpf_func_proto bpf_xdp_sk_lookup_tcp_proto = {
+@@ -6858,7 +6866,8 @@ BPF_CALL_5(bpf_sock_addr_skc_lookup_tcp, struct bpf_sock_addr_kern *, ctx,
+ {
+ return (unsigned long)__bpf_skc_lookup(NULL, tuple, len,
+ sock_net(ctx->sk), 0,
+- IPPROTO_TCP, netns_id, flags);
++ IPPROTO_TCP, netns_id, flags,
++ -1);
+ }
+
+ static const struct bpf_func_proto bpf_sock_addr_skc_lookup_tcp_proto = {
+@@ -6877,7 +6886,7 @@ BPF_CALL_5(bpf_sock_addr_sk_lookup_tcp, struct bpf_sock_addr_kern *, ctx,
+ {
+ return (unsigned long)__bpf_sk_lookup(NULL, tuple, len,
+ sock_net(ctx->sk), 0, IPPROTO_TCP,
+- netns_id, flags);
++ netns_id, flags, -1);
+ }
+
+ static const struct bpf_func_proto bpf_sock_addr_sk_lookup_tcp_proto = {
+@@ -6896,7 +6905,7 @@ BPF_CALL_5(bpf_sock_addr_sk_lookup_udp, struct bpf_sock_addr_kern *, ctx,
+ {
+ return (unsigned long)__bpf_sk_lookup(NULL, tuple, len,
+ sock_net(ctx->sk), 0, IPPROTO_UDP,
+- netns_id, flags);
++ netns_id, flags, -1);
+ }
+
+ static const struct bpf_func_proto bpf_sock_addr_sk_lookup_udp_proto = {
+--
+2.39.2
+
--- /dev/null
+From 4cd2d3eefd705329047c8c8bf856cfba9de64b49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 13:08:47 +0000
+Subject: bpf: Fix memleak due to fentry attach failure
+
+From: Yafang Shao <laoar.shao@gmail.com>
+
+[ Upstream commit 108598c39eefbedc9882273ac0df96127a629220 ]
+
+If it fails to attach fentry, the allocated bpf trampoline image will be
+left in the system. That can be verified by checking /proc/kallsyms.
+
+This meamleak can be verified by a simple bpf program as follows:
+
+ SEC("fentry/trap_init")
+ int fentry_run()
+ {
+ return 0;
+ }
+
+It will fail to attach trap_init because this function is freed after
+kernel init, and then we can find the trampoline image is left in the
+system by checking /proc/kallsyms.
+
+ $ tail /proc/kallsyms
+ ffffffffc0613000 t bpf_trampoline_6442453466_1 [bpf]
+ ffffffffc06c3000 t bpf_trampoline_6442453466_1 [bpf]
+
+ $ bpftool btf dump file /sys/kernel/btf/vmlinux | grep "FUNC 'trap_init'"
+ [2522] FUNC 'trap_init' type_id=119 linkage=static
+
+ $ echo $((6442453466 & 0x7fffffff))
+ 2522
+
+Note that there are two left bpf trampoline images, that is because the
+libbpf will fallback to raw tracepoint if -EINVAL is returned.
+
+Fixes: e21aa341785c ("bpf: Fix fexit trampoline.")
+Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Song Liu <song@kernel.org>
+Cc: Jiri Olsa <olsajiri@gmail.com>
+Link: https://lore.kernel.org/bpf/20230515130849.57502-2-laoar.shao@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/trampoline.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
+index 213d9b3cb06ad..fecb8d2d885a3 100644
+--- a/kernel/bpf/trampoline.c
++++ b/kernel/bpf/trampoline.c
+@@ -279,11 +279,8 @@ bpf_trampoline_get_progs(const struct bpf_trampoline *tr, int *total, bool *ip_a
+ return tlinks;
+ }
+
+-static void __bpf_tramp_image_put_deferred(struct work_struct *work)
++static void bpf_tramp_image_free(struct bpf_tramp_image *im)
+ {
+- struct bpf_tramp_image *im;
+-
+- im = container_of(work, struct bpf_tramp_image, work);
+ bpf_image_ksym_del(&im->ksym);
+ bpf_jit_free_exec(im->image);
+ bpf_jit_uncharge_modmem(PAGE_SIZE);
+@@ -291,6 +288,14 @@ static void __bpf_tramp_image_put_deferred(struct work_struct *work)
+ kfree_rcu(im, rcu);
+ }
+
++static void __bpf_tramp_image_put_deferred(struct work_struct *work)
++{
++ struct bpf_tramp_image *im;
++
++ im = container_of(work, struct bpf_tramp_image, work);
++ bpf_tramp_image_free(im);
++}
++
+ /* callback, fexit step 3 or fentry step 2 */
+ static void __bpf_tramp_image_put_rcu(struct rcu_head *rcu)
+ {
+@@ -465,7 +470,7 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
+ &tr->func.model, tr->flags, tlinks,
+ tr->func.addr);
+ if (err < 0)
+- goto out;
++ goto out_free;
+
+ set_memory_rox((long)im->image, 1);
+
+@@ -494,7 +499,7 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
+ }
+ #endif
+ if (err)
+- goto out;
++ goto out_free;
+
+ if (tr->cur_image)
+ bpf_tramp_image_put(tr->cur_image);
+@@ -505,6 +510,10 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
+ tr->flags = orig_flags;
+ kfree(tlinks);
+ return err;
++
++out_free:
++ bpf_tramp_image_free(im);
++ goto out;
+ }
+
+ static enum bpf_tramp_prog_type bpf_attach_type_to_tramp(struct bpf_prog *prog)
+--
+2.39.2
+
--- /dev/null
+From 0be71b0d57b67ed92fa7dd36ee318500f63a5af3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 13:08:48 +0000
+Subject: bpf: Remove bpf trampoline selector
+
+From: Yafang Shao <laoar.shao@gmail.com>
+
+[ Upstream commit 47e79cbeea4b3891ad476047f4c68543eb51c8e0 ]
+
+After commit e21aa341785c ("bpf: Fix fexit trampoline."), the selector is only
+used to indicate how many times the bpf trampoline image are updated and been
+displayed in the trampoline ksym name. After the trampoline is freed, the
+selector will start from 0 again. So the selector is a useless value to the
+user. We can remove it.
+
+If the user want to check whether the bpf trampoline image has been updated
+or not, the user can compare the address. Each time the trampoline image is
+updated, the address will change consequently. Jiri also pointed out another
+issue that perf is still using the old name "bpf_trampoline_%lu", so this
+change can fix the issue in perf.
+
+Fixes: e21aa341785c ("bpf: Fix fexit trampoline.")
+Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Song Liu <song@kernel.org>
+Cc: Jiri Olsa <olsajiri@gmail.com>
+Link: https://lore.kernel.org/bpf/ZFvOOlrmHiY9AgXE@krava
+Link: https://lore.kernel.org/bpf/20230515130849.57502-3-laoar.shao@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bpf.h | 1 -
+ kernel/bpf/trampoline.c | 11 ++++-------
+ 2 files changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 5bd6ac04773aa..18397e54bac18 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -1082,7 +1082,6 @@ struct bpf_trampoline {
+ int progs_cnt[BPF_TRAMP_MAX];
+ /* Executable image of trampoline */
+ struct bpf_tramp_image *cur_image;
+- u64 selector;
+ struct module *mod;
+ };
+
+diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
+index d0ed7d6f5eec5..213d9b3cb06ad 100644
+--- a/kernel/bpf/trampoline.c
++++ b/kernel/bpf/trampoline.c
+@@ -372,7 +372,7 @@ static void bpf_tramp_image_put(struct bpf_tramp_image *im)
+ call_rcu_tasks_trace(&im->rcu, __bpf_tramp_image_put_rcu_tasks);
+ }
+
+-static struct bpf_tramp_image *bpf_tramp_image_alloc(u64 key, u32 idx)
++static struct bpf_tramp_image *bpf_tramp_image_alloc(u64 key)
+ {
+ struct bpf_tramp_image *im;
+ struct bpf_ksym *ksym;
+@@ -399,7 +399,7 @@ static struct bpf_tramp_image *bpf_tramp_image_alloc(u64 key, u32 idx)
+
+ ksym = &im->ksym;
+ INIT_LIST_HEAD_RCU(&ksym->lnode);
+- snprintf(ksym->name, KSYM_NAME_LEN, "bpf_trampoline_%llu_%u", key, idx);
++ snprintf(ksym->name, KSYM_NAME_LEN, "bpf_trampoline_%llu", key);
+ bpf_image_ksym_add(image, ksym);
+ return im;
+
+@@ -429,11 +429,10 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
+ err = unregister_fentry(tr, tr->cur_image->image);
+ bpf_tramp_image_put(tr->cur_image);
+ tr->cur_image = NULL;
+- tr->selector = 0;
+ goto out;
+ }
+
+- im = bpf_tramp_image_alloc(tr->key, tr->selector);
++ im = bpf_tramp_image_alloc(tr->key);
+ if (IS_ERR(im)) {
+ err = PTR_ERR(im);
+ goto out;
+@@ -470,8 +469,7 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
+
+ set_memory_rox((long)im->image, 1);
+
+- WARN_ON(tr->cur_image && tr->selector == 0);
+- WARN_ON(!tr->cur_image && tr->selector);
++ WARN_ON(tr->cur_image && total == 0);
+ if (tr->cur_image)
+ /* progs already running at this address */
+ err = modify_fentry(tr, tr->cur_image->image, im->image, lock_direct_mutex);
+@@ -501,7 +499,6 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
+ if (tr->cur_image)
+ bpf_tramp_image_put(tr->cur_image);
+ tr->cur_image = im;
+- tr->selector++;
+ out:
+ /* If any error happens, restore previous flags */
+ if (err)
+--
+2.39.2
+
--- /dev/null
+From d3e633b4acddb3c65a0f4ed549ab3e644eef6adb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 12:31:34 +0100
+Subject: bpftool: JIT limited misreported as negative value on aarch64
+
+From: Alan Maguire <alan.maguire@oracle.com>
+
+[ Upstream commit 04cb8453a91c7c22f60ddadb6cef0d19abb33bb5 ]
+
+On aarch64, "bpftool feature" reports an incorrect BPF JIT limit:
+
+$ sudo /sbin/bpftool feature
+Scanning system configuration...
+bpf() syscall restricted to privileged users
+JIT compiler is enabled
+JIT compiler hardening is disabled
+JIT compiler kallsyms exports are enabled for root
+skipping kernel config, can't open file: No such file or directory
+Global memory limit for JIT compiler for unprivileged users is -201326592 bytes
+
+This is because /proc/sys/net/core/bpf_jit_limit reports
+
+$ sudo cat /proc/sys/net/core/bpf_jit_limit
+68169519595520
+
+...and an int is assumed in read_procfs(). Change read_procfs()
+to return a long to avoid negative value reporting.
+
+Fixes: 7a4522bbef0c ("tools: bpftool: add probes for /proc/ eBPF parameters")
+Reported-by: Nicky Veitch <nicky.veitch@oracle.com>
+Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Jiri Olsa <jolsa@kernel.org>
+Acked-by: Quentin Monnet <quentin@isovalent.com>
+Link: https://lore.kernel.org/bpf/20230512113134.58996-1-alan.maguire@oracle.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/feature.c | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/tools/bpf/bpftool/feature.c b/tools/bpf/bpftool/feature.c
+index da16e6a27cccd..0675d6a464138 100644
+--- a/tools/bpf/bpftool/feature.c
++++ b/tools/bpf/bpftool/feature.c
+@@ -167,12 +167,12 @@ static int get_vendor_id(int ifindex)
+ return strtol(buf, NULL, 0);
+ }
+
+-static int read_procfs(const char *path)
++static long read_procfs(const char *path)
+ {
+ char *endptr, *line = NULL;
+ size_t len = 0;
+ FILE *fd;
+- int res;
++ long res;
+
+ fd = fopen(path, "r");
+ if (!fd)
+@@ -194,7 +194,7 @@ static int read_procfs(const char *path)
+
+ static void probe_unprivileged_disabled(void)
+ {
+- int res;
++ long res;
+
+ /* No support for C-style ouptut */
+
+@@ -216,14 +216,14 @@ static void probe_unprivileged_disabled(void)
+ printf("Unable to retrieve required privileges for bpf() syscall\n");
+ break;
+ default:
+- printf("bpf() syscall restriction has unknown value %d\n", res);
++ printf("bpf() syscall restriction has unknown value %ld\n", res);
+ }
+ }
+ }
+
+ static void probe_jit_enable(void)
+ {
+- int res;
++ long res;
+
+ /* No support for C-style ouptut */
+
+@@ -245,7 +245,7 @@ static void probe_jit_enable(void)
+ printf("Unable to retrieve JIT-compiler status\n");
+ break;
+ default:
+- printf("JIT-compiler status has unknown value %d\n",
++ printf("JIT-compiler status has unknown value %ld\n",
+ res);
+ }
+ }
+@@ -253,7 +253,7 @@ static void probe_jit_enable(void)
+
+ static void probe_jit_harden(void)
+ {
+- int res;
++ long res;
+
+ /* No support for C-style ouptut */
+
+@@ -275,7 +275,7 @@ static void probe_jit_harden(void)
+ printf("Unable to retrieve JIT hardening status\n");
+ break;
+ default:
+- printf("JIT hardening status has unknown value %d\n",
++ printf("JIT hardening status has unknown value %ld\n",
+ res);
+ }
+ }
+@@ -283,7 +283,7 @@ static void probe_jit_harden(void)
+
+ static void probe_jit_kallsyms(void)
+ {
+- int res;
++ long res;
+
+ /* No support for C-style ouptut */
+
+@@ -302,14 +302,14 @@ static void probe_jit_kallsyms(void)
+ printf("Unable to retrieve JIT kallsyms export status\n");
+ break;
+ default:
+- printf("JIT kallsyms exports status has unknown value %d\n", res);
++ printf("JIT kallsyms exports status has unknown value %ld\n", res);
+ }
+ }
+ }
+
+ static void probe_jit_limit(void)
+ {
+- int res;
++ long res;
+
+ /* No support for C-style ouptut */
+
+@@ -322,7 +322,7 @@ static void probe_jit_limit(void)
+ printf("Unable to retrieve global memory limit for JIT compiler for unprivileged users\n");
+ break;
+ default:
+- printf("Global memory limit for JIT compiler for unprivileged users is %d bytes\n", res);
++ printf("Global memory limit for JIT compiler for unprivileged users is %ld bytes\n", res);
+ }
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From 3dbb3059c41849e63b79c0e34ea58d3594b0e1b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 May 2023 09:53:54 +0200
+Subject: btrfs: fix file_offset for REQ_BTRFS_ONE_ORDERED bios that get split
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit c731cd0b6d255e4855a7cac9f276864032ab2387 ]
+
+If a bio gets split, it needs to have a proper file_offset for checksum
+validation and repair to work properly.
+
+Based on feedback from Josef, commit 852eee62d31a ("btrfs: allow
+btrfs_submit_bio to split bios") skipped this adjustment for ONE_ORDERED
+bios. But if we actually ever need to split a ONE_ORDERED read bio, this
+will lead to a wrong file offset in the repair code. Right now the only
+user of the file_offset is logging of an error message so this is mostly
+harmless, but the wrong offset might be more problematic for additional
+users in the future.
+
+Fixes: 852eee62d31a ("btrfs: allow btrfs_submit_bio to split bios")
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/bio.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c
+index 67e5156f940d3..4bb2c6f4ad0e7 100644
+--- a/fs/btrfs/bio.c
++++ b/fs/btrfs/bio.c
+@@ -79,8 +79,7 @@ static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info,
+ btrfs_bio_init(bbio, orig_bbio->inode, NULL, orig_bbio);
+
+ bbio->file_offset = orig_bbio->file_offset;
+- if (!(orig_bbio->bio.bi_opf & REQ_BTRFS_ONE_ORDERED))
+- orig_bbio->file_offset += map_length;
++ orig_bbio->file_offset += map_length;
+
+ atomic_inc(&orig_bbio->pending_ios);
+ return bbio;
+--
+2.39.2
+
--- /dev/null
+From 4eb6f0aff69011fe80d05eeb83fa0c5573d3421c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 17:39:45 +0100
+Subject: btrfs: make btrfs_split_bio work on struct btrfs_bio
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 2cef0c79bb81d8bae1dbc45195771a824ca45e76 ]
+
+btrfs_split_bio expects a btrfs_bio as argument and always allocates one.
+Type both the orig_bio argument and the return value as struct btrfs_bio
+to improve type safety.
+
+Reviewed-by: Anand Jain <anand.jain@oracle.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: c731cd0b6d25 ("btrfs: fix file_offset for REQ_BTRFS_ONE_ORDERED bios that get split")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/bio.c | 27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c
+index ada899613486a..67e5156f940d3 100644
+--- a/fs/btrfs/bio.c
++++ b/fs/btrfs/bio.c
+@@ -59,30 +59,31 @@ struct bio *btrfs_bio_alloc(unsigned int nr_vecs, blk_opf_t opf,
+ return bio;
+ }
+
+-static struct bio *btrfs_split_bio(struct btrfs_fs_info *fs_info,
+- struct bio *orig, u64 map_length,
+- bool use_append)
++static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info,
++ struct btrfs_bio *orig_bbio,
++ u64 map_length, bool use_append)
+ {
+- struct btrfs_bio *orig_bbio = btrfs_bio(orig);
++ struct btrfs_bio *bbio;
+ struct bio *bio;
+
+ if (use_append) {
+ unsigned int nr_segs;
+
+- bio = bio_split_rw(orig, &fs_info->limits, &nr_segs,
++ bio = bio_split_rw(&orig_bbio->bio, &fs_info->limits, &nr_segs,
+ &btrfs_clone_bioset, map_length);
+ } else {
+- bio = bio_split(orig, map_length >> SECTOR_SHIFT, GFP_NOFS,
+- &btrfs_clone_bioset);
++ bio = bio_split(&orig_bbio->bio, map_length >> SECTOR_SHIFT,
++ GFP_NOFS, &btrfs_clone_bioset);
+ }
+- btrfs_bio_init(btrfs_bio(bio), orig_bbio->inode, NULL, orig_bbio);
++ bbio = btrfs_bio(bio);
++ btrfs_bio_init(bbio, orig_bbio->inode, NULL, orig_bbio);
+
+- btrfs_bio(bio)->file_offset = orig_bbio->file_offset;
+- if (!(orig->bi_opf & REQ_BTRFS_ONE_ORDERED))
++ bbio->file_offset = orig_bbio->file_offset;
++ if (!(orig_bbio->bio.bi_opf & REQ_BTRFS_ONE_ORDERED))
+ orig_bbio->file_offset += map_length;
+
+ atomic_inc(&orig_bbio->pending_ios);
+- return bio;
++ return bbio;
+ }
+
+ static void btrfs_orig_write_end_io(struct bio *bio);
+@@ -631,8 +632,8 @@ static bool btrfs_submit_chunk(struct bio *bio, int mirror_num)
+ map_length = min(map_length, fs_info->max_zone_append_size);
+
+ if (map_length < length) {
+- bio = btrfs_split_bio(fs_info, bio, map_length, use_append);
+- bbio = btrfs_bio(bio);
++ bbio = btrfs_split_bio(fs_info, bbio, map_length, use_append);
++ bio = &bbio->bio;
+ }
+
+ /*
+--
+2.39.2
+
--- /dev/null
+From c2c0d89b992ba6f7f2b69b33c8f05b4f2f6c52fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 10:04:16 +0300
+Subject: bus: ti-sysc: Fix dispc quirk masking bool variables
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit f620596fa347170852da499e778a5736d79a4b79 ]
+
+Fix warning drivers/bus/ti-sysc.c:1806 sysc_quirk_dispc()
+warn: masking a bool.
+
+While at it let's add a comment for what were doing to make
+the code a bit easier to follow.
+
+Fixes: 7324a7a0d5e2 ("bus: ti-sysc: Implement display subsystem reset quirk")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/linux-omap/a8ec8a68-9c2c-4076-bf47-09fccce7659f@kili.mountain/
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/ti-sysc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
+index 6afae98978434..b5ceec2b2d84f 100644
+--- a/drivers/bus/ti-sysc.c
++++ b/drivers/bus/ti-sysc.c
+@@ -1814,7 +1814,7 @@ static u32 sysc_quirk_dispc(struct sysc *ddata, int dispc_offset,
+ if (!ddata->module_va)
+ return -EIO;
+
+- /* DISP_CONTROL */
++ /* DISP_CONTROL, shut down lcd and digit on disable if enabled */
+ val = sysc_read(ddata, dispc_offset + 0x40);
+ lcd_en = val & lcd_en_mask;
+ digit_en = val & digit_en_mask;
+@@ -1826,7 +1826,7 @@ static u32 sysc_quirk_dispc(struct sysc *ddata, int dispc_offset,
+ else
+ irq_mask |= BIT(2) | BIT(3); /* EVSYNC bits */
+ }
+- if (disable & (lcd_en | digit_en))
++ if (disable && (lcd_en || digit_en))
+ sysc_write(ddata, dispc_offset + 0x40,
+ val & ~(lcd_en_mask | digit_en_mask));
+
+--
+2.39.2
+
--- /dev/null
+From 024bb6991292d5656d5fcd1851091f3b2eb95273 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 May 2023 15:42:37 +0200
+Subject: can: kvaser_pciefd: Add function to set skb hwtstamps
+
+From: Jimmy Assarsson <extja@kvaser.com>
+
+[ Upstream commit 2d55e9f9b4427e1ad59b974f2267767aac3788d3 ]
+
+Add new function, kvaser_pciefd_set_skb_timestamp(), to set skb hwtstamps.
+
+Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
+Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Link: https://lore.kernel.org/all/20230529134248.752036-4-extja@kvaser.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Stable-dep-of: ec681b91befa ("can: kvaser_pciefd: Set hardware timestamp on transmitted packets")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/kvaser_pciefd.c | 27 ++++++++++-----------------
+ 1 file changed, 10 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
+index 956a4a57396f9..0b537292c7b19 100644
+--- a/drivers/net/can/kvaser_pciefd.c
++++ b/drivers/net/can/kvaser_pciefd.c
+@@ -538,6 +538,13 @@ static int kvaser_pciefd_set_tx_irq(struct kvaser_pciefd_can *can)
+ return 0;
+ }
+
++static inline void kvaser_pciefd_set_skb_timestamp(const struct kvaser_pciefd *pcie,
++ struct sk_buff *skb, u64 timestamp)
++{
++ skb_hwtstamps(skb)->hwtstamp =
++ ns_to_ktime(div_u64(timestamp * 1000, pcie->freq_to_ticks_div));
++}
++
+ static void kvaser_pciefd_setup_controller(struct kvaser_pciefd_can *can)
+ {
+ u32 mode;
+@@ -1171,7 +1178,6 @@ static int kvaser_pciefd_handle_data_packet(struct kvaser_pciefd *pcie,
+ struct canfd_frame *cf;
+ struct can_priv *priv;
+ struct net_device_stats *stats;
+- struct skb_shared_hwtstamps *shhwtstamps;
+ u8 ch_id = (p->header[1] >> KVASER_PCIEFD_PACKET_CHID_SHIFT) & 0x7;
+
+ if (ch_id >= pcie->nr_channels)
+@@ -1214,12 +1220,7 @@ static int kvaser_pciefd_handle_data_packet(struct kvaser_pciefd *pcie,
+ stats->rx_bytes += cf->len;
+ }
+ stats->rx_packets++;
+-
+- shhwtstamps = skb_hwtstamps(skb);
+-
+- shhwtstamps->hwtstamp =
+- ns_to_ktime(div_u64(p->timestamp * 1000,
+- pcie->freq_to_ticks_div));
++ kvaser_pciefd_set_skb_timestamp(pcie, skb, p->timestamp);
+
+ return netif_rx(skb);
+ }
+@@ -1282,7 +1283,6 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
+ struct net_device *ndev = can->can.dev;
+ struct sk_buff *skb;
+ struct can_frame *cf = NULL;
+- struct skb_shared_hwtstamps *shhwtstamps;
+ struct net_device_stats *stats = &ndev->stats;
+
+ old_state = can->can.state;
+@@ -1323,10 +1323,7 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
+ return -ENOMEM;
+ }
+
+- shhwtstamps = skb_hwtstamps(skb);
+- shhwtstamps->hwtstamp =
+- ns_to_ktime(div_u64(p->timestamp * 1000,
+- can->kv_pcie->freq_to_ticks_div));
++ kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
+ cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT;
+
+ cf->data[6] = bec.txerr;
+@@ -1374,7 +1371,6 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
+ struct net_device *ndev = can->can.dev;
+ struct sk_buff *skb;
+ struct can_frame *cf;
+- struct skb_shared_hwtstamps *shhwtstamps;
+
+ skb = alloc_can_err_skb(ndev, &cf);
+ if (!skb) {
+@@ -1394,10 +1390,7 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
+ cf->can_id |= CAN_ERR_RESTARTED;
+ }
+
+- shhwtstamps = skb_hwtstamps(skb);
+- shhwtstamps->hwtstamp =
+- ns_to_ktime(div_u64(p->timestamp * 1000,
+- can->kv_pcie->freq_to_ticks_div));
++ kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
+
+ cf->data[6] = bec.txerr;
+ cf->data[7] = bec.rxerr;
+--
+2.39.2
+
--- /dev/null
+From 6b8f184badf673fa413f3a39f1906f2853dee50d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 May 2023 15:42:38 +0200
+Subject: can: kvaser_pciefd: Set hardware timestamp on transmitted packets
+
+From: Jimmy Assarsson <extja@kvaser.com>
+
+[ Upstream commit ec681b91befa982477e24a150dd6452427fe6473 ]
+
+Set hardware timestamp on transmitted packets.
+
+Fixes: 26ad340e582d ("can: kvaser_pciefd: Add driver for Kvaser PCIEcan devices")
+Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
+Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Link: https://lore.kernel.org/all/20230529134248.752036-5-extja@kvaser.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/kvaser_pciefd.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
+index 0b537292c7b19..74a47244f1291 100644
+--- a/drivers/net/can/kvaser_pciefd.c
++++ b/drivers/net/can/kvaser_pciefd.c
+@@ -1519,6 +1519,7 @@ static void kvaser_pciefd_handle_nack_packet(struct kvaser_pciefd_can *can,
+
+ if (skb) {
+ cf->can_id |= CAN_ERR_BUSERROR;
++ kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
+ netif_rx(skb);
+ } else {
+ stats->rx_dropped++;
+@@ -1550,8 +1551,15 @@ static int kvaser_pciefd_handle_ack_packet(struct kvaser_pciefd *pcie,
+ netdev_dbg(can->can.dev, "Packet was flushed\n");
+ } else {
+ int echo_idx = p->header[0] & KVASER_PCIEFD_PACKET_SEQ_MSK;
+- int dlc = can_get_echo_skb(can->can.dev, echo_idx, NULL);
+- u8 count = ioread32(can->reg_base +
++ int dlc;
++ u8 count;
++ struct sk_buff *skb;
++
++ skb = can->can.echo_skb[echo_idx];
++ if (skb)
++ kvaser_pciefd_set_skb_timestamp(pcie, skb, p->timestamp);
++ dlc = can_get_echo_skb(can->can.dev, echo_idx, NULL);
++ count = ioread32(can->reg_base +
+ KVASER_PCIEFD_KCAN_TX_NPACKETS_REG) & 0xff;
+
+ if (count < KVASER_PCIEFD_CAN_TX_MAX_COUNT &&
+--
+2.39.2
+
--- /dev/null
+From faa42987e3f3c6715769c16cbc830a1fc007ac3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Jun 2023 11:57:26 +0900
+Subject: can: length: fix bitstuffing count
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 9fde4c557f78ee2f3626e92b4089ce9d54a2573a ]
+
+The Stuff Bit Count is always coded on 4 bits [1]. Update the Stuff
+Bit Count size accordingly.
+
+In addition, the CRC fields of CAN FD Frames contain stuff bits at
+fixed positions called fixed stuff bits [2]. The CRC field starts with
+a fixed stuff bit and then has another fixed stuff bit after each
+fourth bit [2], which allows us to derive this formula:
+
+ FSB count = 1 + round_down(len(CRC field)/4)
+
+The length of the CRC field is [1]:
+
+ len(CRC field) = len(Stuff Bit Count) + len(CRC)
+ = 4 + len(CRC)
+
+with len(CRC) either 17 or 21 bits depending of the payload length.
+
+In conclusion, for CRC17:
+
+ FSB count = 1 + round_down((4 + 17)/4)
+ = 6
+
+and for CRC 21:
+
+ FSB count = 1 + round_down((4 + 21)/4)
+ = 7
+
+Add a Fixed Stuff bits (FSB) field with above values and update
+CANFD_FRAME_OVERHEAD_SFF and CANFD_FRAME_OVERHEAD_EFF accordingly.
+
+[1] ISO 11898-1:2015 section 10.4.2.6 "CRC field":
+
+ The CRC field shall contain the CRC sequence followed by a recessive
+ CRC delimiter. For FD Frames, the CRC field shall also contain the
+ stuff count.
+
+ Stuff count
+
+ If FD Frames, the stuff count shall be at the beginning of the CRC
+ field. It shall consist of the stuff bit count modulo 8 in a 3-bit
+ gray code followed by a parity bit [...]
+
+[2] ISO 11898-1:2015 paragraph 10.5 "Frame coding":
+
+ In the CRC field of FD Frames, the stuff bits shall be inserted at
+ fixed positions; they are called fixed stuff bits. There shall be a
+ fixed stuff bit before the first bit of the stuff count, even if the
+ last bits of the preceding field are a sequence of five consecutive
+ bits of identical value, there shall be only the fixed stuff bit,
+ there shall not be two consecutive stuff bits. A further fixed stuff
+ bit shall be inserted after each fourth bit of the CRC field [...]
+
+Fixes: 85d99c3e2a13 ("can: length: can_skb_get_frame_len(): introduce function to get data length of frame in data link layer")
+Suggested-by: Thomas Kopp <Thomas.Kopp@microchip.com>
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Reviewed-by: Thomas Kopp <Thomas.Kopp@microchip.com>
+Link: https://lore.kernel.org/all/20230611025728.450837-2-mailhol.vincent@wanadoo.fr
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/can/length.h | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/include/linux/can/length.h b/include/linux/can/length.h
+index 6995092b774ec..ef1fd32cef16b 100644
+--- a/include/linux/can/length.h
++++ b/include/linux/can/length.h
+@@ -69,17 +69,18 @@
+ * Error Status Indicator (ESI) 1
+ * Data length code (DLC) 4
+ * Data field 0...512
+- * Stuff Bit Count (SBC) 0...16: 4 20...64:5
++ * Stuff Bit Count (SBC) 4
+ * CRC 0...16: 17 20...64:21
+ * CRC delimiter (CD) 1
++ * Fixed Stuff bits (FSB) 0...16: 6 20...64:7
+ * ACK slot (AS) 1
+ * ACK delimiter (AD) 1
+ * End-of-frame (EOF) 7
+ * Inter frame spacing 3
+ *
+- * assuming CRC21, rounded up and ignoring bitstuffing
++ * assuming CRC21, rounded up and ignoring dynamic bitstuffing
+ */
+-#define CANFD_FRAME_OVERHEAD_SFF DIV_ROUND_UP(61, 8)
++#define CANFD_FRAME_OVERHEAD_SFF DIV_ROUND_UP(67, 8)
+
+ /*
+ * Size of a CAN-FD Extended Frame
+@@ -98,17 +99,18 @@
+ * Error Status Indicator (ESI) 1
+ * Data length code (DLC) 4
+ * Data field 0...512
+- * Stuff Bit Count (SBC) 0...16: 4 20...64:5
++ * Stuff Bit Count (SBC) 4
+ * CRC 0...16: 17 20...64:21
+ * CRC delimiter (CD) 1
++ * Fixed Stuff bits (FSB) 0...16: 6 20...64:7
+ * ACK slot (AS) 1
+ * ACK delimiter (AD) 1
+ * End-of-frame (EOF) 7
+ * Inter frame spacing 3
+ *
+- * assuming CRC21, rounded up and ignoring bitstuffing
++ * assuming CRC21, rounded up and ignoring dynamic bitstuffing
+ */
+-#define CANFD_FRAME_OVERHEAD_EFF DIV_ROUND_UP(80, 8)
++#define CANFD_FRAME_OVERHEAD_EFF DIV_ROUND_UP(86, 8)
+
+ /*
+ * Maximum size of a Classical CAN frame
+--
+2.39.2
+
--- /dev/null
+From cdd4222bf1fb05a67ace89ae4e447a06cdfabdf7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 18:16:04 +0000
+Subject: cifs: do all necessary checks for credits within or before locking
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+[ Upstream commit 326a8d04f147e2bf393f6f9cdb74126ee6900607 ]
+
+All the server credits and in-flight info is protected by req_lock.
+Once the req_lock is held, and we've determined that we have enough
+credits to continue, this lock cannot be dropped till we've made the
+changes to credits and in-flight count.
+
+However, we used to drop the lock in order to avoid deadlock with
+the recent srv_lock. This could cause the checks already made to be
+invalidated.
+
+Fixed it by moving the server status check to before locking req_lock.
+
+Fixes: d7d7a66aacd6 ("cifs: avoid use of global locks for high contention data")
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2ops.c | 19 ++++++++++---------
+ fs/cifs/transport.c | 20 ++++++++++----------
+ 2 files changed, 20 insertions(+), 19 deletions(-)
+
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 5065398665f11..bb41b9bae262d 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -208,6 +208,16 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
+
+ spin_lock(&server->req_lock);
+ while (1) {
++ spin_unlock(&server->req_lock);
++
++ spin_lock(&server->srv_lock);
++ if (server->tcpStatus == CifsExiting) {
++ spin_unlock(&server->srv_lock);
++ return -ENOENT;
++ }
++ spin_unlock(&server->srv_lock);
++
++ spin_lock(&server->req_lock);
+ if (server->credits <= 0) {
+ spin_unlock(&server->req_lock);
+ cifs_num_waiters_inc(server);
+@@ -218,15 +228,6 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
+ return rc;
+ spin_lock(&server->req_lock);
+ } else {
+- spin_unlock(&server->req_lock);
+- spin_lock(&server->srv_lock);
+- if (server->tcpStatus == CifsExiting) {
+- spin_unlock(&server->srv_lock);
+- return -ENOENT;
+- }
+- spin_unlock(&server->srv_lock);
+-
+- spin_lock(&server->req_lock);
+ scredits = server->credits;
+ /* can deadlock with reopen */
+ if (scredits <= 8) {
+diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
+index 24bdd5f4d3bcc..968bfd029b8eb 100644
+--- a/fs/cifs/transport.c
++++ b/fs/cifs/transport.c
+@@ -522,6 +522,16 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits,
+ }
+
+ while (1) {
++ spin_unlock(&server->req_lock);
++
++ spin_lock(&server->srv_lock);
++ if (server->tcpStatus == CifsExiting) {
++ spin_unlock(&server->srv_lock);
++ return -ENOENT;
++ }
++ spin_unlock(&server->srv_lock);
++
++ spin_lock(&server->req_lock);
+ if (*credits < num_credits) {
+ scredits = *credits;
+ spin_unlock(&server->req_lock);
+@@ -547,15 +557,6 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits,
+ return -ERESTARTSYS;
+ spin_lock(&server->req_lock);
+ } else {
+- spin_unlock(&server->req_lock);
+-
+- spin_lock(&server->srv_lock);
+- if (server->tcpStatus == CifsExiting) {
+- spin_unlock(&server->srv_lock);
+- return -ENOENT;
+- }
+- spin_unlock(&server->srv_lock);
+-
+ /*
+ * For normal commands, reserve the last MAX_COMPOUND
+ * credits to compound requests.
+@@ -569,7 +570,6 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits,
+ * for servers that are slow to hand out credits on
+ * new sessions.
+ */
+- spin_lock(&server->req_lock);
+ if (!optype && num_credits == 1 &&
+ server->in_flight > 2 * MAX_COMPOUND &&
+ *credits <= MAX_COMPOUND) {
+--
+2.39.2
+
--- /dev/null
+From ad82985c81cb7ec70b2bb7506512b66ab0db109f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 18:16:03 +0000
+Subject: cifs: prevent use-after-free by freeing the cfile later
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+[ Upstream commit 33f736187d08f6bc822117629f263b97d3df4165 ]
+
+In smb2_compound_op we have a possible use-after-free
+which can cause hard to debug problems later on.
+
+This was revealed during stress testing with KASAN enabled
+kernel. Fixing it by moving the cfile free call to
+a few lines below, after the usage.
+
+Fixes: 76894f3e2f71 ("cifs: improve symlink handling for smb2+")
+Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2inode.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
+index 163a03298430d..7e3ac4cb4efa6 100644
+--- a/fs/cifs/smb2inode.c
++++ b/fs/cifs/smb2inode.c
+@@ -398,9 +398,6 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+ rsp_iov);
+
+ finished:
+- if (cfile)
+- cifsFileInfo_put(cfile);
+-
+ SMB2_open_free(&rqst[0]);
+ if (rc == -EREMCHG) {
+ pr_warn_once("server share %s deleted\n", tcon->tree_name);
+@@ -529,6 +526,9 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+ break;
+ }
+
++ if (cfile)
++ cifsFileInfo_put(cfile);
++
+ if (rc && err_iov && err_buftype) {
+ memcpy(err_iov, rsp_iov, 3 * sizeof(*err_iov));
+ memcpy(err_buftype, resp_buftype, 3 * sizeof(*err_buftype));
+--
+2.39.2
+
--- /dev/null
+From ce1bc9ab2c6398de06cdc0aaad002658290d4988 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Apr 2023 13:41:01 +0300
+Subject: clk: bcm: rpi: Fix off by one in raspberrypi_discover_clocks()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit da2edb3e3c09fd1451b7f400ccd1070ef086619a ]
+
+Smatch detected an off by one in this code:
+ drivers/clk/bcm/clk-raspberrypi.c:374 raspberrypi_discover_clocks()
+ error: buffer overflow 'data->hws' 16 <= 16
+
+The data->hws[] array has RPI_FIRMWARE_NUM_CLK_ID elements so the >
+comparison needs to changed to >=.
+
+Fixes: 12c90f3f27bb ("clk: bcm: rpi: Add variant structure")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/5a850b08-d2f5-4794-aceb-a6b468965139@kili.mountain
+Reviewed-by: Stefan Wahren <stefan.wahren@i2se.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
+index ce2f934797369..5df19f571a474 100644
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -356,9 +356,9 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
+ while (clks->id) {
+ struct raspberrypi_clk_variant *variant;
+
+- if (clks->id > RPI_FIRMWARE_NUM_CLK_ID) {
++ if (clks->id >= RPI_FIRMWARE_NUM_CLK_ID) {
+ dev_err(rpi->dev, "Unknown clock id: %u (max: %u)\n",
+- clks->id, RPI_FIRMWARE_NUM_CLK_ID);
++ clks->id, RPI_FIRMWARE_NUM_CLK_ID - 1);
+ return -EINVAL;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 94d3a4e7188cd82eaf69f987159605ffcc893bb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 12:39:07 +0300
+Subject: clk: cdce925: check return value of kasprintf()
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit bb7d09ddbf361d51eae46f38e7c8a2b85914ea2a ]
+
+kasprintf() returns a pointer to dynamically allocated memory.
+Pointer could be NULL in case allocation fails. Check pointer validity.
+Identified with coccinelle (kmerr.cocci script).
+
+Fixes: 19fbbbbcd3a3 ("Add TI CDCE925 I2C controlled clock synthesizer driver")
+Depends-on: e665f029a283 ("clk: Convert to using %pOFn instead of device_node.name")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230530093913.1656095-3-claudiu.beznea@microchip.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-cdce925.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c
+index 6350682f7e6d2..87890669297d8 100644
+--- a/drivers/clk/clk-cdce925.c
++++ b/drivers/clk/clk-cdce925.c
+@@ -701,6 +701,10 @@ static int cdce925_probe(struct i2c_client *client)
+ for (i = 0; i < data->chip_info->num_plls; ++i) {
+ pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d",
+ client->dev.of_node, i);
++ if (!pll_clk_name[i]) {
++ err = -ENOMEM;
++ goto error;
++ }
+ init.name = pll_clk_name[i];
+ data->pll[i].chip = data;
+ data->pll[i].hw.init = &init;
+@@ -742,6 +746,10 @@ static int cdce925_probe(struct i2c_client *client)
+ init.num_parents = 1;
+ init.parent_names = &parent_name; /* Mux Y1 to input */
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node);
++ if (!init.name) {
++ err = -ENOMEM;
++ goto error;
++ }
+ data->clk[0].chip = data;
+ data->clk[0].hw.init = &init;
+ data->clk[0].index = 0;
+@@ -760,6 +768,10 @@ static int cdce925_probe(struct i2c_client *client)
+ for (i = 1; i < data->chip_info->num_outputs; ++i) {
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d",
+ client->dev.of_node, i+1);
++ if (!init.name) {
++ err = -ENOMEM;
++ goto error;
++ }
+ data->clk[i].chip = data;
+ data->clk[i].hw.init = &init;
+ data->clk[i].index = i;
+--
+2.39.2
+
--- /dev/null
+From a8e1cc06c49bffed2d3651a589685034efc4e227 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 May 2023 20:01:20 +0300
+Subject: clk: clocking-wizard: Fix Oops in clk_wzrd_register_divider()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 9c632a6396505a019ea6d12b5ab45e659a542a93 ]
+
+Smatch detected this potential error pointer dereference
+clk_wzrd_register_divider(). If devm_clk_hw_register() fails then
+it sets "hw" to an error pointer and then dereferences it on the
+next line. Return the error directly instead.
+
+Fixes: 5a853722eb32 ("staging: clocking-wizard: Add support for dynamic reconfiguration")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/f0e39b5c-4554-41e0-80d9-54ca3fabd060@kili.mountain
+Reviewed-by: Michal Simek <michal.simek@amd.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+index eb1dfe7ecc1b4..4a23583933bcc 100644
+--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
++++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+@@ -354,7 +354,7 @@ static struct clk *clk_wzrd_register_divider(struct device *dev,
+ hw = &div->hw;
+ ret = devm_clk_hw_register(dev, hw);
+ if (ret)
+- hw = ERR_PTR(ret);
++ return ERR_PTR(ret);
+
+ return hw->clk;
+ }
+--
+2.39.2
+
--- /dev/null
+From 31277c63772b3c147b86010996313b4293c7e5eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 May 2023 13:25:03 +0200
+Subject: clk: Export clk_hw_forward_rate_request()
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit ed046ac74da0b5602566073023a1519b5ae657b7 ]
+
+Commit 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the
+parent") introduced the public clk_hw_forward_rate_request() function,
+but didn't export the symbol. Make sure it's the case.
+
+Fixes: 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the parent")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://lore.kernel.org/r/20221018-clk-range-checks-fixes-v4-1-971d5077e7d2@cerno.tech
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index ae07685c7588b..657b27743c4dd 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -1547,6 +1547,7 @@ void clk_hw_forward_rate_request(const struct clk_hw *hw,
+ parent->core, req,
+ parent_rate);
+ }
++EXPORT_SYMBOL_GPL(clk_hw_forward_rate_request);
+
+ static bool clk_core_can_round(struct clk_core * const core)
+ {
+--
+2.39.2
+
--- /dev/null
+From cd7d1f241731201b1a7577add1a802439bde010e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 11:22:53 +0800
+Subject: clk: Fix memory leak in devm_clk_notifier_register()
+
+From: Fei Shao <fshao@chromium.org>
+
+[ Upstream commit 7fb933e56f77a57ef7cfc59fc34cbbf1b1fa31ff ]
+
+devm_clk_notifier_register() allocates a devres resource for clk
+notifier but didn't register that to the device, so the notifier didn't
+get unregistered on device detach and the allocated resource was leaked.
+
+Fix the issue by registering the resource through devres_add().
+
+This issue was found with kmemleak on a Chromebook.
+
+Fixes: 6d30d50d037d ("clk: add devm variant of clk_notifier_register")
+Signed-off-by: Fei Shao <fshao@chromium.org>
+Link: https://lore.kernel.org/r/20230619112253.v2.1.I13f060c10549ef181603e921291bdea95f83033c@changeid
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 657b27743c4dd..15a405a5582bb 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -4694,6 +4694,7 @@ int devm_clk_notifier_register(struct device *dev, struct clk *clk,
+ if (!ret) {
+ devres->clk = clk;
+ devres->nb = nb;
++ devres_add(dev, devres);
+ } else {
+ devres_free(devres);
+ }
+--
+2.39.2
+
--- /dev/null
+From 2117e631bdee68cdaa74902813a5d28accbbc5a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Apr 2023 09:51:07 +0800
+Subject: clk: imx: clk-imx8mn: fix memory leak in imx8mn_clocks_probe
+
+From: Hao Luo <m202171776@hust.edu.cn>
+
+[ Upstream commit 188d070de9132667956f5aadd98d2bd87d3eac89 ]
+
+Use devm_of_iomap() instead of of_iomap() to automatically handle
+the unused ioremap region.
+
+If any error occurs, regions allocated by kzalloc() will leak,
+but using devm_kzalloc() instead will automatically free the memory
+using devm_kfree().
+
+Fixes: daeb14545514 ("clk: imx: imx8mn: Switch to clk_hw based API")
+Fixes: 96d6392b54db ("clk: imx: Add support for i.MX8MN clock driver")
+Signed-off-by: Hao Luo <m202171776@hust.edu.cn>
+Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20230411015107.2645-1-m202171776@hust.edu.cn
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8mn.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
+index a042ed3a9d6c2..569b2abf40525 100644
+--- a/drivers/clk/imx/clk-imx8mn.c
++++ b/drivers/clk/imx/clk-imx8mn.c
+@@ -323,7 +323,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
+ void __iomem *base;
+ int ret;
+
+- clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
++ clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
+ IMX8MN_CLK_END), GFP_KERNEL);
+ if (WARN_ON(!clk_hw_data))
+ return -ENOMEM;
+@@ -340,10 +340,10 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
+ hws[IMX8MN_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4");
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop");
+- base = of_iomap(np, 0);
++ base = devm_of_iomap(dev, np, 0, NULL);
+ of_node_put(np);
+- if (WARN_ON(!base)) {
+- ret = -ENOMEM;
++ if (WARN_ON(IS_ERR(base))) {
++ ret = PTR_ERR(base);
+ goto unregister_hws;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 3130f98ced03a2bd7cecba8cf286d79bc7efd463 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 May 2023 07:06:07 +0000
+Subject: clk: imx: clk-imx8mp: improve error handling in imx8mp_clocks_probe()
+
+From: Yuxing Liu <lyx2022@hust.edu.cn>
+
+[ Upstream commit 878b02d5f3b56cb090dbe2c70c89273be144087f ]
+
+Replace of_iomap() and kzalloc() with devm_of_iomap() and devm_kzalloc()
+which can automatically release the related memory when the device
+or driver is removed or unloaded to avoid potential memory leak.
+
+In this case, iounmap(anatop_base) in line 427,433 are removed
+as manual release is not required.
+
+Besides, referring to clk-imx8mq.c, check the return code of
+of_clk_add_hw_provider, if it returns negtive, print error info
+and unregister hws, which makes the program more robust.
+
+Fixes: 9c140d992676 ("clk: imx: Add support for i.MX8MP clock driver")
+Signed-off-by: Yuxing Liu <lyx2022@hust.edu.cn>
+Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20230503070607.2462-1-lyx2022@hust.edu.cn
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8mp.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
+index 3253589851ffb..de7d2d2176bea 100644
+--- a/drivers/clk/imx/clk-imx8mp.c
++++ b/drivers/clk/imx/clk-imx8mp.c
+@@ -414,25 +414,22 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
+ struct device *dev = &pdev->dev;
+ struct device_node *np;
+ void __iomem *anatop_base, *ccm_base;
++ int err;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop");
+- anatop_base = of_iomap(np, 0);
++ anatop_base = devm_of_iomap(dev, np, 0, NULL);
+ of_node_put(np);
+- if (WARN_ON(!anatop_base))
+- return -ENOMEM;
++ if (WARN_ON(IS_ERR(anatop_base)))
++ return PTR_ERR(anatop_base);
+
+ np = dev->of_node;
+ ccm_base = devm_platform_ioremap_resource(pdev, 0);
+- if (WARN_ON(IS_ERR(ccm_base))) {
+- iounmap(anatop_base);
++ if (WARN_ON(IS_ERR(ccm_base)))
+ return PTR_ERR(ccm_base);
+- }
+
+- clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL);
+- if (WARN_ON(!clk_hw_data)) {
+- iounmap(anatop_base);
++ clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL);
++ if (WARN_ON(!clk_hw_data))
+ return -ENOMEM;
+- }
+
+ clk_hw_data->num = IMX8MP_CLK_END;
+ hws = clk_hw_data->hws;
+@@ -721,7 +718,12 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
+
+ imx_check_clk_hws(hws, IMX8MP_CLK_END);
+
+- of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
++ err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
++ if (err < 0) {
++ dev_err(dev, "failed to register hws for i.MX8MP\n");
++ imx_unregister_hw_clocks(hws, IMX8MP_CLK_END);
++ return err;
++ }
+
+ imx_register_uart_clocks();
+
+--
+2.39.2
+
--- /dev/null
+From 690b6c41268eca7de84e22ced1d6e3e90c2c4849 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Apr 2023 11:34:51 +0000
+Subject: clk: imx: clk-imxrt1050: fix memory leak in imxrt1050_clocks_probe
+
+From: Kai Ma <kaima@hust.edu.cn>
+
+[ Upstream commit 1b280598ab3bd8a2dc8b96a12530d5b1ee7a8f4a ]
+
+Use devm_of_iomap() instead of of_iomap() to automatically
+handle the unused ioremap region. If any error occurs, regions allocated by
+kzalloc() will leak, but using devm_kzalloc() instead will automatically
+free the memory using devm_kfree().
+
+Also, fix error handling of hws by adding unregister_hws label, which
+unregisters remaining hws when iomap failed.
+
+Fixes: 7154b046d8f3 ("clk: imx: Add initial support for i.MXRT1050 clock driver")
+Signed-off-by: Kai Ma <kaima@hust.edu.cn>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Acked-by: Jesse Taube <Mr.Bossman075@gmail.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20230418113451.151312-1-kaima@hust.edu.cn
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imxrt1050.c | 22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c
+index fd5c51fc92c0e..08d155feb035a 100644
+--- a/drivers/clk/imx/clk-imxrt1050.c
++++ b/drivers/clk/imx/clk-imxrt1050.c
+@@ -42,7 +42,7 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
+ struct device_node *anp;
+ int ret;
+
+- clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
++ clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
+ IMXRT1050_CLK_END), GFP_KERNEL);
+ if (WARN_ON(!clk_hw_data))
+ return -ENOMEM;
+@@ -53,10 +53,12 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
+ hws[IMXRT1050_CLK_OSC] = imx_get_clk_hw_by_name(np, "osc");
+
+ anp = of_find_compatible_node(NULL, NULL, "fsl,imxrt-anatop");
+- pll_base = of_iomap(anp, 0);
++ pll_base = devm_of_iomap(dev, anp, 0, NULL);
+ of_node_put(anp);
+- if (WARN_ON(!pll_base))
+- return -ENOMEM;
++ if (WARN_ON(IS_ERR(pll_base))) {
++ ret = PTR_ERR(pll_base);
++ goto unregister_hws;
++ }
+
+ /* Anatop clocks */
+ hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL);
+@@ -104,8 +106,10 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
+
+ /* CCM clocks */
+ ccm_base = devm_platform_ioremap_resource(pdev, 0);
+- if (WARN_ON(IS_ERR(ccm_base)))
+- return PTR_ERR(ccm_base);
++ if (WARN_ON(IS_ERR(ccm_base))) {
++ ret = PTR_ERR(ccm_base);
++ goto unregister_hws;
++ }
+
+ hws[IMXRT1050_CLK_ARM_PODF] = imx_clk_hw_divider("arm_podf", "pll1_arm", ccm_base + 0x10, 0, 3);
+ hws[IMXRT1050_CLK_PRE_PERIPH_SEL] = imx_clk_hw_mux("pre_periph_sel", ccm_base + 0x18, 18, 2,
+@@ -149,8 +153,12 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
+ ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+ if (ret < 0) {
+ dev_err(dev, "Failed to register clks for i.MXRT1050.\n");
+- imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END);
++ goto unregister_hws;
+ }
++ return 0;
++
++unregister_hws:
++ imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END);
+ return ret;
+ }
+ static const struct of_device_id imxrt1050_clk_of_match[] = {
+--
+2.39.2
+
--- /dev/null
+From cf368e4abf7db0551ef839d1e6ecf3af3d4500c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 17:23:01 +0300
+Subject: clk: imx: scu: use _safe list iterator to avoid a use after free
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 632c60ecd25dbacee54d5581fe3aeb834b57010a ]
+
+This loop is freeing "clk" so it needs to use list_for_each_entry_safe().
+Otherwise it dereferences a freed variable to get the next item on the
+loop.
+
+Fixes: 77d8f3068c63 ("clk: imx: scu: add two cells binding support")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/0793fbd1-d2b5-4ec2-9403-3c39343a3e2d@kili.mountain
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-scu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
+index 1e6870f3671f6..db307890e4c16 100644
+--- a/drivers/clk/imx/clk-scu.c
++++ b/drivers/clk/imx/clk-scu.c
+@@ -707,11 +707,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
+
+ void imx_clk_scu_unregister(void)
+ {
+- struct imx_scu_clk_node *clk;
++ struct imx_scu_clk_node *clk, *n;
+ int i;
+
+ for (i = 0; i < IMX_SC_R_LAST; i++) {
+- list_for_each_entry(clk, &imx_scu_clks[i], node) {
++ list_for_each_entry_safe(clk, n, &imx_scu_clks[i], node) {
+ clk_hw_unregister(clk->hw);
+ kfree(clk);
+ }
+--
+2.39.2
+
--- /dev/null
+From 9f92a2155c32f3b3bcfd2e6c364712b27bde88e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 03:38:25 +0000
+Subject: clk: imx93: fix memory leak and missing unwind goto in
+ imx93_clocks_probe
+
+From: Zhanhao Hu <zero12113@hust.edu.cn>
+
+[ Upstream commit e02ba11b457647050cb16e7cad16cec3c252fade ]
+
+In function probe(), it returns directly without unregistered hws
+when error occurs.
+
+Fix this by adding 'goto unregister_hws;' on line 295 and
+line 310.
+
+Use devm_kzalloc() instead of kzalloc() to automatically
+free the memory using devm_kfree() when error occurs.
+
+Replace of_iomap() with devm_of_iomap() to automatically
+handle the unused ioremap region and delete 'iounmap(anatop_base);'
+in unregister_hws.
+
+Fixes: 24defbe194b6 ("clk: imx: add i.MX93 clk")
+Signed-off-by: Zhanhao Hu <zero12113@hust.edu.cn>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20230601033825.336558-1-zero12113@hust.edu.cn
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx93.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c
+index 8d0974db6bfd8..face30012b7dd 100644
+--- a/drivers/clk/imx/clk-imx93.c
++++ b/drivers/clk/imx/clk-imx93.c
+@@ -262,7 +262,7 @@ static int imx93_clocks_probe(struct platform_device *pdev)
+ void __iomem *base, *anatop_base;
+ int i, ret;
+
+- clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
++ clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
+ IMX93_CLK_END), GFP_KERNEL);
+ if (!clk_hw_data)
+ return -ENOMEM;
+@@ -286,10 +286,12 @@ static int imx93_clocks_probe(struct platform_device *pdev)
+ "sys_pll_pfd2", 1, 2);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx93-anatop");
+- anatop_base = of_iomap(np, 0);
++ anatop_base = devm_of_iomap(dev, np, 0, NULL);
+ of_node_put(np);
+- if (WARN_ON(!anatop_base))
+- return -ENOMEM;
++ if (WARN_ON(IS_ERR(anatop_base))) {
++ ret = PTR_ERR(base);
++ goto unregister_hws;
++ }
+
+ clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", anatop_base + 0x1200,
+ &imx_fracn_gppll);
+@@ -299,8 +301,8 @@ static int imx93_clocks_probe(struct platform_device *pdev)
+ np = dev->of_node;
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (WARN_ON(IS_ERR(base))) {
+- iounmap(anatop_base);
+- return PTR_ERR(base);
++ ret = PTR_ERR(base);
++ goto unregister_hws;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(root_array); i++) {
+@@ -332,7 +334,6 @@ static int imx93_clocks_probe(struct platform_device *pdev)
+
+ unregister_hws:
+ imx_unregister_hw_clocks(clks, IMX93_CLK_END);
+- iounmap(anatop_base);
+
+ return ret;
+ }
+--
+2.39.2
+
--- /dev/null
+From 666b884dc29c9281b8396e9dd98dbbbeea176f5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 12:39:11 +0300
+Subject: clk: keystone: sci-clk: check return value of kasprintf()
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit b73ed981da6d25c921aaefa7ca3df85bbd85b7fc ]
+
+kasprintf() returns a pointer to dynamically allocated memory.
+Pointer could be NULL in case allocation fails. Check pointer validity.
+Identified with coccinelle (kmerr.cocci script).
+
+Fixes: b745c0794e2f ("clk: keystone: Add sci-clk driver support")
+Depends-on: 96488c09b0f4 ("clk: keystone: sci-clk: cut down the clock name length")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230530093913.1656095-7-claudiu.beznea@microchip.com
+Reviewed-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/keystone/sci-clk.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
+index d4b4e74e22da6..254f2cf24be21 100644
+--- a/drivers/clk/keystone/sci-clk.c
++++ b/drivers/clk/keystone/sci-clk.c
+@@ -294,6 +294,8 @@ static int _sci_clk_build(struct sci_clk_provider *provider,
+
+ name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id,
+ sci_clk->clk_id);
++ if (!name)
++ return -ENOMEM;
+
+ init.name = name;
+
+--
+2.39.2
+
--- /dev/null
+From 8d0337c0a2b67d3e59a4c6ad6bfd313532752663 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 14:20:51 +0200
+Subject: clk: mediatek: clk-mt8173-apmixedsys: Fix iomap not released issue
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit b270ae61730e0ebccee39a21dd3311d6896a38ae ]
+
+In case of error after of_ioremap() the resource must be released:
+call iounmap() where appropriate to fix that.
+
+Fixes: 41138fbf876c ("clk: mediatek: mt8173: Migrate to platform driver and common probe")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230615122051.546985-4-angelogioacchino.delregno@collabora.com
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/clk-mt8173-apmixedsys.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c
+index a335d076d3f28..0b95d14c18042 100644
+--- a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c
++++ b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c
+@@ -95,8 +95,10 @@ static int clk_mt8173_apmixed_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
+- if (IS_ERR_OR_NULL(clk_data))
++ if (IS_ERR_OR_NULL(clk_data)) {
++ iounmap(base);
+ return -ENOMEM;
++ }
+
+ r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+ if (r)
+@@ -127,6 +129,7 @@ static int clk_mt8173_apmixed_probe(struct platform_device *pdev)
+ mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
+ free_clk_data:
+ mtk_free_clk_data(clk_data);
++ iounmap(base);
+ return r;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 20930a1c20189d855b8121d8cc7e48fb305c7521 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 14:20:50 +0200
+Subject: clk: mediatek: clk-mt8173-apmixedsys: Fix return value for of_iomap()
+ error
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 3dc265b369ee61db999d6d1588e888eb21dc421e ]
+
+The of_iomap() function returns NULL in case of error so usage of
+PTR_ERR() is wrong!
+Change that to return -ENOMEM in case of failure.
+
+Fixes: 41138fbf876c ("clk: mediatek: mt8173: Migrate to platform driver and common probe")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230615122051.546985-3-angelogioacchino.delregno@collabora.com
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Markus Schneider-Pargmann <msp@baylibre.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/clk-mt8173-apmixedsys.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c
+index a56c5845d07a5..a335d076d3f28 100644
+--- a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c
++++ b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c
+@@ -92,7 +92,7 @@ static int clk_mt8173_apmixed_probe(struct platform_device *pdev)
+
+ base = of_iomap(node, 0);
+ if (!base)
+- return PTR_ERR(base);
++ return -ENOMEM;
+
+ clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
+ if (IS_ERR_OR_NULL(clk_data))
+--
+2.39.2
+
--- /dev/null
+From c4b63860a4af8b2e689035ce73e87387bb551469 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Apr 2023 08:43:31 +0000
+Subject: clk: mediatek: fix of_iomap memory leak
+
+From: Bosi Zhang <u201911157@hust.edu.cn>
+
+[ Upstream commit 3db7285e044144fd88a356f5b641b9cd4b231a77 ]
+
+Smatch reports:
+drivers/clk/mediatek/clk-mtk.c:583 mtk_clk_simple_probe() warn:
+ 'base' from of_iomap() not released on lines: 496.
+
+This problem was also found in linux-next. In mtk_clk_simple_probe(),
+base is not released when handling errors
+if clk_data is not existed, which may cause a leak.
+So free_base should be added here to release base.
+
+Fixes: c58cd0e40ffa ("clk: mediatek: Add mtk_clk_simple_probe() to simplify clock providers")
+Signed-off-by: Bosi Zhang <u201911157@hust.edu.cn>
+Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
+Link: https://lore.kernel.org/r/20230422084331.47198-1-u201911157@hust.edu.cn
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/clk-mtk.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
+index 14e8b64a32a3c..b93fb1d80878c 100644
+--- a/drivers/clk/mediatek/clk-mtk.c
++++ b/drivers/clk/mediatek/clk-mtk.c
+@@ -492,8 +492,10 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
+ num_clks += mcd->num_mux_clks;
+
+ clk_data = mtk_alloc_clk_data(num_clks);
+- if (!clk_data)
+- return -ENOMEM;
++ if (!clk_data) {
++ r = -ENOMEM;
++ goto free_base;
++ }
+
+ if (mcd->fixed_clks) {
+ r = mtk_clk_register_fixed_clks(mcd->fixed_clks,
+@@ -578,6 +580,7 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
+ mcd->num_fixed_clks, clk_data);
+ free_data:
+ mtk_free_clk_data(clk_data);
++free_base:
+ if (mcd->shared_io && base)
+ iounmap(base);
+ return r;
+--
+2.39.2
+
--- /dev/null
+From 6b7c31a4b7622d65b96d1e3ca7c670ad0496efc2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 16:23:34 +0100
+Subject: clk: renesas: rzg2l: Fix CPG_SIPLL5_CLK1 register write
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+[ Upstream commit d1c20885d3b01e6a62e920af4b227abd294d22f3 ]
+
+As per the RZ/G2L HW(Rev.1.30 May2023) manual, there are no "write enable"
+bits in the CPG_SIPLL5_CLK1 register. So fix the CPG_SIPLL5_CLK register
+write by removing the "write enable" bits.
+
+Fixes: 1561380ee72f ("clk: renesas: rzg2l: Add FOUTPOSTDIV clk support")
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20230518152334.514922-1-biju.das.jz@bp.renesas.com
+[geert: Remove CPG_SIPLL5_CLK1_*_WEN bit definitions]
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/rzg2l-cpg.c | 6 ++----
+ drivers/clk/renesas/rzg2l-cpg.h | 3 ---
+ 2 files changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
+index 4bf40f6ccd1d1..22ed543fe6b06 100644
+--- a/drivers/clk/renesas/rzg2l-cpg.c
++++ b/drivers/clk/renesas/rzg2l-cpg.c
+@@ -603,10 +603,8 @@ static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw,
+ }
+
+ /* Output clock setting 1 */
+- writel(CPG_SIPLL5_CLK1_POSTDIV1_WEN | CPG_SIPLL5_CLK1_POSTDIV2_WEN |
+- CPG_SIPLL5_CLK1_REFDIV_WEN | (params.pl5_postdiv1 << 0) |
+- (params.pl5_postdiv2 << 4) | (params.pl5_refdiv << 8),
+- priv->base + CPG_SIPLL5_CLK1);
++ writel((params.pl5_postdiv1 << 0) | (params.pl5_postdiv2 << 4) |
++ (params.pl5_refdiv << 8), priv->base + CPG_SIPLL5_CLK1);
+
+ /* Output clock setting, SSCG modulation value setting 3 */
+ writel((params.pl5_fracin << 8), priv->base + CPG_SIPLL5_CLK3);
+diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h
+index eee780276a9e2..6cee9e56acc72 100644
+--- a/drivers/clk/renesas/rzg2l-cpg.h
++++ b/drivers/clk/renesas/rzg2l-cpg.h
+@@ -32,9 +32,6 @@
+ #define CPG_SIPLL5_STBY_RESETB_WEN BIT(16)
+ #define CPG_SIPLL5_STBY_SSCG_EN_WEN BIT(18)
+ #define CPG_SIPLL5_STBY_DOWNSPREAD_WEN BIT(20)
+-#define CPG_SIPLL5_CLK1_POSTDIV1_WEN BIT(16)
+-#define CPG_SIPLL5_CLK1_POSTDIV2_WEN BIT(20)
+-#define CPG_SIPLL5_CLK1_REFDIV_WEN BIT(24)
+ #define CPG_SIPLL5_CLK4_RESV_LSB (0xFF)
+ #define CPG_SIPLL5_MON_PLL5_LOCK BIT(4)
+
+--
+2.39.2
+
--- /dev/null
+From 9ed8d9cb56a0b1094ae938f1ec74cce366c7acd5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Mar 2023 08:55:35 +0100
+Subject: clk: rs9: Add support for 9FGV0441
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit e44fdd114cc3c872aa5157c6b3a190bcf92a9ffb ]
+
+This model is similar to 9FGV0241, but the DIFx bits start at bit 0.
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Link: https://lore.kernel.org/r/20230310075535.3476580-4-alexander.stein@ew.tq-group.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: ad527ca87e4e ("clk: rs9: Fix .driver_data content in i2c_device_id")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-renesas-pcie.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c
+index 0710362b2545b..10d31c222a1cb 100644
+--- a/drivers/clk/clk-renesas-pcie.c
++++ b/drivers/clk/clk-renesas-pcie.c
+@@ -6,6 +6,7 @@
+ * - 9FGV/9DBV/9DMV/9FGL/9DML/9QXL/9SQ
+ * Currently supported:
+ * - 9FGV0241
++ * - 9FGV0441
+ *
+ * Copyright (C) 2022 Marek Vasut <marex@denx.de>
+ */
+@@ -51,6 +52,7 @@
+ /* Supported Renesas 9-series models. */
+ enum rs9_model {
+ RENESAS_9FGV0241,
++ RENESAS_9FGV0441,
+ };
+
+ /* Structure to describe features of a particular 9-series model */
+@@ -64,7 +66,7 @@ struct rs9_driver_data {
+ struct i2c_client *client;
+ struct regmap *regmap;
+ const struct rs9_chip_info *chip_info;
+- struct clk_hw *clk_dif[2];
++ struct clk_hw *clk_dif[4];
+ u8 pll_amplitude;
+ u8 pll_ssc;
+ u8 clk_dif_sr;
+@@ -162,6 +164,8 @@ static u8 rs9_calc_dif(const struct rs9_driver_data *rs9, int idx)
+
+ if (model == RENESAS_9FGV0241)
+ return BIT(idx) + 1;
++ else if (model == RENESAS_9FGV0441)
++ return BIT(idx);
+
+ return 0;
+ }
+@@ -381,14 +385,22 @@ static const struct rs9_chip_info renesas_9fgv0241_info = {
+ .did = RS9_REG_DID_TYPE_FGV | 0x02,
+ };
+
++static const struct rs9_chip_info renesas_9fgv0441_info = {
++ .model = RENESAS_9FGV0441,
++ .num_clks = 4,
++ .did = RS9_REG_DID_TYPE_FGV | 0x04,
++};
++
+ static const struct i2c_device_id rs9_id[] = {
+ { "9fgv0241", .driver_data = RENESAS_9FGV0241 },
++ { "9fgv0441", .driver_data = RENESAS_9FGV0441 },
+ { }
+ };
+ MODULE_DEVICE_TABLE(i2c, rs9_id);
+
+ static const struct of_device_id clk_rs9_of_match[] = {
+ { .compatible = "renesas,9fgv0241", .data = &renesas_9fgv0241_info },
++ { .compatible = "renesas,9fgv0441", .data = &renesas_9fgv0441_info },
+ { }
+ };
+ MODULE_DEVICE_TABLE(of, clk_rs9_of_match);
+--
+2.39.2
+
--- /dev/null
+From 6c416b5a29cf39fec801f96d26fdaff55c087299 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Mar 2023 08:55:32 +0100
+Subject: clk: rs9: Check for vendor/device ID
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit da751726ff2ad2322d81316ebf6aadb22dfad0d8 ]
+
+This is in preparation to support additional devices which have different
+IDs as well as a slightly different register layout.
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Link: https://lore.kernel.org/r/20230310075535.3476580-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: ad527ca87e4e ("clk: rs9: Fix .driver_data content in i2c_device_id")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-renesas-pcie.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c
+index ff3a52d484790..f4e9f70f412af 100644
+--- a/drivers/clk/clk-renesas-pcie.c
++++ b/drivers/clk/clk-renesas-pcie.c
+@@ -45,6 +45,13 @@
+ #define RS9_REG_DID 0x6
+ #define RS9_REG_BCP 0x7
+
++#define RS9_REG_VID_IDT 0x01
++
++#define RS9_REG_DID_TYPE_FGV (0x0 << RS9_REG_DID_TYPE_SHIFT)
++#define RS9_REG_DID_TYPE_DBV (0x1 << RS9_REG_DID_TYPE_SHIFT)
++#define RS9_REG_DID_TYPE_DMV (0x2 << RS9_REG_DID_TYPE_SHIFT)
++#define RS9_REG_DID_TYPE_SHIFT 0x6
++
+ /* Supported Renesas 9-series models. */
+ enum rs9_model {
+ RENESAS_9FGV0241,
+@@ -54,6 +61,7 @@ enum rs9_model {
+ struct rs9_chip_info {
+ const enum rs9_model model;
+ unsigned int num_clks;
++ u8 did;
+ };
+
+ struct rs9_driver_data {
+@@ -270,6 +278,7 @@ static int rs9_probe(struct i2c_client *client)
+ {
+ unsigned char name[5] = "DIF0";
+ struct rs9_driver_data *rs9;
++ unsigned int vid, did;
+ struct clk_hw *hw;
+ int i, ret;
+
+@@ -306,6 +315,20 @@ static int rs9_probe(struct i2c_client *client)
+ if (ret < 0)
+ return ret;
+
++ ret = regmap_read(rs9->regmap, RS9_REG_VID, &vid);
++ if (ret < 0)
++ return ret;
++
++ ret = regmap_read(rs9->regmap, RS9_REG_DID, &did);
++ if (ret < 0)
++ return ret;
++
++ if (vid != RS9_REG_VID_IDT || did != rs9->chip_info->did)
++ return dev_err_probe(&client->dev, -ENODEV,
++ "Incorrect VID/DID: %#02x, %#02x. Expected %#02x, %#02x\n",
++ vid, did, RS9_REG_VID_IDT,
++ rs9->chip_info->did);
++
+ /* Register clock */
+ for (i = 0; i < rs9->chip_info->num_clks; i++) {
+ snprintf(name, 5, "DIF%d", i);
+@@ -349,6 +372,7 @@ static int __maybe_unused rs9_resume(struct device *dev)
+ static const struct rs9_chip_info renesas_9fgv0241_info = {
+ .model = RENESAS_9FGV0241,
+ .num_clks = 2,
++ .did = RS9_REG_DID_TYPE_FGV | 0x02,
+ };
+
+ static const struct i2c_device_id rs9_id[] = {
+--
+2.39.2
+
--- /dev/null
+From d2780b66fd639902a67e5763d645bcce2b7a6a7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 May 2023 15:39:06 +0200
+Subject: clk: rs9: Fix .driver_data content in i2c_device_id
+
+From: Marek Vasut <marek.vasut+renesas@mailbox.org>
+
+[ Upstream commit ad527ca87e4ea42d7baad2ce710b44069287931b ]
+
+The .driver_data content in i2c_device_id table must match the
+.data content in of_device_id table, else device_get_match_data()
+would return bogus value on i2c_device_id match. Align the two
+tables.
+
+The i2c_device_id table is now converted from of_device_id using
+'s@.compatible = "renesas,\([^"]\+"\), .data = \(.*\)@"\1, .driver_data = (kernel_ulong_t)\2@'
+
+Fixes: 892e0ddea1aa ("clk: rs9: Add Renesas 9-series PCIe clock generator driver")
+Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
+Link: https://lore.kernel.org/r/20230507133906.15061-3-marek.vasut+renesas@mailbox.org
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-renesas-pcie.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c
+index 10d31c222a1cb..6060cafe1aa22 100644
+--- a/drivers/clk/clk-renesas-pcie.c
++++ b/drivers/clk/clk-renesas-pcie.c
+@@ -392,8 +392,8 @@ static const struct rs9_chip_info renesas_9fgv0441_info = {
+ };
+
+ static const struct i2c_device_id rs9_id[] = {
+- { "9fgv0241", .driver_data = RENESAS_9FGV0241 },
+- { "9fgv0441", .driver_data = RENESAS_9FGV0441 },
++ { "9fgv0241", .driver_data = (kernel_ulong_t)&renesas_9fgv0241_info },
++ { "9fgv0441", .driver_data = (kernel_ulong_t)&renesas_9fgv0441_info },
+ { }
+ };
+ MODULE_DEVICE_TABLE(i2c, rs9_id);
+--
+2.39.2
+
--- /dev/null
+From 05f72a9ecbcb47af4218dc5cc33e66f016a4c683 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Mar 2023 08:55:34 +0100
+Subject: clk: rs9: Support device specific dif bit calculation
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 603df193ec5174ff81c32cf1a78b7819ce984b8c ]
+
+The calculation DIFx is BIT(n) +1 is only true for 9FGV0241. With
+additional devices this is getting more complicated.
+Support a base bit for the DIF calculation, currently only devices
+with consecutive bits are supported, e.g. the 6-channel device needs
+additional logic.
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Link: https://lore.kernel.org/r/20230310075535.3476580-3-alexander.stein@ew.tq-group.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: ad527ca87e4e ("clk: rs9: Fix .driver_data content in i2c_device_id")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-renesas-pcie.c | 32 +++++++++++++++++++-------------
+ 1 file changed, 19 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c
+index f4e9f70f412af..0710362b2545b 100644
+--- a/drivers/clk/clk-renesas-pcie.c
++++ b/drivers/clk/clk-renesas-pcie.c
+@@ -18,7 +18,6 @@
+ #include <linux/regmap.h>
+
+ #define RS9_REG_OE 0x0
+-#define RS9_REG_OE_DIF_OE(n) BIT((n) + 1)
+ #define RS9_REG_SS 0x1
+ #define RS9_REG_SS_AMP_0V6 0x0
+ #define RS9_REG_SS_AMP_0V7 0x1
+@@ -31,9 +30,6 @@
+ #define RS9_REG_SS_SSC_MASK (3 << 3)
+ #define RS9_REG_SS_SSC_LOCK BIT(5)
+ #define RS9_REG_SR 0x2
+-#define RS9_REG_SR_2V0_DIF(n) 0
+-#define RS9_REG_SR_3V0_DIF(n) BIT((n) + 1)
+-#define RS9_REG_SR_DIF_MASK(n) BIT((n) + 1)
+ #define RS9_REG_REF 0x3
+ #define RS9_REG_REF_OE BIT(4)
+ #define RS9_REG_REF_OD BIT(5)
+@@ -160,17 +156,27 @@ static const struct regmap_config rs9_regmap_config = {
+ .reg_read = rs9_regmap_i2c_read,
+ };
+
++static u8 rs9_calc_dif(const struct rs9_driver_data *rs9, int idx)
++{
++ enum rs9_model model = rs9->chip_info->model;
++
++ if (model == RENESAS_9FGV0241)
++ return BIT(idx) + 1;
++
++ return 0;
++}
++
+ static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
+ {
+ struct i2c_client *client = rs9->client;
++ u8 dif = rs9_calc_dif(rs9, idx);
+ unsigned char name[5] = "DIF0";
+ struct device_node *np;
+ int ret;
+ u32 sr;
+
+ /* Set defaults */
+- rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
+- rs9->clk_dif_sr |= RS9_REG_SR_3V0_DIF(idx);
++ rs9->clk_dif_sr |= dif;
+
+ snprintf(name, 5, "DIF%d", idx);
+ np = of_get_child_by_name(client->dev.of_node, name);
+@@ -182,11 +188,9 @@ static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
+ of_node_put(np);
+ if (!ret) {
+ if (sr == 2000000) { /* 2V/ns */
+- rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
+- rs9->clk_dif_sr |= RS9_REG_SR_2V0_DIF(idx);
++ rs9->clk_dif_sr &= ~dif;
+ } else if (sr == 3000000) { /* 3V/ns (default) */
+- rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
+- rs9->clk_dif_sr |= RS9_REG_SR_3V0_DIF(idx);
++ rs9->clk_dif_sr |= dif;
+ } else
+ ret = dev_err_probe(&client->dev, -EINVAL,
+ "Invalid renesas,slew-rate value\n");
+@@ -257,11 +261,13 @@ static void rs9_update_config(struct rs9_driver_data *rs9)
+ }
+
+ for (i = 0; i < rs9->chip_info->num_clks; i++) {
+- if (rs9->clk_dif_sr & RS9_REG_SR_3V0_DIF(i))
++ u8 dif = rs9_calc_dif(rs9, i);
++
++ if (rs9->clk_dif_sr & dif)
+ continue;
+
+- regmap_update_bits(rs9->regmap, RS9_REG_SR, RS9_REG_SR_3V0_DIF(i),
+- rs9->clk_dif_sr & RS9_REG_SR_3V0_DIF(i));
++ regmap_update_bits(rs9->regmap, RS9_REG_SR, dif,
++ rs9->clk_dif_sr & dif);
+ }
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 2c41313900b30f642762bf28af689adab7e4cd45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 12:39:09 +0300
+Subject: clk: si5341: check return value of {devm_}kasprintf()
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit 36e4ef82016a2b785cf2317eade77e76699b7bff ]
+
+{devm_}kasprintf() returns a pointer to dynamically allocated memory.
+Pointer could be NULL in case allocation fails. Check pointer validity.
+Identified with coccinelle (kmerr.cocci script).
+
+Fixes: 3044a860fd09 ("clk: Add Si5341/Si5340 driver")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230530093913.1656095-5-claudiu.beznea@microchip.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-si5341.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
+index 6dca3288c8940..b2cf7edc8b308 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -1697,6 +1697,10 @@ static int si5341_probe(struct i2c_client *client)
+ for (i = 0; i < data->num_synth; ++i) {
+ synth_clock_names[i] = devm_kasprintf(&client->dev, GFP_KERNEL,
+ "%s.N%u", client->dev.of_node->name, i);
++ if (!synth_clock_names[i]) {
++ err = -ENOMEM;
++ goto free_clk_names;
++ }
+ init.name = synth_clock_names[i];
+ data->synth[i].index = i;
+ data->synth[i].data = data;
+@@ -1715,6 +1719,10 @@ static int si5341_probe(struct i2c_client *client)
+ for (i = 0; i < data->num_outputs; ++i) {
+ init.name = kasprintf(GFP_KERNEL, "%s.%d",
+ client->dev.of_node->name, i);
++ if (!init.name) {
++ err = -ENOMEM;
++ goto free_clk_names;
++ }
+ init.flags = config[i].synth_master ? CLK_SET_RATE_PARENT : 0;
+ data->clk[i].index = i;
+ data->clk[i].data = data;
+--
+2.39.2
+
--- /dev/null
+From 8d0a02ed1f4d88b76b5f742121b55f801c16b765 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 12:39:10 +0300
+Subject: clk: si5341: free unused memory on probe failure
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit 267ad94b13c53d8c99a336f0841b1fa1595b1d0f ]
+
+Pointers from synth_clock_names[] should be freed at the end of probe
+either on probe success or failure path.
+
+Fixes: b7bbf6ec4940 ("clk: si5341: Allow different output VDD_SEL values")
+Fixes: 9b13ff4340df ("clk: si5341: Add sysfs properties to allow checking/resetting device faults")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230530093913.1656095-6-claudiu.beznea@microchip.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-si5341.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
+index b2cf7edc8b308..c7d8cbd22bacc 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -1744,7 +1744,7 @@ static int si5341_probe(struct i2c_client *client)
+ if (err) {
+ dev_err(&client->dev,
+ "output %u registration failed\n", i);
+- goto cleanup;
++ goto free_clk_names;
+ }
+ if (config[i].always_on)
+ clk_prepare(data->clk[i].hw.clk);
+@@ -1754,7 +1754,7 @@ static int si5341_probe(struct i2c_client *client)
+ data);
+ if (err) {
+ dev_err(&client->dev, "unable to add clk provider\n");
+- goto cleanup;
++ goto free_clk_names;
+ }
+
+ if (initialization_required) {
+@@ -1762,11 +1762,11 @@ static int si5341_probe(struct i2c_client *client)
+ regcache_cache_only(data->regmap, false);
+ err = regcache_sync(data->regmap);
+ if (err < 0)
+- goto cleanup;
++ goto free_clk_names;
+
+ err = si5341_finalize_defaults(data);
+ if (err < 0)
+- goto cleanup;
++ goto free_clk_names;
+ }
+
+ /* wait for device to report input clock present and PLL lock */
+@@ -1775,21 +1775,19 @@ static int si5341_probe(struct i2c_client *client)
+ 10000, 250000);
+ if (err) {
+ dev_err(&client->dev, "Error waiting for input clock or PLL lock\n");
+- goto cleanup;
++ goto free_clk_names;
+ }
+
+ /* clear sticky alarm bits from initialization */
+ err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0);
+ if (err) {
+ dev_err(&client->dev, "unable to clear sticky status\n");
+- goto cleanup;
++ goto free_clk_names;
+ }
+
+ err = sysfs_create_files(&client->dev.kobj, si5341_attributes);
+- if (err) {
++ if (err)
+ dev_err(&client->dev, "unable to create sysfs files\n");
+- goto cleanup;
+- }
+
+ free_clk_names:
+ /* Free the names, clk framework makes copies */
+--
+2.39.2
+
--- /dev/null
+From 982e50788c4b8f0cfe548d8194500ff474ba4c37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 12:39:08 +0300
+Subject: clk: si5341: return error if one synth clock registration fails
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit 2560114c06d7a752b3f4639f28cece58fed11267 ]
+
+In case devm_clk_hw_register() fails for one of synth clocks the probe
+continues. Later on, when registering output clocks which have as parents
+all the synth clocks, in case there is registration failure for at least
+one synth clock the information passed to clk core for registering output
+clock is not right: init.num_parents is fixed but init.parents may contain
+an array with less parents.
+
+Fixes: 3044a860fd09 ("clk: Add Si5341/Si5340 driver")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230530093913.1656095-4-claudiu.beznea@microchip.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-si5341.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
+index 0e528d7ba656e..6dca3288c8940 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -1553,7 +1553,7 @@ static int si5341_probe(struct i2c_client *client)
+ struct clk_init_data init;
+ struct clk *input;
+ const char *root_clock_name;
+- const char *synth_clock_names[SI5341_NUM_SYNTH];
++ const char *synth_clock_names[SI5341_NUM_SYNTH] = { NULL };
+ int err;
+ unsigned int i;
+ struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS];
+@@ -1705,6 +1705,7 @@ static int si5341_probe(struct i2c_client *client)
+ if (err) {
+ dev_err(&client->dev,
+ "synth N%u registration failed\n", i);
++ goto free_clk_names;
+ }
+ }
+
+@@ -1782,16 +1783,17 @@ static int si5341_probe(struct i2c_client *client)
+ goto cleanup;
+ }
+
++free_clk_names:
+ /* Free the names, clk framework makes copies */
+ for (i = 0; i < data->num_synth; ++i)
+ devm_kfree(&client->dev, (void *)synth_clock_names[i]);
+
+- return 0;
+-
+ cleanup:
+- for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
+- if (data->clk[i].vddo_reg)
+- regulator_disable(data->clk[i].vddo_reg);
++ if (err) {
++ for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
++ if (data->clk[i].vddo_reg)
++ regulator_disable(data->clk[i].vddo_reg);
++ }
+ }
+ return err;
+ }
+--
+2.39.2
+
--- /dev/null
+From 6fcf15cdf3242a6e953668a4bc0d285724f400aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 09:41:24 +0000
+Subject: clk: tegra: tegra124-emc: Fix potential memory leak
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 53a06e5924c0d43c11379a08c5a78529c3e61595 ]
+
+The tegra and tegra needs to be freed in the error handling path, otherwise
+it will be leaked.
+
+Fixes: 2db04f16b589 ("clk: tegra: Add EMC clock driver")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Link: https://lore.kernel.org/r/20221209094124.71043-1-yuancan@huawei.com
+Acked-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/tegra/clk-tegra124-emc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c
+index 219c80653dbdb..2a6db04342815 100644
+--- a/drivers/clk/tegra/clk-tegra124-emc.c
++++ b/drivers/clk/tegra/clk-tegra124-emc.c
+@@ -464,6 +464,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
+ err = load_one_timing_from_dt(tegra, timing, child);
+ if (err) {
+ of_node_put(child);
++ kfree(tegra->timings);
+ return err;
+ }
+
+@@ -515,6 +516,7 @@ struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np
+ err = load_timings_from_dt(tegra, node, node_ram_code);
+ if (err) {
+ of_node_put(node);
++ kfree(tegra);
+ return ERR_PTR(err);
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From 7a1a7a5aa86aaf3eada67764c92da3328398d6f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 12:39:12 +0300
+Subject: clk: ti: clkctrl: check return value of kasprintf()
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit bd46cd0b802d9c9576ca78007aa084ae3e74907b ]
+
+kasprintf() returns a pointer to dynamically allocated memory.
+Pointer could be NULL in case allocation fails. Check pointer validity.
+Identified with coccinelle (kmerr.cocci script).
+
+Fixes: 852049594b9a ("clk: ti: clkctrl: convert subclocks to use proper names also")
+Fixes: 6c3090520554 ("clk: ti: clkctrl: Fix hidden dependency to node name")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230530093913.1656095-8-claudiu.beznea@microchip.com
+Reviewed-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/ti/clkctrl.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c
+index f73f402ff7de9..87e5624789ef6 100644
+--- a/drivers/clk/ti/clkctrl.c
++++ b/drivers/clk/ti/clkctrl.c
+@@ -258,6 +258,9 @@ static const char * __init clkctrl_get_clock_name(struct device_node *np,
+ if (clkctrl_name && !legacy_naming) {
+ clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d",
+ clkctrl_name, offset, index);
++ if (!clock_name)
++ return NULL;
++
+ strreplace(clock_name, '_', '-');
+
+ return clock_name;
+@@ -586,6 +589,10 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
+ if (clkctrl_name) {
+ provider->clkdm_name = kasprintf(GFP_KERNEL,
+ "%s_clkdm", clkctrl_name);
++ if (!provider->clkdm_name) {
++ kfree(provider);
++ return;
++ }
+ goto clkdm_found;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 15f73646d09fcd2de12d154f194f9f11448ff51c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 12:39:06 +0300
+Subject: clk: vc5: check memory returned by kasprintf()
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit 144601f6228de5598f03e693822b60a95c367a17 ]
+
+kasprintf() returns a pointer to dynamically allocated memory.
+Pointer could be NULL in case allocation fails. Check pointer validity.
+Identified with coccinelle (kmerr.cocci script).
+
+Fixes: f491276a5168 ("clk: vc5: Allow Versaclock driver to support multiple instances")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230530093913.1656095-2-claudiu.beznea@microchip.com
+Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-versaclock5.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
+index 5452471b7ba55..e9a7f3c91ae0e 100644
+--- a/drivers/clk/clk-versaclock5.c
++++ b/drivers/clk/clk-versaclock5.c
+@@ -1028,6 +1028,11 @@ static int vc5_probe(struct i2c_client *client)
+ }
+
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node);
++ if (!init.name) {
++ ret = -ENOMEM;
++ goto err_clk;
++ }
++
+ init.ops = &vc5_mux_ops;
+ init.flags = 0;
+ init.parent_names = parent_names;
+@@ -1042,6 +1047,10 @@ static int vc5_probe(struct i2c_client *client)
+ memset(&init, 0, sizeof(init));
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl",
+ client->dev.of_node);
++ if (!init.name) {
++ ret = -ENOMEM;
++ goto err_clk;
++ }
+ init.ops = &vc5_dbl_ops;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = parent_names;
+@@ -1057,6 +1066,10 @@ static int vc5_probe(struct i2c_client *client)
+ /* Register PFD */
+ memset(&init, 0, sizeof(init));
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.pfd", client->dev.of_node);
++ if (!init.name) {
++ ret = -ENOMEM;
++ goto err_clk;
++ }
+ init.ops = &vc5_pfd_ops;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = parent_names;
+@@ -1074,6 +1087,10 @@ static int vc5_probe(struct i2c_client *client)
+ /* Register PLL */
+ memset(&init, 0, sizeof(init));
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.pll", client->dev.of_node);
++ if (!init.name) {
++ ret = -ENOMEM;
++ goto err_clk;
++ }
+ init.ops = &vc5_pll_ops;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = parent_names;
+@@ -1093,6 +1110,10 @@ static int vc5_probe(struct i2c_client *client)
+ memset(&init, 0, sizeof(init));
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d",
+ client->dev.of_node, idx);
++ if (!init.name) {
++ ret = -ENOMEM;
++ goto err_clk;
++ }
+ init.ops = &vc5_fod_ops;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = parent_names;
+@@ -1111,6 +1132,10 @@ static int vc5_probe(struct i2c_client *client)
+ memset(&init, 0, sizeof(init));
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb",
+ client->dev.of_node);
++ if (!init.name) {
++ ret = -ENOMEM;
++ goto err_clk;
++ }
+ init.ops = &vc5_clk_out_ops;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = parent_names;
+@@ -1137,6 +1162,10 @@ static int vc5_probe(struct i2c_client *client)
+ memset(&init, 0, sizeof(init));
+ init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d",
+ client->dev.of_node, idx + 1);
++ if (!init.name) {
++ ret = -ENOMEM;
++ goto err_clk;
++ }
+ init.ops = &vc5_clk_out_ops;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = parent_names;
+--
+2.39.2
+
--- /dev/null
+From bba9d747fabce514187595a9371b8d7f3388bd02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 May 2023 15:39:04 +0200
+Subject: clk: vc5: Fix .driver_data content in i2c_device_id
+
+From: Marek Vasut <marek.vasut+renesas@mailbox.org>
+
+[ Upstream commit be3471c5bd9b921c9adfab7948e8021611639164 ]
+
+The .driver_data content in i2c_device_id table must match the
+.data content in of_device_id table, else device_get_match_data()
+would return bogus value on i2c_device_id match. Align the two
+tables.
+
+The i2c_device_id table is now converted from of_device_id using
+'s@.compatible = "idt,\([^"]\+"\), .data = \(.*\)@"\1, .driver_data = (kernel_ulong_t)\2@'
+
+Fixes: 9adddb01ce5f ("clk: vc5: Add structure to describe particular chip features")
+Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
+Link: https://lore.kernel.org/r/20230507133906.15061-1-marek.vasut+renesas@mailbox.org
+Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-versaclock5.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
+index fa71a57875ce8..5452471b7ba55 100644
+--- a/drivers/clk/clk-versaclock5.c
++++ b/drivers/clk/clk-versaclock5.c
+@@ -1271,14 +1271,14 @@ static const struct vc5_chip_info idt_5p49v6975_info = {
+ };
+
+ static const struct i2c_device_id vc5_id[] = {
+- { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 },
+- { "5p49v5925", .driver_data = IDT_VC5_5P49V5925 },
+- { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 },
+- { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 },
+- { "5p49v60", .driver_data = IDT_VC6_5P49V60 },
+- { "5p49v6901", .driver_data = IDT_VC6_5P49V6901 },
+- { "5p49v6965", .driver_data = IDT_VC6_5P49V6965 },
+- { "5p49v6975", .driver_data = IDT_VC6_5P49V6975 },
++ { "5p49v5923", .driver_data = (kernel_ulong_t)&idt_5p49v5923_info },
++ { "5p49v5925", .driver_data = (kernel_ulong_t)&idt_5p49v5925_info },
++ { "5p49v5933", .driver_data = (kernel_ulong_t)&idt_5p49v5933_info },
++ { "5p49v5935", .driver_data = (kernel_ulong_t)&idt_5p49v5935_info },
++ { "5p49v60", .driver_data = (kernel_ulong_t)&idt_5p49v60_info },
++ { "5p49v6901", .driver_data = (kernel_ulong_t)&idt_5p49v6901_info },
++ { "5p49v6965", .driver_data = (kernel_ulong_t)&idt_5p49v6965_info },
++ { "5p49v6975", .driver_data = (kernel_ulong_t)&idt_5p49v6975_info },
+ { }
+ };
+ MODULE_DEVICE_TABLE(i2c, vc5_id);
+--
+2.39.2
+
--- /dev/null
+From d15037614f9354bc1738498934823188950de51c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 May 2023 15:39:05 +0200
+Subject: clk: vc7: Fix .driver_data content in i2c_device_id
+
+From: Marek Vasut <marek.vasut+renesas@mailbox.org>
+
+[ Upstream commit b5e10beeafaa3266559c582dde7534ae3fe8cefb ]
+
+The .driver_data content in i2c_device_id table must match the
+.data content in of_device_id table, else device_get_match_data()
+would return bogus value on i2c_device_id match. Align the two
+tables.
+
+The i2c_device_id table is now converted from of_device_id using
+'s@.compatible = "renesas,\([^"]\+"\), .data = \(.*\)@"\1, .driver_data = (kernel_ulong_t)\2@'
+
+Fixes: 48c5e98fedd9 ("clk: Renesas versaclock7 ccf device driver")
+Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
+Link: https://lore.kernel.org/r/20230507133906.15061-2-marek.vasut+renesas@mailbox.org
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-versaclock7.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/clk-versaclock7.c b/drivers/clk/clk-versaclock7.c
+index 8e4f86e852aa0..0ae191f50b4b2 100644
+--- a/drivers/clk/clk-versaclock7.c
++++ b/drivers/clk/clk-versaclock7.c
+@@ -1282,7 +1282,7 @@ static const struct regmap_config vc7_regmap_config = {
+ };
+
+ static const struct i2c_device_id vc7_i2c_id[] = {
+- { "rc21008a", VC7_RC21008A },
++ { "rc21008a", .driver_data = (kernel_ulong_t)&vc7_rc21008a_info },
+ {}
+ };
+ MODULE_DEVICE_TABLE(i2c, vc7_i2c_id);
+--
+2.39.2
+
--- /dev/null
+From f2af91aff968b0b696678a5591545febad91db7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Apr 2023 06:56:11 +0000
+Subject: clocksource/drivers/cadence-ttc: Fix memory leak in ttc_timer_probe
+
+From: Feng Mingxi <m202271825@hust.edu.cn>
+
+[ Upstream commit 8b5bf64c89c7100c921bd807ba39b2eb003061ab ]
+
+Smatch reports:
+drivers/clocksource/timer-cadence-ttc.c:529 ttc_timer_probe()
+warn: 'timer_baseaddr' from of_iomap() not released on lines: 498,508,516.
+
+timer_baseaddr may have the problem of not being released after use,
+I replaced it with the devm_of_iomap() function and added the clk_put()
+function to cleanup the "clk_ce" and "clk_cs".
+
+Fixes: e932900a3279 ("arm: zynq: Use standard timer binding")
+Fixes: 70504f311d4b ("clocksource/drivers/cadence_ttc: Convert init function to return error")
+Signed-off-by: Feng Mingxi <m202271825@hust.edu.cn>
+Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
+Acked-by: Michal Simek <michal.simek@amd.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230425065611.702917-1-m202271825@hust.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clocksource/timer-cadence-ttc.c | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/clocksource/timer-cadence-ttc.c b/drivers/clocksource/timer-cadence-ttc.c
+index 4efd0cf3b602d..0d52e28fea4de 100644
+--- a/drivers/clocksource/timer-cadence-ttc.c
++++ b/drivers/clocksource/timer-cadence-ttc.c
+@@ -486,10 +486,10 @@ static int __init ttc_timer_probe(struct platform_device *pdev)
+ * and use it. Note that the event timer uses the interrupt and it's the
+ * 2nd TTC hence the irq_of_parse_and_map(,1)
+ */
+- timer_baseaddr = of_iomap(timer, 0);
+- if (!timer_baseaddr) {
++ timer_baseaddr = devm_of_iomap(&pdev->dev, timer, 0, NULL);
++ if (IS_ERR(timer_baseaddr)) {
+ pr_err("ERROR: invalid timer base address\n");
+- return -ENXIO;
++ return PTR_ERR(timer_baseaddr);
+ }
+
+ irq = irq_of_parse_and_map(timer, 1);
+@@ -513,20 +513,27 @@ static int __init ttc_timer_probe(struct platform_device *pdev)
+ clk_ce = of_clk_get(timer, clksel);
+ if (IS_ERR(clk_ce)) {
+ pr_err("ERROR: timer input clock not found\n");
+- return PTR_ERR(clk_ce);
++ ret = PTR_ERR(clk_ce);
++ goto put_clk_cs;
+ }
+
+ ret = ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width);
+ if (ret)
+- return ret;
++ goto put_clk_ce;
+
+ ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq);
+ if (ret)
+- return ret;
++ goto put_clk_ce;
+
+ pr_info("%pOFn #0 at %p, irq=%d\n", timer, timer_baseaddr, irq);
+
+ return 0;
++
++put_clk_ce:
++ clk_put(clk_ce);
++put_clk_cs:
++ clk_put(clk_cs);
++ return ret;
+ }
+
+ static const struct of_device_id ttc_timer_of_match[] = {
+--
+2.39.2
+
--- /dev/null
+From 3fc5d4fe5e4f956f6f3ecf247bac1e83dfbc4a61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 09:58:39 +0300
+Subject: cpufreq: intel_pstate: Fix energy_performance_preference for passive
+
+From: Tero Kristo <tero.kristo@linux.intel.com>
+
+[ Upstream commit 03f44ffb3d5be2fceda375d92c70ab6de4df7081 ]
+
+If the intel_pstate driver is set to passive mode, then writing the
+same value to the energy_performance_preference sysfs twice will fail.
+This is caused by the wrong return value used (index of the matched
+energy_perf_string), instead of the length of the passed in parameter.
+Fix by forcing the internal return value to zero when the same
+preference is passed in by user. This same issue is not present when
+active mode is used for the driver.
+
+Fixes: f6ebbcf08f37 ("cpufreq: intel_pstate: Implement passive mode with HWP enabled")
+Reported-by: Niklas Neronin <niklas.neronin@intel.com>
+Signed-off-by: Tero Kristo <tero.kristo@linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/intel_pstate.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index 48a4613cef1e1..ee9e96a1893c6 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -824,6 +824,8 @@ static ssize_t store_energy_performance_preference(
+ err = cpufreq_start_governor(policy);
+ if (!ret)
+ ret = err;
++ } else {
++ ret = 0;
+ }
+ }
+
+--
+2.39.2
+
--- /dev/null
+From b2346f2b6aa0f8051f2d0768f9cda7aebd8d51ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 May 2023 19:00:05 +0200
+Subject: crypto: jitter - correct health test during initialization
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Stephan Müller <smueller@chronox.de>
+
+[ Upstream commit d23659769ad1bf2cbafaa0efcbae20ef1a74f77e ]
+
+With the update of the permanent and intermittent health errors, the
+actual indicator for the health test indicates a potential error only
+for the one offending time stamp gathered in the current iteration
+round. The next iteration round will "overwrite" the health test result.
+
+Thus, the entropy collection loop in jent_gen_entropy checks for
+the health test failure upon each loop iteration. However, the
+initialization operation checked for the APT health test once for
+an APT window which implies it would not catch most errors.
+
+Thus, the check for all health errors is now invoked unconditionally
+during each loop iteration for the startup test.
+
+With the change, the error JENT_ERCT becomes unused as all health
+errors are only reported with the JENT_HEALTH return code. This
+allows the removal of the error indicator.
+
+Fixes: 3fde2fe99aa6 ("crypto: jitter - permanent and intermittent health errors"
+)
+Reported-by: Joachim Vandersmissen <git@jvdsn.com>
+Signed-off-by: Stephan Mueller <smueller@chronox.de>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/jitterentropy.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
+index 22f48bf4c6f57..227cedfa4f0ae 100644
+--- a/crypto/jitterentropy.c
++++ b/crypto/jitterentropy.c
+@@ -117,7 +117,6 @@ struct rand_data {
+ * zero). */
+ #define JENT_ESTUCK 8 /* Too many stuck results during init. */
+ #define JENT_EHEALTH 9 /* Health test failed during initialization */
+-#define JENT_ERCT 10 /* RCT failed during initialization */
+
+ /*
+ * The output n bits can receive more than n bits of min entropy, of course,
+@@ -762,14 +761,12 @@ int jent_entropy_init(void)
+ if ((nonstuck % JENT_APT_WINDOW_SIZE) == 0) {
+ jent_apt_reset(&ec,
+ delta & JENT_APT_WORD_MASK);
+- if (jent_health_failure(&ec))
+- return JENT_EHEALTH;
+ }
+ }
+
+- /* Validate RCT */
+- if (jent_rct_failure(&ec))
+- return JENT_ERCT;
++ /* Validate health test result */
++ if (jent_health_failure(&ec))
++ return JENT_EHEALTH;
+
+ /* test whether we have an increasing timer */
+ if (!(time2 > time))
+--
+2.39.2
+
--- /dev/null
+From 977e08a27e82bdf4c152fedeaafcf93ee0fe707f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 May 2023 10:33:04 +0200
+Subject: crypto: marvell/cesa - Fix type mismatch warning
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit efbc7764c4446566edb76ca05e903b5905673d2e ]
+
+Commit df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3") uncovered
+a type mismatch in cesa 3des support that leads to a memcpy beyond the
+end of a structure:
+
+In function 'fortify_memcpy_chk',
+ inlined from 'mv_cesa_des3_ede_setkey' at drivers/crypto/marvell/cesa/cipher.c:307:2:
+include/linux/fortify-string.h:583:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning]
+ 583 | __write_overflow_field(p_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is probably harmless as the actual data that is copied has the correct
+type, but clearly worth fixing nonetheless.
+
+Fixes: 4ada48397823 ("crypto: marvell/cesa - add Triple-DES support")
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Gustavo A. R. Silva" <gustavoars@kernel.org>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/marvell/cesa/cipher.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/marvell/cesa/cipher.c b/drivers/crypto/marvell/cesa/cipher.c
+index c6f2fa753b7c0..0f37dfd42d850 100644
+--- a/drivers/crypto/marvell/cesa/cipher.c
++++ b/drivers/crypto/marvell/cesa/cipher.c
+@@ -297,7 +297,7 @@ static int mv_cesa_des_setkey(struct crypto_skcipher *cipher, const u8 *key,
+ static int mv_cesa_des3_ede_setkey(struct crypto_skcipher *cipher,
+ const u8 *key, unsigned int len)
+ {
+- struct mv_cesa_des_ctx *ctx = crypto_skcipher_ctx(cipher);
++ struct mv_cesa_des3_ctx *ctx = crypto_skcipher_ctx(cipher);
+ int err;
+
+ err = verify_skcipher_des3_key(cipher, key);
+--
+2.39.2
+
--- /dev/null
+From f3eb8954a6020b4315437dfe7d1b20a7e5713832 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 May 2023 15:33:34 -0700
+Subject: crypto: nx - fix build warnings when DEBUG_FS is not enabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit b04b076fb56560b39d695ac3744db457e12278fd ]
+
+Fix build warnings when DEBUG_FS is not enabled by using an empty
+do-while loop instead of a value:
+
+In file included from ../drivers/crypto/nx/nx.c:27:
+../drivers/crypto/nx/nx.c: In function 'nx_register_algs':
+../drivers/crypto/nx/nx.h:173:33: warning: statement with no effect [-Wunused-value]
+ 173 | #define NX_DEBUGFS_INIT(drv) (0)
+../drivers/crypto/nx/nx.c:573:9: note: in expansion of macro 'NX_DEBUGFS_INIT'
+ 573 | NX_DEBUGFS_INIT(&nx_driver);
+../drivers/crypto/nx/nx.c: In function 'nx_remove':
+../drivers/crypto/nx/nx.h:174:33: warning: statement with no effect [-Wunused-value]
+ 174 | #define NX_DEBUGFS_FINI(drv) (0)
+../drivers/crypto/nx/nx.c:793:17: note: in expansion of macro 'NX_DEBUGFS_FINI'
+ 793 | NX_DEBUGFS_FINI(&nx_driver);
+
+Also, there is no need to build nx_debugfs.o when DEBUG_FS is not
+enabled, so change the Makefile to accommodate that.
+
+Fixes: ae0222b7289d ("powerpc/crypto: nx driver code supporting nx encryption")
+Fixes: aef7b31c8833 ("powerpc/crypto: Build files for the nx device driver")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Breno Leitão <leitao@debian.org>
+Cc: Nayna Jain <nayna@linux.ibm.com>
+Cc: Paulo Flabiano Smorigo <pfsmorigo@gmail.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: linux-crypto@vger.kernel.org
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Nicholas Piggin <npiggin@gmail.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: linuxppc-dev@lists.ozlabs.org
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/nx/Makefile | 2 +-
+ drivers/crypto/nx/nx.h | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/crypto/nx/Makefile b/drivers/crypto/nx/Makefile
+index d00181a26dd65..483cef62acee8 100644
+--- a/drivers/crypto/nx/Makefile
++++ b/drivers/crypto/nx/Makefile
+@@ -1,7 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+ obj-$(CONFIG_CRYPTO_DEV_NX_ENCRYPT) += nx-crypto.o
+ nx-crypto-objs := nx.o \
+- nx_debugfs.o \
+ nx-aes-cbc.o \
+ nx-aes-ecb.o \
+ nx-aes-gcm.o \
+@@ -11,6 +10,7 @@ nx-crypto-objs := nx.o \
+ nx-sha256.o \
+ nx-sha512.o
+
++nx-crypto-$(CONFIG_DEBUG_FS) += nx_debugfs.o
+ obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o nx-compress.o
+ obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o nx-compress.o
+ nx-compress-objs := nx-842.o
+diff --git a/drivers/crypto/nx/nx.h b/drivers/crypto/nx/nx.h
+index c6233173c612e..2697baebb6a35 100644
+--- a/drivers/crypto/nx/nx.h
++++ b/drivers/crypto/nx/nx.h
+@@ -170,8 +170,8 @@ struct nx_sg *nx_walk_and_build(struct nx_sg *, unsigned int,
+ void nx_debugfs_init(struct nx_crypto_driver *);
+ void nx_debugfs_fini(struct nx_crypto_driver *);
+ #else
+-#define NX_DEBUGFS_INIT(drv) (0)
+-#define NX_DEBUGFS_FINI(drv) (0)
++#define NX_DEBUGFS_INIT(drv) do {} while (0)
++#define NX_DEBUGFS_FINI(drv) do {} while (0)
+ #endif
+
+ #define NX_PAGE_NUM(x) ((u64)(x) & 0xfffffffffffff000ULL)
+--
+2.39.2
+
--- /dev/null
+From babde2c5448e1791a5dbcdd753f7ea30c3a62254 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 22:06:06 +0100
+Subject: crypto: qat - unmap buffer before free for DH
+
+From: Hareshx Sankar Raj <hareshx.sankar.raj@intel.com>
+
+[ Upstream commit eb7713f5ca97697b92f225127440d1525119b8de ]
+
+The callback function for DH frees the memory allocated for the
+destination buffer before unmapping it.
+This sequence is wrong.
+
+Change the cleanup sequence to unmap the buffer before freeing it.
+
+Fixes: 029aa4624a7f ("crypto: qat - remove dma_free_coherent() for DH")
+Signed-off-by: Hareshx Sankar Raj <hareshx.sankar.raj@intel.com>
+Co-developed-by: Bolemx Sivanagaleela <bolemx.sivanagaleela@intel.com>
+Signed-off-by: Bolemx Sivanagaleela <bolemx.sivanagaleela@intel.com>
+Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/qat/qat_common/qat_asym_algs.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c
+index 935a7e012946e..8806242469a06 100644
+--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
+@@ -170,15 +170,14 @@ static void qat_dh_cb(struct icp_qat_fw_pke_resp *resp)
+ }
+
+ areq->dst_len = req->ctx.dh->p_size;
++ dma_unmap_single(dev, req->out.dh.r, req->ctx.dh->p_size,
++ DMA_FROM_DEVICE);
+ if (req->dst_align) {
+ scatterwalk_map_and_copy(req->dst_align, areq->dst, 0,
+ areq->dst_len, 1);
+ kfree_sensitive(req->dst_align);
+ }
+
+- dma_unmap_single(dev, req->out.dh.r, req->ctx.dh->p_size,
+- DMA_FROM_DEVICE);
+-
+ dma_unmap_single(dev, req->phy_in, sizeof(struct qat_dh_input_params),
+ DMA_TO_DEVICE);
+ dma_unmap_single(dev, req->phy_out,
+--
+2.39.2
+
--- /dev/null
+From d647d75d760913e328e0da98467c297b2773763e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 22:06:07 +0100
+Subject: crypto: qat - unmap buffers before free for RSA
+
+From: Hareshx Sankar Raj <hareshx.sankar.raj@intel.com>
+
+[ Upstream commit d776b25495f2c71b9dbf1f5e53b642215ba72f3c ]
+
+The callback function for RSA frees the memory allocated for the source
+and destination buffers before unmapping them.
+This sequence is wrong.
+
+Change the cleanup sequence to unmap the buffers before freeing them.
+
+Fixes: 3dfaf0071ed7 ("crypto: qat - remove dma_free_coherent() for RSA")
+Signed-off-by: Hareshx Sankar Raj <hareshx.sankar.raj@intel.com>
+Co-developed-by: Bolemx Sivanagaleela <bolemx.sivanagaleela@intel.com>
+Signed-off-by: Bolemx Sivanagaleela <bolemx.sivanagaleela@intel.com>
+Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/qat/qat_common/qat_asym_algs.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c
+index 8806242469a06..4128200a90329 100644
+--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
+@@ -520,12 +520,14 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp)
+
+ err = (err == ICP_QAT_FW_COMN_STATUS_FLAG_OK) ? 0 : -EINVAL;
+
+- kfree_sensitive(req->src_align);
+-
+ dma_unmap_single(dev, req->in.rsa.enc.m, req->ctx.rsa->key_sz,
+ DMA_TO_DEVICE);
+
++ kfree_sensitive(req->src_align);
++
+ areq->dst_len = req->ctx.rsa->key_sz;
++ dma_unmap_single(dev, req->out.rsa.enc.c, req->ctx.rsa->key_sz,
++ DMA_FROM_DEVICE);
+ if (req->dst_align) {
+ scatterwalk_map_and_copy(req->dst_align, areq->dst, 0,
+ areq->dst_len, 1);
+@@ -533,9 +535,6 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp)
+ kfree_sensitive(req->dst_align);
+ }
+
+- dma_unmap_single(dev, req->out.rsa.enc.c, req->ctx.rsa->key_sz,
+- DMA_FROM_DEVICE);
+-
+ dma_unmap_single(dev, req->phy_in, sizeof(struct qat_rsa_input_params),
+ DMA_TO_DEVICE);
+ dma_unmap_single(dev, req->phy_out,
+--
+2.39.2
+
--- /dev/null
+From 9a080955d841a87deb907359ea5c374775a31b5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 18:24:39 -0700
+Subject: cxl/region: Fix state transitions after reset failure
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit adfe19738b71a893da62cb2e30bd6bdb4299ea67 ]
+
+Jonathan reports that failed attempts to reset a region (teardown its
+HDM decoder configuration) mistakenly advance the state of the region
+to "not committed". Revert to the previous state of the region on reset
+failure so that the reset can be re-attempted.
+
+Reported-by: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
+Closes: http://lore.kernel.org/r/20230316171441.0000205b@Huawei.com
+Fixes: 176baefb2eb5 ("cxl/hdm: Commit decoder state to hardware")
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/168696507968.3590522.14484000711718573626.stgit@dwillia2-xfh.jf.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/region.c | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index c1422167ab02b..1997bc1bf64aa 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -296,9 +296,11 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr,
+ if (rc)
+ return rc;
+
+- if (commit)
++ if (commit) {
+ rc = cxl_region_decode_commit(cxlr);
+- else {
++ if (rc == 0)
++ p->state = CXL_CONFIG_COMMIT;
++ } else {
+ p->state = CXL_CONFIG_RESET_PENDING;
+ up_write(&cxl_region_rwsem);
+ device_release_driver(&cxlr->dev);
+@@ -308,18 +310,20 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr,
+ * The lock was dropped, so need to revalidate that the reset is
+ * still pending.
+ */
+- if (p->state == CXL_CONFIG_RESET_PENDING)
++ if (p->state == CXL_CONFIG_RESET_PENDING) {
+ rc = cxl_region_decode_reset(cxlr, p->interleave_ways);
++ /*
++ * Revert to committed since there may still be active
++ * decoders associated with this region, or move forward
++ * to active to mark the reset successful
++ */
++ if (rc)
++ p->state = CXL_CONFIG_COMMIT;
++ else
++ p->state = CXL_CONFIG_ACTIVE;
++ }
+ }
+
+- if (rc)
+- goto out;
+-
+- if (commit)
+- p->state = CXL_CONFIG_COMMIT;
+- else if (p->state == CXL_CONFIG_RESET_PENDING)
+- p->state = CXL_CONFIG_ACTIVE;
+-
+ out:
+ up_write(&cxl_region_rwsem);
+
+--
+2.39.2
+
--- /dev/null
+From efed36881a583c305bceaebe7dbb055edd141ff9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 18:24:34 -0700
+Subject: cxl/region: Flag partially torn down regions as unusable
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 2ab47045ac96a605e3037d479a7d5854570ee5bf ]
+
+cxl_region_decode_reset() walks all the decoders associated with a given
+region and disables them. Due to decoder ordering rules it is possible
+that a switch in the topology notices that a given decoder can not be
+shutdown before another region with a higher HPA is shutdown first. That
+can leave the region in a partially committed state.
+
+Capture that state in a new CXL_REGION_F_NEEDS_RESET flag and require
+that a successful cxl_region_decode_reset() attempt must be completed
+before cxl_region_probe() accepts the region.
+
+This is a corollary for the bug that Jonathan identified in "CXL/region
+: commit reset of out of order region appears to succeed." [1].
+
+Cc: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
+Link: http://lore.kernel.org/r/20230316171441.0000205b@Huawei.com [1]
+Fixes: 176baefb2eb5 ("cxl/hdm: Commit decoder state to hardware")
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/168696507423.3590522.16254212607926684429.stgit@dwillia2-xfh.jf.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/region.c | 12 ++++++++++++
+ drivers/cxl/cxl.h | 8 ++++++++
+ 2 files changed, 20 insertions(+)
+
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index 3b3bbd98e99d5..c1422167ab02b 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -182,14 +182,19 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
+ rc = cxld->reset(cxld);
+ if (rc)
+ return rc;
++ set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
+ }
+
+ endpoint_reset:
+ rc = cxled->cxld.reset(&cxled->cxld);
+ if (rc)
+ return rc;
++ set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
+ }
+
++ /* all decoders associated with this region have been torn down */
++ clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
++
+ return 0;
+ }
+
+@@ -2740,6 +2745,13 @@ static int cxl_region_probe(struct device *dev)
+ goto out;
+ }
+
++ if (test_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags)) {
++ dev_err(&cxlr->dev,
++ "failed to activate, re-commit region and retry\n");
++ rc = -ENXIO;
++ goto out;
++ }
++
+ /*
+ * From this point on any path that changes the region's state away from
+ * CXL_CONFIG_COMMIT is also responsible for releasing the driver.
+diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
+index 70ab8fcd0377c..dcebe48bb5bb5 100644
+--- a/drivers/cxl/cxl.h
++++ b/drivers/cxl/cxl.h
+@@ -469,6 +469,14 @@ struct cxl_region_params {
+ */
+ #define CXL_REGION_F_AUTO 0
+
++/*
++ * Require that a committed region successfully complete a teardown once
++ * any of its associated decoders have been torn down. This maintains
++ * the commit state for the region since there are committed decoders,
++ * but blocks cxl_region_probe().
++ */
++#define CXL_REGION_F_NEEDS_RESET 1
++
+ /**
+ * struct cxl_region - CXL region
+ * @dev: This region's device
+--
+2.39.2
+
--- /dev/null
+From ce2e21d844afd459c3b252b0c2aa53edaaceb52d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 18:24:28 -0700
+Subject: cxl/region: Move cache invalidation before region teardown, and
+ before setup
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit d1257d098a5a38753a0736a50db0a26a62377ad7 ]
+
+Vikram raised a concern with the theoretical case of a CPU sending
+MemClnEvict to a device that is not prepared to receive. MemClnEvict is
+a message that is sent after a CPU has taken ownership of a cacheline
+from accelerator memory (HDM-DB). In the case of hotplug or HDM decoder
+reconfiguration it is possible that the CPU is holding old contents for
+a new device that has taken over the physical address range being cached
+by the CPU.
+
+To avoid this scenario, invalidate caches prior to tearing down an HDM
+decoder configuration.
+
+Now, this poses another problem that it is possible for something to
+speculate into that space while the decode configuration is still up, so
+to close that gap also invalidate prior to establish new contents behind
+a given physical address range.
+
+With this change the cache invalidation is now explicit and need not be
+checked in cxl_region_probe(), and that obviates the need for
+CXL_REGION_F_INCOHERENT.
+
+Cc: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
+Fixes: d18bc74aced6 ("cxl/region: Manage CPU caches relative to DPA invalidation events")
+Reported-by: Vikram Sethi <vsethi@nvidia.com>
+Closes: http://lore.kernel.org/r/BYAPR12MB33364B5EB908BF7239BB996BBD53A@BYAPR12MB3336.namprd12.prod.outlook.com
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/168696506886.3590522.4597053660991916591.stgit@dwillia2-xfh.jf.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/region.c | 66 ++++++++++++++++++++++-----------------
+ drivers/cxl/cxl.h | 8 +----
+ 2 files changed, 38 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index b2fd67fcebfb5..3b3bbd98e99d5 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -125,10 +125,38 @@ static struct cxl_region_ref *cxl_rr_load(struct cxl_port *port,
+ return xa_load(&port->regions, (unsigned long)cxlr);
+ }
+
++static int cxl_region_invalidate_memregion(struct cxl_region *cxlr)
++{
++ if (!cpu_cache_has_invalidate_memregion()) {
++ if (IS_ENABLED(CONFIG_CXL_REGION_INVALIDATION_TEST)) {
++ dev_warn_once(
++ &cxlr->dev,
++ "Bypassing cpu_cache_invalidate_memregion() for testing!\n");
++ return 0;
++ } else {
++ dev_err(&cxlr->dev,
++ "Failed to synchronize CPU cache state\n");
++ return -ENXIO;
++ }
++ }
++
++ cpu_cache_invalidate_memregion(IORES_DESC_CXL);
++ return 0;
++}
++
+ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
+ {
+ struct cxl_region_params *p = &cxlr->params;
+- int i;
++ int i, rc = 0;
++
++ /*
++ * Before region teardown attempt to flush, and if the flush
++ * fails cancel the region teardown for data consistency
++ * concerns
++ */
++ rc = cxl_region_invalidate_memregion(cxlr);
++ if (rc)
++ return rc;
+
+ for (i = count - 1; i >= 0; i--) {
+ struct cxl_endpoint_decoder *cxled = p->targets[i];
+@@ -136,7 +164,6 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
+ struct cxl_port *iter = cxled_to_port(cxled);
+ struct cxl_dev_state *cxlds = cxlmd->cxlds;
+ struct cxl_ep *ep;
+- int rc = 0;
+
+ if (cxlds->rcd)
+ goto endpoint_reset;
+@@ -256,6 +283,14 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr,
+ goto out;
+ }
+
++ /*
++ * Invalidate caches before region setup to drop any speculative
++ * consumption of this address space
++ */
++ rc = cxl_region_invalidate_memregion(cxlr);
++ if (rc)
++ return rc;
++
+ if (commit)
+ rc = cxl_region_decode_commit(cxlr);
+ else {
+@@ -1674,7 +1709,6 @@ static int cxl_region_attach(struct cxl_region *cxlr,
+ if (rc)
+ goto err_decrement;
+ p->state = CXL_CONFIG_ACTIVE;
+- set_bit(CXL_REGION_F_INCOHERENT, &cxlr->flags);
+ }
+
+ cxled->cxld.interleave_ways = p->interleave_ways;
+@@ -2679,30 +2713,6 @@ int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled)
+ }
+ EXPORT_SYMBOL_NS_GPL(cxl_add_to_region, CXL);
+
+-static int cxl_region_invalidate_memregion(struct cxl_region *cxlr)
+-{
+- if (!test_bit(CXL_REGION_F_INCOHERENT, &cxlr->flags))
+- return 0;
+-
+- if (!cpu_cache_has_invalidate_memregion()) {
+- if (IS_ENABLED(CONFIG_CXL_REGION_INVALIDATION_TEST)) {
+- dev_warn_once(
+- &cxlr->dev,
+- "Bypassing cpu_cache_invalidate_memregion() for testing!\n");
+- clear_bit(CXL_REGION_F_INCOHERENT, &cxlr->flags);
+- return 0;
+- } else {
+- dev_err(&cxlr->dev,
+- "Failed to synchronize CPU cache state\n");
+- return -ENXIO;
+- }
+- }
+-
+- cpu_cache_invalidate_memregion(IORES_DESC_CXL);
+- clear_bit(CXL_REGION_F_INCOHERENT, &cxlr->flags);
+- return 0;
+-}
+-
+ static int is_system_ram(struct resource *res, void *arg)
+ {
+ struct cxl_region *cxlr = arg;
+@@ -2730,8 +2740,6 @@ static int cxl_region_probe(struct device *dev)
+ goto out;
+ }
+
+- rc = cxl_region_invalidate_memregion(cxlr);
+-
+ /*
+ * From this point on any path that changes the region's state away from
+ * CXL_CONFIG_COMMIT is also responsible for releasing the driver.
+diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
+index 044a92d9813e2..70ab8fcd0377c 100644
+--- a/drivers/cxl/cxl.h
++++ b/drivers/cxl/cxl.h
+@@ -462,18 +462,12 @@ struct cxl_region_params {
+ int nr_targets;
+ };
+
+-/*
+- * Flag whether this region needs to have its HPA span synchronized with
+- * CPU cache state at region activation time.
+- */
+-#define CXL_REGION_F_INCOHERENT 0
+-
+ /*
+ * Indicate whether this region has been assembled by autodetection or
+ * userspace assembly. Prevent endpoint decoders outside of automatic
+ * detection from being added to the region.
+ */
+-#define CXL_REGION_F_AUTO 1
++#define CXL_REGION_F_AUTO 0
+
+ /**
+ * struct cxl_region - CXL region
+--
+2.39.2
+
--- /dev/null
+From 866e38880824024f86b2897d47b68ca507a9af45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 23:13:54 -0700
+Subject: dax: Fix dax_mapping_release() use after free
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 6d24b170a9db0456f577b1ab01226a2254c016a8 ]
+
+A CONFIG_DEBUG_KOBJECT_RELEASE test of removing a device-dax region
+provider (like modprobe -r dax_hmem) yields:
+
+ kobject: 'mapping0' (ffff93eb460e8800): kobject_release, parent 0000000000000000 (delayed 2000)
+ [..]
+ DEBUG_LOCKS_WARN_ON(1)
+ WARNING: CPU: 23 PID: 282 at kernel/locking/lockdep.c:232 __lock_acquire+0x9fc/0x2260
+ [..]
+ RIP: 0010:__lock_acquire+0x9fc/0x2260
+ [..]
+ Call Trace:
+ <TASK>
+ [..]
+ lock_acquire+0xd4/0x2c0
+ ? ida_free+0x62/0x130
+ _raw_spin_lock_irqsave+0x47/0x70
+ ? ida_free+0x62/0x130
+ ida_free+0x62/0x130
+ dax_mapping_release+0x1f/0x30
+ device_release+0x36/0x90
+ kobject_delayed_cleanup+0x46/0x150
+
+Due to attempting ida_free() on an ida object that has already been
+freed. Devices typically only hold a reference on their parent while
+registered. If a child needs a parent object to complete its release it
+needs to hold a reference that it drops from its release callback.
+Arrange for a dax_mapping to pin its parent dev_dax instance until
+dax_mapping_release().
+
+Fixes: 0b07ce872a9e ("device-dax: introduce 'mapping' devices")
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Link: https://lore.kernel.org/r/168577283412.1672036.16111545266174261446.stgit@dwillia2-xfh.jf.intel.com
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Fan Ni <fan.ni@samsung.com>
+Reviewed-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dax/bus.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c
+index 227800053309f..aee695f86b445 100644
+--- a/drivers/dax/bus.c
++++ b/drivers/dax/bus.c
+@@ -635,10 +635,12 @@ EXPORT_SYMBOL_GPL(alloc_dax_region);
+ static void dax_mapping_release(struct device *dev)
+ {
+ struct dax_mapping *mapping = to_dax_mapping(dev);
+- struct dev_dax *dev_dax = to_dev_dax(dev->parent);
++ struct device *parent = dev->parent;
++ struct dev_dax *dev_dax = to_dev_dax(parent);
+
+ ida_free(&dev_dax->ida, mapping->id);
+ kfree(mapping);
++ put_device(parent);
+ }
+
+ static void unregister_dax_mapping(void *data)
+@@ -778,6 +780,7 @@ static int devm_register_dax_mapping(struct dev_dax *dev_dax, int range_id)
+ dev = &mapping->dev;
+ device_initialize(dev);
+ dev->parent = &dev_dax->dev;
++ get_device(dev->parent);
+ dev->type = &dax_mapping_type;
+ dev_set_name(dev, "mapping%d", mapping->id);
+ rc = device_add(dev);
+--
+2.39.2
+
--- /dev/null
+From ed7abe23998cfa5e6c9ab33db468c191091a06de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 23:14:05 -0700
+Subject: dax: Introduce alloc_dev_dax_id()
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 70aab281e18c68a1284bc387de127c2fc0bed3f8 ]
+
+The reference counting of dax_region objects is needlessly complicated,
+has lead to confusion [1], and has hidden a bug [2]. Towards cleaning up
+that mess introduce alloc_dev_dax_id() to minimize the holding of a
+dax_region reference to only what dev_dax_release() needs, the
+dax_region->ida.
+
+Part of the reason for the mess was the design to dereference a
+dax_region in all cases in free_dev_dax_id() even if the id was
+statically assigned by the upper level dax_region driver. Remove the
+need to call "is_static(dax_region)" by tracking whether the id is
+dynamic directly in the dev_dax instance itself.
+
+With that flag the dax_region pinning and release per dev_dax instance
+can move to alloc_dev_dax_id() and free_dev_dax_id() respectively.
+
+A follow-on cleanup address the unnecessary references in the dax_region
+setup and drivers.
+
+Fixes: 0f3da14a4f05 ("device-dax: introduce 'seed' devices")
+Link: http://lore.kernel.org/r/20221203095858.612027-1-liuyongqiang13@huawei.com [1]
+Link: http://lore.kernel.org/r/3cf0890b-4eb0-e70e-cd9c-2ecc3d496263@hpe.com [2]
+Reported-by: Yongqiang Liu <liuyongqiang13@huawei.com>
+Reported-by: Paul Cassella <cassella@hpe.com>
+Reported-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Link: https://lore.kernel.org/r/168577284563.1672036.13493034988900989554.stgit@dwillia2-xfh.jf.intel.com
+Reviewed-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dax/bus.c | 56 ++++++++++++++++++++++++---------------
+ drivers/dax/dax-private.h | 4 ++-
+ 2 files changed, 37 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c
+index aee695f86b445..e7c61358564e1 100644
+--- a/drivers/dax/bus.c
++++ b/drivers/dax/bus.c
+@@ -446,18 +446,34 @@ static void unregister_dev_dax(void *dev)
+ put_device(dev);
+ }
+
++static void dax_region_free(struct kref *kref)
++{
++ struct dax_region *dax_region;
++
++ dax_region = container_of(kref, struct dax_region, kref);
++ kfree(dax_region);
++}
++
++void dax_region_put(struct dax_region *dax_region)
++{
++ kref_put(&dax_region->kref, dax_region_free);
++}
++EXPORT_SYMBOL_GPL(dax_region_put);
++
+ /* a return value >= 0 indicates this invocation invalidated the id */
+ static int __free_dev_dax_id(struct dev_dax *dev_dax)
+ {
+- struct dax_region *dax_region = dev_dax->region;
+ struct device *dev = &dev_dax->dev;
++ struct dax_region *dax_region;
+ int rc = dev_dax->id;
+
+ device_lock_assert(dev);
+
+- if (is_static(dax_region) || dev_dax->id < 0)
++ if (!dev_dax->dyn_id || dev_dax->id < 0)
+ return -1;
++ dax_region = dev_dax->region;
+ ida_free(&dax_region->ida, dev_dax->id);
++ dax_region_put(dax_region);
+ dev_dax->id = -1;
+ return rc;
+ }
+@@ -473,6 +489,20 @@ static int free_dev_dax_id(struct dev_dax *dev_dax)
+ return rc;
+ }
+
++static int alloc_dev_dax_id(struct dev_dax *dev_dax)
++{
++ struct dax_region *dax_region = dev_dax->region;
++ int id;
++
++ id = ida_alloc(&dax_region->ida, GFP_KERNEL);
++ if (id < 0)
++ return id;
++ kref_get(&dax_region->kref);
++ dev_dax->dyn_id = true;
++ dev_dax->id = id;
++ return id;
++}
++
+ static ssize_t delete_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
+ {
+@@ -560,20 +590,6 @@ static const struct attribute_group *dax_region_attribute_groups[] = {
+ NULL,
+ };
+
+-static void dax_region_free(struct kref *kref)
+-{
+- struct dax_region *dax_region;
+-
+- dax_region = container_of(kref, struct dax_region, kref);
+- kfree(dax_region);
+-}
+-
+-void dax_region_put(struct dax_region *dax_region)
+-{
+- kref_put(&dax_region->kref, dax_region_free);
+-}
+-EXPORT_SYMBOL_GPL(dax_region_put);
+-
+ static void dax_region_unregister(void *region)
+ {
+ struct dax_region *dax_region = region;
+@@ -1298,12 +1314,10 @@ static const struct attribute_group *dax_attribute_groups[] = {
+ static void dev_dax_release(struct device *dev)
+ {
+ struct dev_dax *dev_dax = to_dev_dax(dev);
+- struct dax_region *dax_region = dev_dax->region;
+ struct dax_device *dax_dev = dev_dax->dax_dev;
+
+ put_dax(dax_dev);
+ free_dev_dax_id(dev_dax);
+- dax_region_put(dax_region);
+ kfree(dev_dax->pgmap);
+ kfree(dev_dax);
+ }
+@@ -1327,6 +1341,7 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data)
+ if (!dev_dax)
+ return ERR_PTR(-ENOMEM);
+
++ dev_dax->region = dax_region;
+ if (is_static(dax_region)) {
+ if (dev_WARN_ONCE(parent, data->id < 0,
+ "dynamic id specified to static region\n")) {
+@@ -1342,13 +1357,11 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data)
+ goto err_id;
+ }
+
+- rc = ida_alloc(&dax_region->ida, GFP_KERNEL);
++ rc = alloc_dev_dax_id(dev_dax);
+ if (rc < 0)
+ goto err_id;
+- dev_dax->id = rc;
+ }
+
+- dev_dax->region = dax_region;
+ dev = &dev_dax->dev;
+ device_initialize(dev);
+ dev_set_name(dev, "dax%d.%d", dax_region->id, dev_dax->id);
+@@ -1389,7 +1402,6 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data)
+ dev_dax->target_node = dax_region->target_node;
+ dev_dax->align = dax_region->align;
+ ida_init(&dev_dax->ida);
+- kref_get(&dax_region->kref);
+
+ inode = dax_inode(dax_dev);
+ dev->devt = inode->i_rdev;
+diff --git a/drivers/dax/dax-private.h b/drivers/dax/dax-private.h
+index 1c974b7caae6e..afcada6fd2eda 100644
+--- a/drivers/dax/dax-private.h
++++ b/drivers/dax/dax-private.h
+@@ -52,7 +52,8 @@ struct dax_mapping {
+ * @region - parent region
+ * @dax_dev - core dax functionality
+ * @target_node: effective numa node if dev_dax memory range is onlined
+- * @id: ida allocated id
++ * @dyn_id: is this a dynamic or statically created instance
++ * @id: ida allocated id when the dax_region is not static
+ * @ida: mapping id allocator
+ * @dev - device core
+ * @pgmap - pgmap for memmap setup / lifetime (driver owned)
+@@ -64,6 +65,7 @@ struct dev_dax {
+ struct dax_device *dax_dev;
+ unsigned int align;
+ int target_node;
++ bool dyn_id;
+ int id;
+ struct ida ida;
+ struct device dev;
+--
+2.39.2
+
--- /dev/null
+From 6df23197314e3f6ec71dc74dadbf1e4b5a7f0a70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 21:20:25 +0530
+Subject: dax/kmem: Pass valid argument to memory_group_register_static
+
+From: Tarun Sahu <tsahu@linux.ibm.com>
+
+[ Upstream commit 46e66dab8565f742374e9cc4ff7d35f344d774e2 ]
+
+memory_group_register_static takes maximum number of pages as the argument
+while dev_dax_kmem_probe passes total_len (in bytes) as the argument.
+
+IIUC, I don't see any crash/panic impact as such. As,
+memory_group_register_static just set the max_pages limit which is used in
+auto_movable_zone_for_pfn to determine the zone.
+
+which might cause these condition to behave differently,
+
+This will be true always so jump will happen to kernel_zone
+ ...
+ if (!auto_movable_can_online_movable(NUMA_NO_NODE, group, nr_pages))
+ goto kernel_zone;
+
+ ...
+ kernel_zone:
+ return default_kernel_zone_for_pfn(nid, pfn, nr_pages);
+
+Here, In below, zone_intersects compare range will be larger as nr_pages
+will be higher (derived from total_len passed in dev_dax_kmem_probe).
+
+ ...
+ static struct zone *default_kernel_zone_for_pfn(int nid, unsigned long start_pfn,
+ unsigned long nr_pages)
+ {
+ struct pglist_data *pgdat = NODE_DATA(nid);
+ int zid;
+
+ for (zid = 0; zid < ZONE_NORMAL; zid++) {
+ struct zone *zone = &pgdat->node_zones[zid];
+
+ if (zone_intersects(zone, start_pfn, nr_pages))
+ return zone;
+ }
+
+ return &pgdat->node_zones[ZONE_NORMAL];
+ }
+
+Incorrect zone will be returned here, which in later time might cause bigger
+problem.
+
+Fixes: eedf634aac3b ("dax/kmem: use a single static memory group for a single probed unit")
+Signed-off-by: Tarun Sahu <tsahu@linux.ibm.com>
+Link: https://lore.kernel.org/r/20230621155025.370672-1-tsahu@linux.ibm.com
+Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
+Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dax/kmem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/dax/kmem.c b/drivers/dax/kmem.c
+index 7b36db6f1cbdc..898ca95057547 100644
+--- a/drivers/dax/kmem.c
++++ b/drivers/dax/kmem.c
+@@ -99,7 +99,7 @@ static int dev_dax_kmem_probe(struct dev_dax *dev_dax)
+ if (!data->res_name)
+ goto err_res_name;
+
+- rc = memory_group_register_static(numa_node, total_len);
++ rc = memory_group_register_static(numa_node, PFN_UP(total_len));
+ if (rc < 0)
+ goto err_reg_mgid;
+ data->mgid = rc;
+--
+2.39.2
+
--- /dev/null
+From 45ced4b5a6df4b814030e68b268386cbe68eb7db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Apr 2023 13:44:54 +0300
+Subject: driver: soc: xilinx: use _safe loop iterator to avoid a use after
+ free
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit c58da0ba3e5c86e51e2c1557afaf6f71e00c4533 ]
+
+The hash_for_each_possible() loop dereferences "eve_data" to get the
+next item on the list. However the loop frees eve_data so it leads to
+a use after free. Use hash_for_each_possible_safe() instead.
+
+Fixes: c7fdb2404f66 ("drivers: soc: xilinx: add xilinx event management driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/761e0e4a-4caf-4a71-8f47-1c6ad908a848@kili.mountain
+Signed-off-by: Michal Simek <michal.simek@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/xilinx/xlnx_event_manager.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/xilinx/xlnx_event_manager.c b/drivers/soc/xilinx/xlnx_event_manager.c
+index c76381899ef49..f9d9b82b562da 100644
+--- a/drivers/soc/xilinx/xlnx_event_manager.c
++++ b/drivers/soc/xilinx/xlnx_event_manager.c
+@@ -192,11 +192,12 @@ static int xlnx_remove_cb_for_suspend(event_cb_func_t cb_fun)
+ struct registered_event_data *eve_data;
+ struct agent_cb *cb_pos;
+ struct agent_cb *cb_next;
++ struct hlist_node *tmp;
+
+ is_need_to_unregister = false;
+
+ /* Check for existing entry in hash table for given cb_type */
+- hash_for_each_possible(reg_driver_map, eve_data, hentry, PM_INIT_SUSPEND_CB) {
++ hash_for_each_possible_safe(reg_driver_map, eve_data, tmp, hentry, PM_INIT_SUSPEND_CB) {
+ if (eve_data->cb_type == PM_INIT_SUSPEND_CB) {
+ /* Delete the list of callback */
+ list_for_each_entry_safe(cb_pos, cb_next, &eve_data->cb_list_head, list) {
+@@ -228,11 +229,12 @@ static int xlnx_remove_cb_for_notify_event(const u32 node_id, const u32 event,
+ u64 key = ((u64)node_id << 32U) | (u64)event;
+ struct agent_cb *cb_pos;
+ struct agent_cb *cb_next;
++ struct hlist_node *tmp;
+
+ is_need_to_unregister = false;
+
+ /* Check for existing entry in hash table for given key id */
+- hash_for_each_possible(reg_driver_map, eve_data, hentry, key) {
++ hash_for_each_possible_safe(reg_driver_map, eve_data, tmp, hentry, key) {
+ if (eve_data->key == key) {
+ /* Delete the list of callback */
+ list_for_each_entry_safe(cb_pos, cb_next, &eve_data->cb_list_head, list) {
+--
+2.39.2
+
--- /dev/null
+From 552ef24c1faf12f84789980d69ffff62af7965b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Jun 2023 12:04:14 +0300
+Subject: drivers: meson: secure-pwrc: always enable DMA domain
+
+From: Alexey Romanov <avromanov@sberdevices.ru>
+
+[ Upstream commit 0bb4644d583789c97e74d3e3047189f0c59c4742 ]
+
+Starting from commit e45f243409db ("firmware: meson_sm:
+populate platform devices from sm device tree data") pwrc
+is probed successfully and disables unused pwr domains.
+By A1 SoC family design, any TEE requires DMA pwr domain
+always enabled.
+
+Fixes: b3dde5013e13 ("soc: amlogic: Add support for Secure power domains controller")
+Signed-off-by: Alexey Romanov <avromanov@sberdevices.ru>
+Acked-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20230610090414.90529-1-avromanov@sberdevices.ru
+[narmstrong: added fixes tag]
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/amlogic/meson-secure-pwrc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soc/amlogic/meson-secure-pwrc.c b/drivers/soc/amlogic/meson-secure-pwrc.c
+index e935187635267..25b4b71df9b89 100644
+--- a/drivers/soc/amlogic/meson-secure-pwrc.c
++++ b/drivers/soc/amlogic/meson-secure-pwrc.c
+@@ -105,7 +105,7 @@ static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = {
+ SEC_PD(ACODEC, 0),
+ SEC_PD(AUDIO, 0),
+ SEC_PD(OTP, 0),
+- SEC_PD(DMA, 0),
++ SEC_PD(DMA, GENPD_FLAG_ALWAYS_ON | GENPD_FLAG_IRQ_SAFE),
+ SEC_PD(SD_EMMC, 0),
+ SEC_PD(RAMA, 0),
+ /* SRAMB is used as ATF runtime memory, and should be always on */
+--
+2.39.2
+
--- /dev/null
+From 5c5ce54518296305bfe4c00d0b2f73ffa9b2e4c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Jun 2023 19:43:26 +0800
+Subject: drivers/perf: hisi: Don't migrate perf to the CPU going to teardown
+
+From: Junhao He <hejunhao3@huawei.com>
+
+[ Upstream commit 7a6a9f1c5a0a875a421db798d4b2ee022dc1ee1a ]
+
+The driver needs to migrate the perf context if the current using CPU going
+to teardown. By the time calling the cpuhp::teardown() callback the
+cpu_online_mask() hasn't updated yet and still includes the CPU going to
+teardown. In current driver's implementation we may migrate the context
+to the teardown CPU and leads to the below calltrace:
+
+...
+[ 368.104662][ T932] task:cpuhp/0 state:D stack: 0 pid: 15 ppid: 2 flags:0x00000008
+[ 368.113699][ T932] Call trace:
+[ 368.116834][ T932] __switch_to+0x7c/0xbc
+[ 368.120924][ T932] __schedule+0x338/0x6f0
+[ 368.125098][ T932] schedule+0x50/0xe0
+[ 368.128926][ T932] schedule_preempt_disabled+0x18/0x24
+[ 368.134229][ T932] __mutex_lock.constprop.0+0x1d4/0x5dc
+[ 368.139617][ T932] __mutex_lock_slowpath+0x1c/0x30
+[ 368.144573][ T932] mutex_lock+0x50/0x60
+[ 368.148579][ T932] perf_pmu_migrate_context+0x84/0x2b0
+[ 368.153884][ T932] hisi_pcie_pmu_offline_cpu+0x90/0xe0 [hisi_pcie_pmu]
+[ 368.160579][ T932] cpuhp_invoke_callback+0x2a0/0x650
+[ 368.165707][ T932] cpuhp_thread_fun+0xe4/0x190
+[ 368.170316][ T932] smpboot_thread_fn+0x15c/0x1a0
+[ 368.175099][ T932] kthread+0x108/0x13c
+[ 368.179012][ T932] ret_from_fork+0x10/0x18
+...
+
+Use function cpumask_any_but() to find one correct active cpu to fixes
+this issue.
+
+Fixes: 8404b0fbc7fb ("drivers/perf: hisi: Add driver for HiSilicon PCIe PMU")
+Signed-off-by: Junhao He <hejunhao3@huawei.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Yicong Yang <yangyicong@hisilicon.com>
+Acked-by: Mark Rutland <mark.rutland@arm.com>
+Link: https://lore.kernel.org/r/20230608114326.27649-1-hejunhao3@huawei.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/hisilicon/hisi_pcie_pmu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
+index 6fee0b6e163bb..e10fc7cb9493a 100644
+--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
++++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
+@@ -683,7 +683,7 @@ static int hisi_pcie_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
+
+ pcie_pmu->on_cpu = -1;
+ /* Choose a new CPU from all online cpus. */
+- target = cpumask_first(cpu_online_mask);
++ target = cpumask_any_but(cpu_online_mask, cpu);
+ if (target >= nr_cpu_ids) {
+ pci_err(pcie_pmu->pdev, "There is no CPU to set\n");
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From 165675856db79b7657d75d0314907eadf7e06a37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 07:40:44 -0300
+Subject: drm: Add fixed-point helper to get rounded integer values
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+[ Upstream commit 8b25320887d7feac98875546ea0f521628b745bb ]
+
+Create a new fixed-point helper to allow us to return the rounded value
+of our fixed point value.
+
+[v2]:
+ * Create the function drm_fixp2int_round() (Melissa Wen).
+[v3]:
+ * Use drm_fixp2int() instead of shifting manually (Arthur Grillo).
+
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Reviewed-by: Arthur Grillo <arthurgrillo@riseup.net>
+Signed-off-by: Maíra Canal <mairacanal@riseup.net>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230512104044.65034-1-mcanal@igalia.com
+Stable-dep-of: ab87f558dcfb ("drm/vkms: Fix RGB565 pixel conversion")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/drm/drm_fixed.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h
+index 255645c1f9a89..6ea339d5de088 100644
+--- a/include/drm/drm_fixed.h
++++ b/include/drm/drm_fixed.h
+@@ -71,6 +71,7 @@ static inline u32 dfixed_div(fixed20_12 A, fixed20_12 B)
+ }
+
+ #define DRM_FIXED_POINT 32
++#define DRM_FIXED_POINT_HALF 16
+ #define DRM_FIXED_ONE (1ULL << DRM_FIXED_POINT)
+ #define DRM_FIXED_DECIMAL_MASK (DRM_FIXED_ONE - 1)
+ #define DRM_FIXED_DIGITS_MASK (~DRM_FIXED_DECIMAL_MASK)
+@@ -87,6 +88,11 @@ static inline int drm_fixp2int(s64 a)
+ return ((s64)a) >> DRM_FIXED_POINT;
+ }
+
++static inline int drm_fixp2int_round(s64 a)
++{
++ return drm_fixp2int(a + (1 << (DRM_FIXED_POINT_HALF - 1)));
++}
++
+ static inline int drm_fixp2int_ceil(s64 a)
+ {
+ if (a > 0)
+--
+2.39.2
+
--- /dev/null
+From 5dd0f66518ce7f011ef7a6a1bce998b484acd6a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2020 11:49:16 -0400
+Subject: drm/amd/display: Add logging for display MALL refresh setting
+
+From: Wesley Chalmers <Wesley.Chalmers@amd.com>
+
+[ Upstream commit cd8f067a46d34dee3188da184912ae3d64d98444 ]
+
+[WHY]
+Add log entry for when display refresh from MALL
+settings are sent to SMU.
+
+Fixes: 1664641ea946 ("drm/amd/display: Add logger for SMU msg")
+Signed-off-by: Wesley Chalmers <Wesley.Chalmers@amd.com>
+Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c
+index 1fbf1c105dc12..bdbf183066981 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c
+@@ -312,6 +312,9 @@ void dcn30_smu_set_display_refresh_from_mall(struct clk_mgr_internal *clk_mgr, b
+ /* bits 8:7 for cache timer scale, bits 6:1 for cache timer delay, bit 0 = 1 for enable, = 0 for disable */
+ uint32_t param = (cache_timer_scale << 7) | (cache_timer_delay << 1) | (enable ? 1 : 0);
+
++ smu_print("SMU Set display refresh from mall: enable = %d, cache_timer_delay = %d, cache_timer_scale = %d\n",
++ enable, cache_timer_delay, cache_timer_scale);
++
+ dcn30_smu_send_msg_with_param(clk_mgr,
+ DALSMC_MSG_SetDisplayRefreshFromMall, param, NULL);
+ }
+--
+2.39.2
+
--- /dev/null
+From 4de9a6468a0dcf5ed88fedef9cabacd70234e352 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 May 2019 13:21:48 -0400
+Subject: drm/amd/display: Explicitly specify update type per plane info change
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit 710cc1e7cd461446a9325c9bd1e9a54daa462952 ]
+
+[Why]
+The bit for flip addr is being set causing the determination for
+FAST vs MEDIUM to always return MEDIUM when plane info is provided
+as a surface update. This causes extreme stuttering for the typical
+atomic update path on Linux.
+
+[How]
+Don't use update_flags->raw for determining FAST vs MEDIUM. It's too
+fragile to changes like this.
+
+Explicitly specify the update type per update flag instead. It's not
+as clever as checking the bits itself but at least it's correct.
+
+Fixes: aa5fdb1ab5b6 ("drm/amd/display: Explicitly specify update type per plane info change")
+Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 9ec0a343efadb..e6e26fe1be0f8 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -2540,9 +2540,6 @@ static enum surface_update_type det_surface_update(const struct dc *dc,
+ enum surface_update_type overall_type = UPDATE_TYPE_FAST;
+ union surface_update_flags *update_flags = &u->surface->update_flags;
+
+- if (u->flip_addr)
+- update_flags->bits.addr_update = 1;
+-
+ if (!is_surface_in_context(context, u->surface) || u->surface->force_full_update) {
+ update_flags->raw = 0xFFFFFFFF;
+ return UPDATE_TYPE_FULL;
+--
+2.39.2
+
--- /dev/null
+From 7fb417e79fccdf234f4c66e608a8512e36798e81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 23:35:08 +0200
+Subject: drm/amd/display: Fix a test CalculatePrefetchSchedule()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 960e27a5741cd3001996ff6ddfb3eb0ed3a4909d ]
+
+It is likely Height was expected here, instead of Width.
+
+Test the correct variable.
+
+Fixes: 17529ea2acfa ("drm/amd/display: Optimizations for DML math")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
+index b7c2844d0cbee..f294f2f8c75bc 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
+@@ -810,7 +810,7 @@ static bool CalculatePrefetchSchedule(
+ *swath_width_chroma_ub = dml_ceil(SwathWidthY / 2 - 1, myPipe->BlockWidth256BytesC) + myPipe->BlockWidth256BytesC;
+ } else {
+ *swath_width_luma_ub = dml_ceil(SwathWidthY - 1, myPipe->BlockHeight256BytesY) + myPipe->BlockHeight256BytesY;
+- if (myPipe->BlockWidth256BytesC > 0)
++ if (myPipe->BlockHeight256BytesC > 0)
+ *swath_width_chroma_ub = dml_ceil(SwathWidthY / 2 - 1, myPipe->BlockHeight256BytesC) + myPipe->BlockHeight256BytesC;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From be06773eebfb387b848d6d48a90d0d1e70a4e735 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 23:41:11 +0200
+Subject: drm/amd/display: Fix a test dml32_rq_dlg_get_rq_reg()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit bafc31166aa7df5fa26ae0ad8196d1717e6cdea9 ]
+
+It is likely p1_min_meta_chunk_bytes was expected here, instead of
+min_meta_chunk_bytes.
+
+Test the correct variable.
+
+Fixes: dda4fb85e433 ("drm/amd/display: DML changes for DCN32/321")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+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 395ae8761980f..9ba6cb67655f4 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
+@@ -116,7 +116,7 @@ void dml32_rq_dlg_get_rq_reg(display_rq_regs_st *rq_regs,
+ else
+ rq_regs->rq_regs_l.min_meta_chunk_size = dml_log2(min_meta_chunk_bytes) - 6 + 1;
+
+- if (min_meta_chunk_bytes == 0)
++ if (p1_min_meta_chunk_bytes == 0)
+ rq_regs->rq_regs_c.min_meta_chunk_size = 0;
+ else
+ rq_regs->rq_regs_c.min_meta_chunk_size = dml_log2(p1_min_meta_chunk_bytes) - 6 + 1;
+--
+2.39.2
+
--- /dev/null
+From 5cc832e1cf31bc68a4b2e66dfc14c319471d2ada Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 14:39:46 -0400
+Subject: drm/amd/display: Fix artifacting on eDP panels when engaging freesync
+ video mode
+
+From: Aurabindo Pillai <aurabindo.pillai@amd.com>
+
+[ Upstream commit b18f05a0666aecd5cb19c26a8305bcfa4e9d6502 ]
+
+[Why]
+When freesync video mode is enabled, switching resolution from native
+mode to one of the freesync video compatible modes can trigger continous
+artifacts on some eDP panels when running under KDE. The articating can be seen in the
+attached bug report.
+
+[How]
+Fix this by restricting updates that require full commit by using the same checks
+for stream and scaling changes in the the enable pass of dm_update_crtc_state()
+along with the check for compatible timings for freesync vide mode.
+
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2162
+Fixes: da5e14909776 ("drm/amd/display: Fix hang when skipping modeset")
+Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+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 2cbd6949804f5..261dbd417c2f8 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -9276,6 +9276,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
+
+ /* Now check if we should set freesync video mode */
+ if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream &&
++ dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
++ dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream) &&
+ is_timing_unchanged_for_freesync(new_crtc_state,
+ old_crtc_state)) {
+ new_crtc_state->mode_changed = false;
+--
+2.39.2
+
--- /dev/null
+From b45bb361c0c37000cd5560b4fdcda29da86d7be3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Apr 2023 00:07:18 +0200
+Subject: drm/amd/display: fix is_timing_changed() prototype
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 3306ba4b60b2f3d9ac6bddc587a4d702e1ba2224 ]
+
+Three functions in the amdgpu display driver cause -Wmissing-prototype
+warnings:
+
+drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_resource.c:1858:6: error: no previous prototype for 'is_timing_changed' [-Werror=missing-prototypes]
+
+is_timing_changed() is actually meant to be a global symbol, but needs
+a proper name and prototype.
+
+Fixes: 17ce8a6907f7 ("drm/amd/display: Add dsc pre-validation in atomic check")
+Reviewed-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 5 ++---
+ drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 6 +++---
+ drivers/gpu/drm/amd/display/dc/dc.h | 3 +++
+ 3 files changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+index 3da519957f6c8..0096614f2a8be 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+@@ -48,8 +48,7 @@
+ #endif
+
+ #include "dc/dcn20/dcn20_resource.h"
+-bool is_timing_changed(struct dc_stream_state *cur_stream,
+- struct dc_stream_state *new_stream);
++
+ #define PEAK_FACTOR_X1000 1006
+
+ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
+@@ -1426,7 +1425,7 @@ int pre_validate_dsc(struct drm_atomic_state *state,
+ struct dc_stream_state *stream = dm_state->context->streams[i];
+
+ if (local_dc_state->streams[i] &&
+- is_timing_changed(stream, local_dc_state->streams[i])) {
++ dc_is_timing_changed(stream, local_dc_state->streams[i])) {
+ DRM_INFO_ONCE("crtc[%d] needs mode_changed\n", i);
+ } else {
+ int ind = find_crtc_index_in_state_by_stream(state, stream);
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+index 986de684b078e..7b0fd0dc31b34 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+@@ -1878,7 +1878,7 @@ bool dc_add_all_planes_for_stream(
+ return add_all_planes_for_stream(dc, stream, &set, 1, context);
+ }
+
+-bool is_timing_changed(struct dc_stream_state *cur_stream,
++bool dc_is_timing_changed(struct dc_stream_state *cur_stream,
+ struct dc_stream_state *new_stream)
+ {
+ if (cur_stream == NULL)
+@@ -1903,7 +1903,7 @@ static bool are_stream_backends_same(
+ if (stream_a == NULL || stream_b == NULL)
+ return false;
+
+- if (is_timing_changed(stream_a, stream_b))
++ if (dc_is_timing_changed(stream_a, stream_b))
+ return false;
+
+ if (stream_a->signal != stream_b->signal)
+@@ -3527,7 +3527,7 @@ bool pipe_need_reprogram(
+ if (pipe_ctx_old->stream_res.stream_enc != pipe_ctx->stream_res.stream_enc)
+ return true;
+
+- if (is_timing_changed(pipe_ctx_old->stream, pipe_ctx->stream))
++ if (dc_is_timing_changed(pipe_ctx_old->stream, pipe_ctx->stream))
+ return true;
+
+ if (pipe_ctx_old->stream->dpms_off != pipe_ctx->stream->dpms_off)
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index 3fb868f2f6f5b..9307442dc2258 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -2223,4 +2223,7 @@ void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc,
+ /* Disable acc mode Interfaces */
+ void dc_disable_accelerated_mode(struct dc *dc);
+
++bool dc_is_timing_changed(struct dc_stream_state *cur_stream,
++ struct dc_stream_state *new_stream);
++
+ #endif /* DC_INTERFACE_H_ */
+--
+2.39.2
+
--- /dev/null
+From 7708700ac5d84b17ea1ade09950630f0fca88a65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 14:06:43 +0530
+Subject: drm/amdgpu: Fix memcpy() in sienna_cichlid_append_powerplay_table
+ function.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit d50dc746ff72b9c48812dac3344fa87fbde940a3 ]
+
+Fixes the following gcc with W=1:
+
+In file included from ./include/linux/string.h:253,
+ from ./include/linux/bitmap.h:11,
+ from ./include/linux/cpumask.h:12,
+ from ./arch/x86/include/asm/cpumask.h:5,
+ from ./arch/x86/include/asm/msr.h:11,
+ from ./arch/x86/include/asm/processor.h:22,
+ from ./arch/x86/include/asm/cpufeature.h:5,
+ from ./arch/x86/include/asm/thread_info.h:53,
+ from ./include/linux/thread_info.h:60,
+ from ./arch/x86/include/asm/preempt.h:7,
+ from ./include/linux/preempt.h:78,
+ from ./include/linux/spinlock.h:56,
+ from ./include/linux/mmzone.h:8,
+ from ./include/linux/gfp.h:7,
+ from ./include/linux/firmware.h:7,
+ from drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu11/sienna_cichlid_ppt.c:26:
+In function ‘fortify_memcpy_chk’,
+ inlined from ‘sienna_cichlid_append_powerplay_table’ at drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu11/sienna_cichlid_ppt.c:444:2,
+ inlined from ‘sienna_cichlid_setup_pptable’ at drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu11/sienna_cichlid_ppt.c:506:8,
+ inlined from ‘sienna_cichlid_setup_pptable’ at drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu11/sienna_cichlid_ppt.c:494:12:
+./include/linux/fortify-string.h:413:4: warning: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning]
+ 413 | __read_overflow2_field(q_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+the compiler complains about the size calculation in the memcpy() -
+"sizeof(*smc_dpm_table) - sizeof(smc_dpm_table->table_header)" is much
+larger than what fits into table_member.
+
+Hence, reuse 'smu_memcpy_trailing' for nv1x
+
+Fixes: 7077b19a38240 ("drm/amd/pm: use macro to get pptable members")
+Suggested-by: Evan Quan <Evan.Quan@amd.com>
+Cc: Evan Quan <Evan.Quan@amd.com>
+Cc: Chengming Gui <Jack.Gui@amd.com>
+Cc: Christian König <christian.koenig@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Evan Quan <evan.quan@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+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 85d53597eb07a..f7ed3e655e397 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
+@@ -431,7 +431,13 @@ static int sienna_cichlid_append_powerplay_table(struct smu_context *smu)
+ {
+ struct atom_smc_dpm_info_v4_9 *smc_dpm_table;
+ int index, ret;
+- I2cControllerConfig_t *table_member;
++ PPTable_beige_goby_t *ppt_beige_goby;
++ PPTable_t *ppt;
++
++ if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13))
++ ppt_beige_goby = smu->smu_table.driver_pptable;
++ else
++ ppt = smu->smu_table.driver_pptable;
+
+ index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
+ smc_dpm_info);
+@@ -440,9 +446,13 @@ static int sienna_cichlid_append_powerplay_table(struct smu_context *smu)
+ (uint8_t **)&smc_dpm_table);
+ if (ret)
+ return ret;
+- GET_PPTABLE_MEMBER(I2cControllers, &table_member);
+- memcpy(table_member, smc_dpm_table->I2cControllers,
+- sizeof(*smc_dpm_table) - sizeof(smc_dpm_table->table_header));
++
++ if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13))
++ smu_memcpy_trailing(ppt_beige_goby, I2cControllers, BoardReserved,
++ smc_dpm_table, I2cControllers);
++ else
++ smu_memcpy_trailing(ppt, I2cControllers, BoardReserved,
++ smc_dpm_table, I2cControllers);
+
+ return 0;
+ }
+--
+2.39.2
+
--- /dev/null
+From a078a8a42c712b8c42826e3ef9e4b6602e254c70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Jun 2023 06:19:15 -0400
+Subject: drm/amdgpu: Fix usage of UMC fill record in RAS
+
+From: Luben Tuikov <luben.tuikov@amd.com>
+
+[ Upstream commit 71344a718a9fda8c551cdc4381d354f9a9907f6f ]
+
+The fixed commit listed in the Fixes tag below, introduced a bug in
+amdgpu_ras.c::amdgpu_reserve_page_direct(), in that when introducing the new
+amdgpu_umc_fill_error_record() and internally in that new function the physical
+address (argument "uint64_t retired_page"--wrong name) is right-shifted by
+AMDGPU_GPU_PAGE_SHIFT. Thus, in amdgpu_reserve_page_direct() when we pass
+"address" to that new function, we should NOT right-shift it, since this
+results, erroneously, in the page address to be 0 for first
+2^(2*AMDGPU_GPU_PAGE_SHIFT) memory addresses.
+
+This commit fixes this bug.
+
+Cc: Tao Zhou <tao.zhou1@amd.com>
+Cc: Hawking Zhang <Hawking.Zhang@amd.com>
+Cc: Alex Deucher <Alexander.Deucher@amd.com>
+Fixes: 400013b268cb ("drm/amdgpu: add umc_fill_error_record to make code more simple")
+Signed-off-by: Luben Tuikov <luben.tuikov@amd.com>
+Link: https://lore.kernel.org/r/20230610113536.10621-1-luben.tuikov@amd.com
+Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+index 63dfcc98152d5..b3daca6372a90 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+@@ -170,8 +170,7 @@ static int amdgpu_reserve_page_direct(struct amdgpu_device *adev, uint64_t addre
+
+ memset(&err_rec, 0x0, sizeof(struct eeprom_table_record));
+ err_data.err_addr = &err_rec;
+- amdgpu_umc_fill_error_record(&err_data, address,
+- (address >> AMDGPU_GPU_PAGE_SHIFT), 0, 0);
++ amdgpu_umc_fill_error_record(&err_data, address, address, 0, 0);
+
+ if (amdgpu_bad_page_threshold != 0) {
+ amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
+--
+2.39.2
+
--- /dev/null
+From 32608cd675cc43d9c230101e0c290ab02e1a907e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 May 2023 04:23:14 -0700
+Subject: drm/amdkfd: Fix potential deallocation of previously deallocated
+ memory.
+
+From: Daniil Dulov <d.dulov@aladdin.ru>
+
+[ Upstream commit cabbdea1f1861098991768d7bbf5a49ed1608213 ]
+
+Pointer mqd_mem_obj can be deallocated in kfd_gtt_sa_allocate().
+The function then returns non-zero value, which causes the second deallocation.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: d1f8f0d17d40 ("drm/amdkfd: Move non-sdma mqd allocation out of init_mqd")
+Signed-off-by: Daniil Dulov <d.dulov@aladdin.ru>
+Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
+Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
+index 0778e587a2d68..eaf084acb706f 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
+@@ -115,18 +115,19 @@ static struct kfd_mem_obj *allocate_mqd(struct kfd_dev *kfd,
+ &(mqd_mem_obj->gtt_mem),
+ &(mqd_mem_obj->gpu_addr),
+ (void *)&(mqd_mem_obj->cpu_ptr), true);
++
++ if (retval) {
++ kfree(mqd_mem_obj);
++ return NULL;
++ }
+ } else {
+ retval = kfd_gtt_sa_allocate(kfd, sizeof(struct v9_mqd),
+ &mqd_mem_obj);
+- }
+-
+- if (retval) {
+- kfree(mqd_mem_obj);
+- return NULL;
++ if (retval)
++ return NULL;
+ }
+
+ return mqd_mem_obj;
+-
+ }
+
+ static void init_mqd(struct mqd_manager *mm, void **mqd,
+--
+2.39.2
+
--- /dev/null
+From 57c8b030bf429ee3d7ed2863a42eed13cd31d6bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 15:39:02 -0400
+Subject: drm/bridge: anx7625: Prevent endless probe loop
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 1464e48d69ab7a50a377c9d39f5e5eb3cee2722e ]
+
+During probe, the driver registers i2c dummy devices and populates the
+aux bus, which registers a device for the panel. After doing that, the
+driver can still defer probe if needed. This ordering of operations is
+troublesome however, because the deferred probe work will retry probing
+all pending devices every time a new device is registered. Therefore, if
+modules need to be loaded in order to satisfy the dependencies for this
+driver to complete probe, the kernel will stall, since it'll keep trying
+to probe the anx7625 driver, but never succeed, given that modules would
+only be loaded after the deferred probe work completes.
+
+Two changes are required to avoid this issue:
+* Move of_find_mipi_dsi_host_by_node(), which can defer probe, to before
+ anx7625_register_i2c_dummy_clients() and
+ devm_of_dp_aux_populate_ep_devices(), which register devices.
+* Make use of the done_probing callback when populating the aux bus,
+ so that the bridge registration is only done after the panel is
+ probed. This is required because the panel might need to defer probe,
+ but the aux bus population needs the i2c dummy devices working, so
+ this call couldn't just be moved to an earlier point in probe.
+ One caveat is that if the panel is described outside the aux bus, the
+ probe loop issue can still happen, but we don't have a way to avoid
+ it in that case since there's no callback available.
+
+With this patch applied, it's possible to boot on
+mt8192-asurada-spherion with
+
+CONFIG_DRM_ANALOGIX_ANX7625=y
+CONFIG_MTK_MMSYS=m
+CONFIG_BACKLIGHT_PWM=y
+
+and also with
+
+CONFIG_DRM_ANALOGIX_ANX7625=y
+CONFIG_MTK_MMSYS=y
+CONFIG_BACKLIGHT_PWM=m
+
+Fixes: adca62ec370c ("drm/bridge: anx7625: Support reading edid through aux channel")
+Fixes: 269332997a16 ("drm/bridge: anx7625: Return -EPROBE_DEFER if the dsi host was not found")
+Reported-by: "kernelci.org bot" <bot@kernelci.org>
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230518193902.891121-1-nfraprado@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/analogix/anx7625.c | 128 +++++++++++++++-------
+ 1 file changed, 88 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
+index 6846199a2ee14..9e387c3e9b696 100644
+--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
+@@ -1687,6 +1687,14 @@ static int anx7625_parse_dt(struct device *dev,
+ if (of_property_read_bool(np, "analogix,audio-enable"))
+ pdata->audio_en = 1;
+
++ return 0;
++}
++
++static int anx7625_parse_dt_panel(struct device *dev,
++ struct anx7625_platform_data *pdata)
++{
++ struct device_node *np = dev->of_node;
++
+ pdata->panel_bridge = devm_drm_of_get_bridge(dev, np, 1, 0);
+ if (IS_ERR(pdata->panel_bridge)) {
+ if (PTR_ERR(pdata->panel_bridge) == -ENODEV) {
+@@ -2032,7 +2040,7 @@ static int anx7625_register_audio(struct device *dev, struct anx7625_data *ctx)
+ return 0;
+ }
+
+-static int anx7625_attach_dsi(struct anx7625_data *ctx)
++static int anx7625_setup_dsi_device(struct anx7625_data *ctx)
+ {
+ struct mipi_dsi_device *dsi;
+ struct device *dev = &ctx->client->dev;
+@@ -2042,9 +2050,6 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx)
+ .channel = 0,
+ .node = NULL,
+ };
+- int ret;
+-
+- DRM_DEV_DEBUG_DRIVER(dev, "attach dsi\n");
+
+ host = of_find_mipi_dsi_host_by_node(ctx->pdata.mipi_host_node);
+ if (!host) {
+@@ -2065,14 +2070,24 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx)
+ MIPI_DSI_MODE_VIDEO_HSE |
+ MIPI_DSI_HS_PKT_END_ALIGNED;
+
+- ret = devm_mipi_dsi_attach(dev, dsi);
++ ctx->dsi = dsi;
++
++ return 0;
++}
++
++static int anx7625_attach_dsi(struct anx7625_data *ctx)
++{
++ struct device *dev = &ctx->client->dev;
++ int ret;
++
++ DRM_DEV_DEBUG_DRIVER(dev, "attach dsi\n");
++
++ ret = devm_mipi_dsi_attach(dev, ctx->dsi);
+ if (ret) {
+ DRM_DEV_ERROR(dev, "fail to attach dsi to host.\n");
+ return ret;
+ }
+
+- ctx->dsi = dsi;
+-
+ DRM_DEV_DEBUG_DRIVER(dev, "attach dsi succeeded.\n");
+
+ return 0;
+@@ -2560,6 +2575,40 @@ static void anx7625_runtime_disable(void *data)
+ pm_runtime_disable(data);
+ }
+
++static int anx7625_link_bridge(struct drm_dp_aux *aux)
++{
++ struct anx7625_data *platform = container_of(aux, struct anx7625_data, aux);
++ struct device *dev = aux->dev;
++ int ret;
++
++ ret = anx7625_parse_dt_panel(dev, &platform->pdata);
++ if (ret) {
++ DRM_DEV_ERROR(dev, "fail to parse DT for panel : %d\n", ret);
++ return ret;
++ }
++
++ platform->bridge.funcs = &anx7625_bridge_funcs;
++ platform->bridge.of_node = dev->of_node;
++ if (!anx7625_of_panel_on_aux_bus(dev))
++ platform->bridge.ops |= DRM_BRIDGE_OP_EDID;
++ if (!platform->pdata.panel_bridge)
++ platform->bridge.ops |= DRM_BRIDGE_OP_HPD |
++ DRM_BRIDGE_OP_DETECT;
++ platform->bridge.type = platform->pdata.panel_bridge ?
++ DRM_MODE_CONNECTOR_eDP :
++ DRM_MODE_CONNECTOR_DisplayPort;
++
++ drm_bridge_add(&platform->bridge);
++
++ if (!platform->pdata.is_dpi) {
++ ret = anx7625_attach_dsi(platform);
++ if (ret)
++ drm_bridge_remove(&platform->bridge);
++ }
++
++ return ret;
++}
++
+ static int anx7625_i2c_probe(struct i2c_client *client)
+ {
+ struct anx7625_data *platform;
+@@ -2634,6 +2683,24 @@ static int anx7625_i2c_probe(struct i2c_client *client)
+ platform->aux.wait_hpd_asserted = anx7625_wait_hpd_asserted;
+ drm_dp_aux_init(&platform->aux);
+
++ ret = anx7625_parse_dt(dev, pdata);
++ if (ret) {
++ if (ret != -EPROBE_DEFER)
++ DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret);
++ goto free_wq;
++ }
++
++ if (!platform->pdata.is_dpi) {
++ ret = anx7625_setup_dsi_device(platform);
++ if (ret < 0)
++ goto free_wq;
++ }
++
++ /*
++ * Registering the i2c devices will retrigger deferred probe, so it
++ * needs to be done after calls that might return EPROBE_DEFER,
++ * otherwise we can get an infinite loop.
++ */
+ if (anx7625_register_i2c_dummy_clients(platform, client) != 0) {
+ ret = -ENOMEM;
+ DRM_DEV_ERROR(dev, "fail to reserve I2C bus.\n");
+@@ -2648,13 +2715,21 @@ static int anx7625_i2c_probe(struct i2c_client *client)
+ if (ret)
+ goto free_wq;
+
+- devm_of_dp_aux_populate_ep_devices(&platform->aux);
+-
+- ret = anx7625_parse_dt(dev, pdata);
++ /*
++ * Populating the aux bus will retrigger deferred probe, so it needs to
++ * be done after calls that might return EPROBE_DEFER, otherwise we can
++ * get an infinite loop.
++ */
++ ret = devm_of_dp_aux_populate_bus(&platform->aux, anx7625_link_bridge);
+ if (ret) {
+- if (ret != -EPROBE_DEFER)
+- DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret);
+- goto free_wq;
++ if (ret != -ENODEV) {
++ DRM_DEV_ERROR(dev, "failed to populate aux bus : %d\n", ret);
++ goto free_wq;
++ }
++
++ ret = anx7625_link_bridge(&platform->aux);
++ if (ret)
++ goto free_wq;
+ }
+
+ if (!platform->pdata.low_power_mode) {
+@@ -2667,27 +2742,6 @@ static int anx7625_i2c_probe(struct i2c_client *client)
+ if (platform->pdata.intp_irq)
+ queue_work(platform->workqueue, &platform->work);
+
+- platform->bridge.funcs = &anx7625_bridge_funcs;
+- platform->bridge.of_node = client->dev.of_node;
+- if (!anx7625_of_panel_on_aux_bus(&client->dev))
+- platform->bridge.ops |= DRM_BRIDGE_OP_EDID;
+- if (!platform->pdata.panel_bridge)
+- platform->bridge.ops |= DRM_BRIDGE_OP_HPD |
+- DRM_BRIDGE_OP_DETECT;
+- platform->bridge.type = platform->pdata.panel_bridge ?
+- DRM_MODE_CONNECTOR_eDP :
+- DRM_MODE_CONNECTOR_DisplayPort;
+-
+- drm_bridge_add(&platform->bridge);
+-
+- if (!platform->pdata.is_dpi) {
+- ret = anx7625_attach_dsi(platform);
+- if (ret) {
+- DRM_DEV_ERROR(dev, "Fail to attach to dsi : %d\n", ret);
+- goto unregister_bridge;
+- }
+- }
+-
+ if (platform->pdata.audio_en)
+ anx7625_register_audio(dev, platform);
+
+@@ -2695,12 +2749,6 @@ static int anx7625_i2c_probe(struct i2c_client *client)
+
+ return 0;
+
+-unregister_bridge:
+- drm_bridge_remove(&platform->bridge);
+-
+- if (!platform->pdata.low_power_mode)
+- pm_runtime_put_sync_suspend(&client->dev);
+-
+ free_wq:
+ if (platform->workqueue)
+ destroy_workqueue(platform->workqueue);
+--
+2.39.2
+
--- /dev/null
+From c6e6fdcce0729a12297efbff63c0617e586a9a7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Apr 2023 17:30:46 +0200
+Subject: drm/bridge: it6505: Move a variable assignment behind a null pointer
+ check in receive_timing_debugfs_show()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Markus Elfring <elfring@users.sourceforge.net>
+
+[ Upstream commit 0be05a75de2916421e88e0d64b001984f54df0bd ]
+
+The address of a data structure member was determined before
+a corresponding null pointer check in the implementation of
+the function “receive_timing_debugfs_show”.
+
+Thus avoid the risk for undefined behaviour by moving the assignment
+for the variable “vid” behind the null pointer check.
+
+This issue was detected by using the Coccinelle software.
+
+Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver")
+Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
+Link: https://patchwork.freedesktop.org/patch/msgid/fa69384f-1485-142b-c4ee-3df54ac68a89@web.de
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/ite-it6505.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
+index bc451b2a77c28..32ea61b79965e 100644
+--- a/drivers/gpu/drm/bridge/ite-it6505.c
++++ b/drivers/gpu/drm/bridge/ite-it6505.c
+@@ -3195,7 +3195,7 @@ static ssize_t receive_timing_debugfs_show(struct file *file, char __user *buf,
+ size_t len, loff_t *ppos)
+ {
+ struct it6505 *it6505 = file->private_data;
+- struct drm_display_mode *vid = &it6505->video_info;
++ struct drm_display_mode *vid;
+ u8 read_buf[READ_BUFFER_SIZE];
+ u8 *str = read_buf, *end = read_buf + READ_BUFFER_SIZE;
+ ssize_t ret, count;
+@@ -3204,6 +3204,7 @@ static ssize_t receive_timing_debugfs_show(struct file *file, char __user *buf,
+ return -ENODEV;
+
+ it6505_calc_video_info(it6505);
++ vid = &it6505->video_info;
+ str += scnprintf(str, end - str, "---video timing---\n");
+ str += scnprintf(str, end - str, "PCLK:%d.%03dMHz\n",
+ vid->clock / 1000, vid->clock % 1000);
+--
+2.39.2
+
--- /dev/null
+From cffd0902351f51ee8edd1917db234461c75a6e9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 14:21:06 +0200
+Subject: drm/bridge: tc358767: Switch to devm MIPI-DSI helpers
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit f47d6140b7a4c858d82d263e7577ff6fb5279a9c ]
+
+DSI device registering and attaching needs to be undone upon
+deregistration. This fixes module unload/load.
+
+Fixes: bbfd3190b656 ("drm/bridge: tc358767: Add DSI-to-DPI mode support")
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230517122107.1766673-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358767.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
+index 6d16ec45ea614..232e23a1bfcc0 100644
+--- a/drivers/gpu/drm/bridge/tc358767.c
++++ b/drivers/gpu/drm/bridge/tc358767.c
+@@ -1890,7 +1890,7 @@ static int tc_mipi_dsi_host_attach(struct tc_data *tc)
+ if (dsi_lanes < 0)
+ return dsi_lanes;
+
+- dsi = mipi_dsi_device_register_full(host, &info);
++ dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
+ if (IS_ERR(dsi))
+ return dev_err_probe(dev, PTR_ERR(dsi),
+ "failed to create dsi device\n");
+@@ -1901,7 +1901,7 @@ static int tc_mipi_dsi_host_attach(struct tc_data *tc)
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
+
+- ret = mipi_dsi_attach(dsi);
++ ret = devm_mipi_dsi_attach(dev, dsi);
+ if (ret < 0) {
+ dev_err(dev, "failed to attach dsi to host: %d\n", ret);
+ return ret;
+--
+2.39.2
+
--- /dev/null
+From 639a38d2bc87053ae7116fa9490336d92cdce040 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Mar 2023 11:59:41 +0200
+Subject: drm/bridge: tc358768: Add atomic_get_input_bus_fmts() implementation
+
+From: Francesco Dolcini <francesco.dolcini@toradex.com>
+
+[ Upstream commit cec5ccef85bd0128cf895612de54a9d21d2015d0 ]
+
+Add atomic_get_input_bus_fmts() implementation, tc358768 has a parallel
+RGB input interface with the actual bus format depending on the amount
+of parallel input data lines.
+
+Without this change when the tc358768 is used with less than 24bit the
+color mapping is completely wrong.
+
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230330095941.428122-7-francesco@dolcini.it
+Stable-dep-of: ee18698e212b ("drm/bridge: tc358768: fix TCLK_TRAILCNT computation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358768.c | 44 +++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index aff400c360662..487bfe33edc88 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -9,6 +9,7 @@
+ #include <linux/gpio/consumer.h>
+ #include <linux/i2c.h>
+ #include <linux/kernel.h>
++#include <linux/media-bus-format.h>
+ #include <linux/module.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
+@@ -918,6 +919,44 @@ static void tc358768_bridge_enable(struct drm_bridge *bridge)
+ }
+ }
+
++#define MAX_INPUT_SEL_FORMATS 1
++
++static u32 *
++tc358768_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
++ struct drm_bridge_state *bridge_state,
++ struct drm_crtc_state *crtc_state,
++ struct drm_connector_state *conn_state,
++ u32 output_fmt,
++ unsigned int *num_input_fmts)
++{
++ struct tc358768_priv *priv = bridge_to_tc358768(bridge);
++ u32 *input_fmts;
++
++ *num_input_fmts = 0;
++
++ input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
++ GFP_KERNEL);
++ if (!input_fmts)
++ return NULL;
++
++ switch (priv->pd_lines) {
++ case 16:
++ input_fmts[0] = MEDIA_BUS_FMT_RGB565_1X16;
++ break;
++ case 18:
++ input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X18;
++ break;
++ default:
++ case 24:
++ input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
++ break;
++ };
++
++ *num_input_fmts = MAX_INPUT_SEL_FORMATS;
++
++ return input_fmts;
++}
++
+ static const struct drm_bridge_funcs tc358768_bridge_funcs = {
+ .attach = tc358768_bridge_attach,
+ .mode_valid = tc358768_bridge_mode_valid,
+@@ -925,6 +964,11 @@ static const struct drm_bridge_funcs tc358768_bridge_funcs = {
+ .enable = tc358768_bridge_enable,
+ .disable = tc358768_bridge_disable,
+ .post_disable = tc358768_bridge_post_disable,
++
++ .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,
++ .atomic_get_input_bus_fmts = tc358768_atomic_get_input_bus_fmts,
+ };
+
+ static const struct drm_bridge_timings default_tc358768_timings = {
+--
+2.39.2
+
--- /dev/null
+From ef9c33a55ee0ef0379c4e4cfc547b46f170cafe0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Apr 2023 16:29:26 +0200
+Subject: drm/bridge: tc358768: always enable HS video mode
+
+From: Francesco Dolcini <francesco.dolcini@toradex.com>
+
+[ Upstream commit 75a8aeac2573ab258c53676eba9b3796ea691988 ]
+
+Always enable HS video mode setting the TXMD bit, without this change no
+video output is present with DSI sinks that are setting
+MIPI_DSI_MODE_LPM flag (tested with LT8912B DSI-HDMI bridge).
+
+Previously the driver was enabling HS mode only when the DSI sink was
+not explicitly setting the MIPI_DSI_MODE_LPM, however this is not
+correct.
+
+The MIPI_DSI_MODE_LPM is supposed to indicate that the sink is willing
+to receive data in low power mode, however clearing the
+TC358768_DSI_CONTROL_TXMD bit will make the TC358768 send video in
+LP mode that is not the intended behavior.
+
+Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-francesco@dolcini.it
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358768.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index 7c0cbe84611b9..8f349bf4fc32f 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -866,8 +866,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+ val = TC358768_DSI_CONFW_MODE_SET | TC358768_DSI_CONFW_ADDR_DSI_CONTROL;
+ val |= (dsi_dev->lanes - 1) << 1;
+
+- if (!(dsi_dev->mode_flags & MIPI_DSI_MODE_LPM))
+- val |= TC358768_DSI_CONTROL_TXMD;
++ val |= TC358768_DSI_CONTROL_TXMD;
+
+ if (!(mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
+ val |= TC358768_DSI_CONTROL_HSCKMD;
+--
+2.39.2
+
--- /dev/null
+From 92b5457badd6c37402d126c3f729b539423d38b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Apr 2023 16:29:27 +0200
+Subject: drm/bridge: tc358768: fix PLL parameters computation
+
+From: Francesco Dolcini <francesco.dolcini@toradex.com>
+
+[ Upstream commit 6a4020b4c63911977aaf8047f904a300d15de739 ]
+
+According to Toshiba documentation the PLL input clock after the divider
+should be not less than 4MHz, fix the PLL parameters computation
+accordingly.
+
+Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-francesco@dolcini.it
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358768.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index 8f349bf4fc32f..e9e3f9e02bba0 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -334,13 +334,17 @@ static int tc358768_calc_pll(struct tc358768_priv *priv,
+ u32 fbd;
+
+ for (fbd = 0; fbd < 512; ++fbd) {
+- u32 pll, diff;
++ u32 pll, diff, pll_in;
+
+ pll = (u32)div_u64((u64)refclk * (fbd + 1), divisor);
+
+ if (pll >= max_pll || pll < min_pll)
+ continue;
+
++ pll_in = (u32)div_u64((u64)refclk, prd + 1);
++ if (pll_in < 4000000)
++ continue;
++
+ diff = max(pll, target_pll) - min(pll, target_pll);
+
+ if (diff < best_diff) {
+--
+2.39.2
+
--- /dev/null
+From 4b3222097c29a791a6cc944bfdb271ffa0b61293 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Apr 2023 16:29:28 +0200
+Subject: drm/bridge: tc358768: fix PLL target frequency
+
+From: Francesco Dolcini <francesco.dolcini@toradex.com>
+
+[ Upstream commit ffd2e4bbea626d565b9817312b0fcfb382fecb88 ]
+
+Correctly compute the PLL target frequency, the current formula works
+correctly only when the input bus width is 24bit, actually to properly
+compute the PLL target frequency what is relevant is the bits-per-pixel
+on the DSI link.
+
+No regression expected since the DSI format is currently hard-coded as
+MIPI_DSI_FMT_RGB888.
+
+Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-francesco@dolcini.it
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358768.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index e9e3f9e02bba0..dba1bf3912f1e 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -146,6 +146,7 @@ struct tc358768_priv {
+
+ u32 pd_lines; /* number of Parallel Port Input Data Lines */
+ u32 dsi_lanes; /* number of DSI Lanes */
++ u32 dsi_bpp; /* number of Bits Per Pixel over DSI */
+
+ /* Parameters for PLL programming */
+ u32 fbd; /* PLL feedback divider */
+@@ -284,12 +285,12 @@ static void tc358768_hw_disable(struct tc358768_priv *priv)
+
+ static u32 tc358768_pll_to_pclk(struct tc358768_priv *priv, u32 pll_clk)
+ {
+- return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->pd_lines);
++ return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->dsi_bpp);
+ }
+
+ static u32 tc358768_pclk_to_pll(struct tc358768_priv *priv, u32 pclk)
+ {
+- return (u32)div_u64((u64)pclk * priv->pd_lines, priv->dsi_lanes);
++ return (u32)div_u64((u64)pclk * priv->dsi_bpp, priv->dsi_lanes);
+ }
+
+ static int tc358768_calc_pll(struct tc358768_priv *priv,
+@@ -426,6 +427,7 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host,
+ priv->output.panel = panel;
+
+ priv->dsi_lanes = dev->lanes;
++ priv->dsi_bpp = mipi_dsi_pixel_format_to_bpp(dev->format);
+
+ /* get input ep (port0/endpoint0) */
+ ret = -EINVAL;
+@@ -437,7 +439,7 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host,
+ }
+
+ if (ret)
+- priv->pd_lines = mipi_dsi_pixel_format_to_bpp(dev->format);
++ priv->pd_lines = priv->dsi_bpp;
+
+ drm_bridge_add(&priv->bridge);
+
+--
+2.39.2
+
--- /dev/null
+From ae39a33265930e702e83c53abdcfdf1ac66492f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Apr 2023 16:29:30 +0200
+Subject: drm/bridge: tc358768: fix TCLK_TRAILCNT computation
+
+From: Francesco Dolcini <francesco.dolcini@toradex.com>
+
+[ Upstream commit ee18698e212b1659dd0850d7e2ae0f22e16ed3d3 ]
+
+Correct computation of TCLK_TRAILCNT register.
+
+The driver does not implement non-continuous clock mode, so the actual
+value doesn't make a practical difference yet. However this change also
+ensures that the value does not write to reserved registers bits in case
+of under/overflow.
+
+This register must be set to a value that ensures that
+
+TCLK-TRAIL > 60ns
+ and
+TEOT <= (105 ns + 12 x UI)
+
+with the actual value of TCLK-TRAIL being
+
+(TCLK_TRAILCNT + (1 to 2)) xHSByteClkCycle +
+ (2 + (1 to 2)) * HSBYTECLKCycle - (PHY output delay)
+
+with PHY output delay being about
+
+(2 to 3) x MIPIBitClk cycle in the BitClk conversion.
+
+Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-francesco@dolcini.it
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-francesco@dolcini.it
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358768.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index 487bfe33edc88..4cb46a3e6be8c 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -10,6 +10,7 @@
+ #include <linux/i2c.h>
+ #include <linux/kernel.h>
+ #include <linux/media-bus-format.h>
++#include <linux/minmax.h>
+ #include <linux/module.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
+@@ -639,6 +640,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+ struct mipi_dsi_device *dsi_dev = priv->output.dev;
+ unsigned long mode_flags = dsi_dev->mode_flags;
+ u32 val, val2, lptxcnt, hact, data_type;
++ s32 raw_val;
+ const struct drm_display_mode *mode;
+ u32 dsibclk_nsk, dsiclk_nsk, ui_nsk, phy_delay_nsk;
+ u32 dsiclk, dsibclk, video_start;
+@@ -750,9 +752,9 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+ dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val);
+ tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
+
+- /* TCLK_TRAIL > 60ns + 3*UI */
+- val = 60 + tc358768_to_ns(3 * ui_nsk);
+- val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 5;
++ /* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */
++ raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), dsibclk_nsk) - 5;
++ val = clamp(raw_val, 0, 127);
+ dev_dbg(priv->dev, "TCLK_TRAILCNT: 0x%x\n", val);
+ tc358768_write(priv, TC358768_TCLK_TRAILCNT, val);
+
+--
+2.39.2
+
--- /dev/null
+From bcefeefb52748291a6985210d8ae9c1645b7a372 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Apr 2023 16:29:29 +0200
+Subject: drm/bridge: tc358768: fix TCLK_ZEROCNT computation
+
+From: Francesco Dolcini <francesco.dolcini@toradex.com>
+
+[ Upstream commit f9cf811374f42fca31ac34aaf59ee2ae72b89879 ]
+
+Correct computation of TCLK_ZEROCNT register.
+
+This register must be set to a value that ensure that
+(TCLK-PREPARECNT + TCLK-ZERO) > 300ns
+
+with the actual value of (TCLK-PREPARECNT + TCLK-ZERO) being
+
+(1 to 2) + (TCLK_ZEROCNT + 1)) x HSByteClkCycle + (PHY output delay)
+
+with PHY output delay being about
+
+(2 to 3) x MIPIBitClk cycle in the BitClk conversion.
+
+Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-francesco@dolcini.it
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358768.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index dba1bf3912f1e..aff400c360662 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -742,10 +742,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+
+ /* 38ns < TCLK_PREPARE < 95ns */
+ val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1;
+- /* TCLK_PREPARE > 300ns */
+- val2 = tc358768_ns_to_cnt(300 + tc358768_to_ns(3 * ui_nsk),
+- dsibclk_nsk);
+- val |= (val2 - tc358768_to_ns(phy_delay_nsk - dsibclk_nsk)) << 8;
++ /* TCLK_PREPARE + TCLK_ZERO > 300ns */
++ val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk),
++ dsibclk_nsk) - 2;
++ val |= val2 << 8;
+ dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val);
+ tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
+
+--
+2.39.2
+
--- /dev/null
+From f6d01c235715a25cf037de1c3424ff4a91ff14d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Apr 2023 16:29:33 +0200
+Subject: drm/bridge: tc358768: fix THS_TRAILCNT computation
+
+From: Francesco Dolcini <francesco.dolcini@toradex.com>
+
+[ Upstream commit bac7842cd179572e8e0fc2d7b5254e40c6e9e057 ]
+
+Correct computation of THS_TRAILCNT register.
+
+This register must be set to a value that ensure that
+THS_TRAIL > 60 ns + 4 x UI
+ and
+THS_TRAIL > 8 x UI
+ and
+THS_TRAIL < TEOT
+ with
+TEOT = 105 ns + (12 x UI)
+
+with the actual value of THS_TRAIL being
+
+(1 + THS_TRAILCNT) x ByteClk cycle + ((1 to 2) + 2) xHSBYTECLK cycle +
+ - (PHY output delay)
+
+with PHY output delay being about
+
+(8 + (5 to 6)) x MIPIBitClk cycle in the BitClk conversion.
+
+Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-9-francesco@dolcini.it
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358768.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index d8209433d5f43..966a25cb0b108 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -780,9 +780,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+ dev_dbg(priv->dev, "TCLK_POSTCNT: 0x%x\n", val);
+ tc358768_write(priv, TC358768_TCLK_POSTCNT, val);
+
+- /* 60ns + 4*UI < THS_PREPARE < 105ns + 12*UI */
+- val = tc358768_ns_to_cnt(60 + tc358768_to_ns(15 * ui_nsk),
+- dsibclk_nsk) - 5;
++ /* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */
++ raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk),
++ dsibclk_nsk) - 4;
++ val = clamp(raw_val, 0, 15);
+ dev_dbg(priv->dev, "THS_TRAILCNT: 0x%x\n", val);
+ tc358768_write(priv, TC358768_THS_TRAILCNT, val);
+
+--
+2.39.2
+
--- /dev/null
+From 6bfe97b8cab4a8f638372783cea6eef05e05cbfe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Apr 2023 16:29:31 +0200
+Subject: drm/bridge: tc358768: fix THS_ZEROCNT computation
+
+From: Francesco Dolcini <francesco.dolcini@toradex.com>
+
+[ Upstream commit 77a089328da791118af9692543a5eedc79eb5fd4 ]
+
+Correct computation of THS_ZEROCNT register.
+
+This register must be set to a value that ensure that
+THS_PREPARE + THS_ZERO > 145ns + 10*UI
+
+with the actual value of (THS_PREPARE + THS_ZERO) being
+
+((1 to 2) + 1 + (TCLK_ZEROCNT + 1) + (3 to 4)) x ByteClk cycle +
+ + HSByteClk x (2 + (1 to 2)) + (PHY delay)
+
+with PHY delay being about
+
+(8 + (5 to 6)) x MIPIBitClk cycle in the BitClk conversion.
+
+Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-7-francesco@dolcini.it
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358768.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index 4cb46a3e6be8c..e3f456bfb90c1 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -761,9 +761,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+ /* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */
+ val = 50 + tc358768_to_ns(4 * ui_nsk);
+ val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
+- /* THS_ZERO > 145ns + 10*UI */
+- val2 = tc358768_ns_to_cnt(145 - tc358768_to_ns(ui_nsk), dsibclk_nsk);
+- val |= (val2 - tc358768_to_ns(phy_delay_nsk)) << 8;
++ /* THS_PREPARE + THS_ZERO > 145ns + 10*UI */
++ raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), dsibclk_nsk) - 10;
++ val2 = clamp(raw_val, 0, 127);
++ val |= val2 << 8;
+ dev_dbg(priv->dev, "THS_HEADERCNT: 0x%x\n", val);
+ tc358768_write(priv, TC358768_THS_HEADERCNT, val);
+
+--
+2.39.2
+
--- /dev/null
+From a285c3c0243ee224a82373d11b9c49072cca2955 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Apr 2023 16:29:32 +0200
+Subject: drm/bridge: tc358768: fix TXTAGOCNT computation
+
+From: Francesco Dolcini <francesco.dolcini@toradex.com>
+
+[ Upstream commit 3666aad8185af8d0ce164fd3c4974235417d6d0b ]
+
+Correct computation of TXTAGOCNT register.
+
+This register must be set to a value that ensure that the
+TTA-GO period = (4 x TLPX)
+
+with the actual value of TTA-GO being
+
+4 x (TXTAGOCNT + 1) x (HSByteClk cycle)
+
+Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-8-francesco@dolcini.it
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358768.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index e3f456bfb90c1..d8209433d5f43 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -796,7 +796,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+
+ /* TXTAGOCNT[26:16] RXTASURECNT[10:0] */
+ val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4);
+- val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
++ val = tc358768_ns_to_cnt(val, dsibclk_nsk) / 4 - 1;
+ val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk),
+ dsibclk_nsk) - 2;
+ val = val << 16 | val2;
+--
+2.39.2
+
--- /dev/null
+From e0d320c34c44ee8b201ff0c74c92f1ccfb6d9eab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 May 2023 18:33:07 +0200
+Subject: drm/bridge: ti-sn65dsi83: Fix enable/disable flow to meet spec
+
+From: Frieder Schrempf <frieder.schrempf@kontron.de>
+
+[ Upstream commit dd9e329af7236e34c566d3705ea32a63069b9b13 ]
+
+The datasheet describes the following initialization flow including
+minimum delay times between each step:
+
+1. DSI data lanes need to be in LP-11 and the clock lane in HS mode
+2. toggle EN signal
+3. initialize registers
+4. enable PLL
+5. soft reset
+6. enable DSI stream
+7. check error status register
+
+To meet this requirement we need to make sure the host bridge's
+pre_enable() is called first by using the pre_enable_prev_first
+flag.
+
+Furthermore we need to split enable() into pre_enable() which covers
+steps 2-5 from above and enable() which covers step 7 and is called
+after the host bridge's enable().
+
+Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Fixes: ceb515ba29ba ("drm/bridge: ti-sn65dsi83: Add TI SN65DSI83 and SN65DSI84 driver")
+Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com> #TQMa8MxML/MBa8Mx
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230503163313.2640898-3-frieder@fris.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/ti-sn65dsi83.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+index a6534011c9214..e4ee2904d0893 100644
+--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
++++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+@@ -321,8 +321,8 @@ static u8 sn65dsi83_get_dsi_div(struct sn65dsi83 *ctx)
+ return dsi_div - 1;
+ }
+
+-static void sn65dsi83_atomic_enable(struct drm_bridge *bridge,
+- struct drm_bridge_state *old_bridge_state)
++static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
++ struct drm_bridge_state *old_bridge_state)
+ {
+ struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
+ struct drm_atomic_state *state = old_bridge_state->base.state;
+@@ -485,11 +485,22 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge,
+ /* Trigger reset after CSR register update. */
+ regmap_write(ctx->regmap, REG_RC_RESET, REG_RC_RESET_SOFT_RESET);
+
++ /* Wait for 10ms after soft reset as specified in datasheet */
++ usleep_range(10000, 12000);
++}
++
++static void sn65dsi83_atomic_enable(struct drm_bridge *bridge,
++ struct drm_bridge_state *old_bridge_state)
++{
++ struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
++ unsigned int pval;
++
+ /* Clear all errors that got asserted during initialization. */
+ regmap_read(ctx->regmap, REG_IRQ_STAT, &pval);
+ regmap_write(ctx->regmap, REG_IRQ_STAT, pval);
+
+- usleep_range(10000, 12000);
++ /* Wait for 1ms and check for errors in status register */
++ usleep_range(1000, 1100);
+ regmap_read(ctx->regmap, REG_IRQ_STAT, &pval);
+ if (pval)
+ dev_err(ctx->dev, "Unexpected link status 0x%02x\n", pval);
+@@ -556,6 +567,7 @@ static const struct drm_bridge_funcs sn65dsi83_funcs = {
+ .attach = sn65dsi83_attach,
+ .detach = sn65dsi83_detach,
+ .atomic_enable = sn65dsi83_atomic_enable,
++ .atomic_pre_enable = sn65dsi83_atomic_pre_enable,
+ .atomic_disable = sn65dsi83_atomic_disable,
+ .mode_valid = sn65dsi83_mode_valid,
+
+@@ -696,6 +708,7 @@ static int sn65dsi83_probe(struct i2c_client *client)
+
+ ctx->bridge.funcs = &sn65dsi83_funcs;
+ ctx->bridge.of_node = dev->of_node;
++ ctx->bridge.pre_enable_prev_first = true;
+ drm_bridge_add(&ctx->bridge);
+
+ ret = sn65dsi83_host_attach(ctx);
+--
+2.39.2
+
--- /dev/null
+From 5b0a86ac16ed1ac9c0ee8d1a9cf64db11e092c0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 May 2023 08:53:16 +0200
+Subject: drm/bridge: ti-sn65dsi83: Fix enable error path
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 8a91b29f1f50ce7742cdbe5cf11d17f128511f3f ]
+
+If PLL locking failed, the regulator needs to be disabled again.
+
+Fixes: 5664e3c907e2 ("drm/bridge: ti-sn65dsi83: Add vcc supply regulator support")
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230504065316.2640739-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/ti-sn65dsi83.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+index 91ecfbe45bf90..a6534011c9214 100644
+--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
++++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+@@ -478,6 +478,7 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge,
+ dev_err(ctx->dev, "failed to lock PLL, ret=%i\n", ret);
+ /* On failure, disable PLL again and exit. */
+ regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00);
++ regulator_disable(ctx->vcc);
+ return;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From ccf4e1d2fb4081846e4c3131f9946c5025072bce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 21:07:16 -0800
+Subject: drm/i915/guc: More debug print updates - GuC SLPC
+
+From: John Harrison <John.C.Harrison@Intel.com>
+
+[ Upstream commit 9847ffce9b5f83a7707504b0127aeb6a05dbd378 ]
+
+Update a bunch more debug prints to use the new GT based scheme.
+
+v2: Also change prints to use %pe for error values (MichalW).
+
+Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
+Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230207050717.1833718-6-John.C.Harrison@Intel.com
+Stable-dep-of: 55f9720dbf23 ("drm/i915/guc/slpc: Provide sysfs for efficient freq")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c | 8 +--
+ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 61 ++++++++-------------
+ 2 files changed, 26 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
+index 8f8dd05835c5a..1adec6de223c7 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
+@@ -6,6 +6,7 @@
+ #include <linux/string_helpers.h>
+
+ #include "intel_guc_rc.h"
++#include "intel_guc_print.h"
+ #include "gt/intel_gt.h"
+ #include "i915_drv.h"
+
+@@ -59,13 +60,12 @@ static int __guc_rc_control(struct intel_guc *guc, bool enable)
+
+ ret = guc_action_control_gucrc(guc, enable);
+ if (ret) {
+- i915_probe_error(guc_to_gt(guc)->i915, "Failed to %s GuC RC (%pe)\n",
+- str_enable_disable(enable), ERR_PTR(ret));
++ guc_probe_error(guc, "Failed to %s RC (%pe)\n",
++ str_enable_disable(enable), ERR_PTR(ret));
+ return ret;
+ }
+
+- drm_info(>->i915->drm, "GuC RC: %s\n",
+- str_enabled_disabled(enable));
++ guc_info(guc, "RC %s\n", str_enabled_disabled(enable));
+
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+index 63464933cbceb..026d73855f36c 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+@@ -9,6 +9,7 @@
+ #include "i915_drv.h"
+ #include "i915_reg.h"
+ #include "intel_guc_slpc.h"
++#include "intel_guc_print.h"
+ #include "intel_mchbar_regs.h"
+ #include "gt/intel_gt.h"
+ #include "gt/intel_gt_regs.h"
+@@ -171,14 +172,12 @@ static int guc_action_slpc_query(struct intel_guc *guc, u32 offset)
+ static int slpc_query_task_state(struct intel_guc_slpc *slpc)
+ {
+ struct intel_guc *guc = slpc_to_guc(slpc);
+- struct drm_i915_private *i915 = slpc_to_i915(slpc);
+ u32 offset = intel_guc_ggtt_offset(guc, slpc->vma);
+ int ret;
+
+ ret = guc_action_slpc_query(guc, offset);
+ if (unlikely(ret))
+- i915_probe_error(i915, "Failed to query task state (%pe)\n",
+- ERR_PTR(ret));
++ guc_probe_error(guc, "Failed to query task state: %pe\n", ERR_PTR(ret));
+
+ drm_clflush_virt_range(slpc->vaddr, SLPC_PAGE_SIZE_BYTES);
+
+@@ -188,15 +187,14 @@ static int slpc_query_task_state(struct intel_guc_slpc *slpc)
+ static int slpc_set_param(struct intel_guc_slpc *slpc, u8 id, u32 value)
+ {
+ struct intel_guc *guc = slpc_to_guc(slpc);
+- struct drm_i915_private *i915 = slpc_to_i915(slpc);
+ int ret;
+
+ GEM_BUG_ON(id >= SLPC_MAX_PARAM);
+
+ ret = guc_action_slpc_set_param(guc, id, value);
+ if (ret)
+- i915_probe_error(i915, "Failed to set param %d to %u (%pe)\n",
+- id, value, ERR_PTR(ret));
++ guc_probe_error(guc, "Failed to set param %d to %u: %pe\n",
++ id, value, ERR_PTR(ret));
+
+ return ret;
+ }
+@@ -212,8 +210,8 @@ static int slpc_unset_param(struct intel_guc_slpc *slpc, u8 id)
+
+ static int slpc_force_min_freq(struct intel_guc_slpc *slpc, u32 freq)
+ {
+- struct drm_i915_private *i915 = slpc_to_i915(slpc);
+ struct intel_guc *guc = slpc_to_guc(slpc);
++ struct drm_i915_private *i915 = slpc_to_i915(slpc);
+ intel_wakeref_t wakeref;
+ int ret = 0;
+
+@@ -236,9 +234,8 @@ static int slpc_force_min_freq(struct intel_guc_slpc *slpc, u32 freq)
+ SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
+ freq);
+ if (ret)
+- drm_notice(&i915->drm,
+- "Failed to send set_param for min freq(%d): (%d)\n",
+- freq, ret);
++ guc_notice(guc, "Failed to send set_param for min freq(%d): %pe\n",
++ freq, ERR_PTR(ret));
+ }
+
+ return ret;
+@@ -267,7 +264,6 @@ static void slpc_boost_work(struct work_struct *work)
+ int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
+ {
+ struct intel_guc *guc = slpc_to_guc(slpc);
+- struct drm_i915_private *i915 = slpc_to_i915(slpc);
+ u32 size = PAGE_ALIGN(sizeof(struct slpc_shared_data));
+ int err;
+
+@@ -275,9 +271,7 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
+
+ err = intel_guc_allocate_and_map_vma(guc, size, &slpc->vma, (void **)&slpc->vaddr);
+ if (unlikely(err)) {
+- i915_probe_error(i915,
+- "Failed to allocate SLPC struct (err=%pe)\n",
+- ERR_PTR(err));
++ guc_probe_error(guc, "Failed to allocate SLPC struct: %pe\n", ERR_PTR(err));
+ return err;
+ }
+
+@@ -338,7 +332,6 @@ static int guc_action_slpc_reset(struct intel_guc *guc, u32 offset)
+
+ static int slpc_reset(struct intel_guc_slpc *slpc)
+ {
+- struct drm_i915_private *i915 = slpc_to_i915(slpc);
+ struct intel_guc *guc = slpc_to_guc(slpc);
+ u32 offset = intel_guc_ggtt_offset(guc, slpc->vma);
+ int ret;
+@@ -346,15 +339,14 @@ static int slpc_reset(struct intel_guc_slpc *slpc)
+ ret = guc_action_slpc_reset(guc, offset);
+
+ if (unlikely(ret < 0)) {
+- i915_probe_error(i915, "SLPC reset action failed (%pe)\n",
+- ERR_PTR(ret));
++ guc_probe_error(guc, "SLPC reset action failed: %pe\n", ERR_PTR(ret));
+ return ret;
+ }
+
+ if (!ret) {
+ if (wait_for(slpc_is_running(slpc), SLPC_RESET_TIMEOUT_MS)) {
+- i915_probe_error(i915, "SLPC not enabled! State = %s\n",
+- slpc_get_state_string(slpc));
++ guc_probe_error(guc, "SLPC not enabled! State = %s\n",
++ slpc_get_state_string(slpc));
+ return -EIO;
+ }
+ }
+@@ -495,8 +487,8 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val)
+ SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
+ val < slpc->rp1_freq);
+ if (ret) {
+- i915_probe_error(i915, "Failed to toggle efficient freq (%pe)\n",
+- ERR_PTR(ret));
++ guc_probe_error(slpc_to_guc(slpc), "Failed to toggle efficient freq: %pe\n",
++ ERR_PTR(ret));
+ goto out;
+ }
+
+@@ -611,15 +603,12 @@ static int slpc_set_softlimits(struct intel_guc_slpc *slpc)
+
+ static bool is_slpc_min_freq_rpmax(struct intel_guc_slpc *slpc)
+ {
+- struct drm_i915_private *i915 = slpc_to_i915(slpc);
+ int slpc_min_freq;
+ int ret;
+
+ ret = intel_guc_slpc_get_min_freq(slpc, &slpc_min_freq);
+ if (ret) {
+- drm_err(&i915->drm,
+- "Failed to get min freq: (%d)\n",
+- ret);
++ guc_err(slpc_to_guc(slpc), "Failed to get min freq: %pe\n", ERR_PTR(ret));
+ return false;
+ }
+
+@@ -685,9 +674,8 @@ int intel_guc_slpc_override_gucrc_mode(struct intel_guc_slpc *slpc, u32 mode)
+ with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
+ ret = slpc_set_param(slpc, SLPC_PARAM_PWRGATE_RC_MODE, mode);
+ if (ret)
+- drm_err(&i915->drm,
+- "Override gucrc mode %d failed %d\n",
+- mode, ret);
++ guc_err(slpc_to_guc(slpc), "Override RC mode %d failed: %pe\n",
++ mode, ERR_PTR(ret));
+ }
+
+ return ret;
+@@ -702,9 +690,7 @@ int intel_guc_slpc_unset_gucrc_mode(struct intel_guc_slpc *slpc)
+ with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
+ ret = slpc_unset_param(slpc, SLPC_PARAM_PWRGATE_RC_MODE);
+ if (ret)
+- drm_err(&i915->drm,
+- "Unsetting gucrc mode failed %d\n",
+- ret);
++ guc_err(slpc_to_guc(slpc), "Unsetting RC mode failed: %pe\n", ERR_PTR(ret));
+ }
+
+ return ret;
+@@ -725,7 +711,7 @@ int intel_guc_slpc_unset_gucrc_mode(struct intel_guc_slpc *slpc)
+ */
+ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
+ {
+- struct drm_i915_private *i915 = slpc_to_i915(slpc);
++ struct intel_guc *guc = slpc_to_guc(slpc);
+ int ret;
+
+ GEM_BUG_ON(!slpc->vma);
+@@ -734,8 +720,7 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
+
+ ret = slpc_reset(slpc);
+ if (unlikely(ret < 0)) {
+- i915_probe_error(i915, "SLPC Reset event returned (%pe)\n",
+- ERR_PTR(ret));
++ guc_probe_error(guc, "SLPC Reset event returned: %pe\n", ERR_PTR(ret));
+ return ret;
+ }
+
+@@ -743,7 +728,7 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
+ if (unlikely(ret < 0))
+ return ret;
+
+- intel_guc_pm_intrmsk_enable(to_gt(i915));
++ intel_guc_pm_intrmsk_enable(slpc_to_gt(slpc));
+
+ slpc_get_rp_values(slpc);
+
+@@ -753,16 +738,14 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
+ /* Set SLPC max limit to RP0 */
+ ret = slpc_use_fused_rp0(slpc);
+ if (unlikely(ret)) {
+- i915_probe_error(i915, "Failed to set SLPC max to RP0 (%pe)\n",
+- ERR_PTR(ret));
++ guc_probe_error(guc, "Failed to set SLPC max to RP0: %pe\n", ERR_PTR(ret));
+ return ret;
+ }
+
+ /* Revert SLPC min/max to softlimits if necessary */
+ ret = slpc_set_softlimits(slpc);
+ if (unlikely(ret)) {
+- i915_probe_error(i915, "Failed to set SLPC softlimits (%pe)\n",
+- ERR_PTR(ret));
++ guc_probe_error(guc, "Failed to set SLPC softlimits: %pe\n", ERR_PTR(ret));
+ return ret;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From b26fa5fdd9b907f3acab0de21e863c26ef9ebea9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Apr 2023 17:39:41 -0700
+Subject: drm/i915/guc/slpc: Provide sysfs for efficient freq
+
+From: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
+
+[ Upstream commit 55f9720dbf23ed640a51ea5564c22305efa8a467 ]
+
+SLPC enables use of efficient freq at init by default. It is
+possible for GuC to request frequencies that are higher than
+the 'software' max if user has set it lower than the efficient
+level.
+
+Scenarios/tests that require strict fixing of freq below the efficient
+level will need to disable it through this interface.
+
+v2: Keep just one interface to toggle sysfs. With this, user will
+be completely responsible for toggling efficient frequency if need
+be. There will be no implicit disabling when user sets min < RP1 (Ashutosh)
+
+v3: Remove unused label, review comments (Ashutosh)
+
+v4: Toggle efficient freq usage in SLPC selftest and checkpatch fixes
+
+v5: Review comments (Andi) and add a separate patch for selftest updates
+
+Fixes: 95ccf312a1e4 ("drm/i915/guc/slpc: Allow SLPC to use efficient frequency")
+Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
+Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
+Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
+Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230426003942.1924347-1-vinay.belgaumkar@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c | 35 +++++++++++++++++
+ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 38 +++++++++++++------
+ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h | 1 +
+ .../gpu/drm/i915/gt/uc/intel_guc_slpc_types.h | 1 +
+ 4 files changed, 64 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c
+index 28f27091cd3b7..ee2b44f896a27 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c
++++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c
+@@ -451,6 +451,33 @@ static ssize_t punit_req_freq_mhz_show(struct kobject *kobj,
+ return sysfs_emit(buff, "%u\n", preq);
+ }
+
++static ssize_t slpc_ignore_eff_freq_show(struct kobject *kobj,
++ struct kobj_attribute *attr,
++ char *buff)
++{
++ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
++ struct intel_guc_slpc *slpc = >->uc.guc.slpc;
++
++ return sysfs_emit(buff, "%u\n", slpc->ignore_eff_freq);
++}
++
++static ssize_t slpc_ignore_eff_freq_store(struct kobject *kobj,
++ struct kobj_attribute *attr,
++ const char *buff, size_t count)
++{
++ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
++ struct intel_guc_slpc *slpc = >->uc.guc.slpc;
++ int err;
++ u32 val;
++
++ err = kstrtou32(buff, 0, &val);
++ if (err)
++ return err;
++
++ err = intel_guc_slpc_set_ignore_eff_freq(slpc, val);
++ return err ?: count;
++}
++
+ struct intel_gt_bool_throttle_attr {
+ struct attribute attr;
+ ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
+@@ -663,6 +690,8 @@ static struct kobj_attribute attr_media_freq_factor_scale =
+ INTEL_GT_ATTR_RO(media_RP0_freq_mhz);
+ INTEL_GT_ATTR_RO(media_RPn_freq_mhz);
+
++INTEL_GT_ATTR_RW(slpc_ignore_eff_freq);
++
+ static const struct attribute *media_perf_power_attrs[] = {
+ &attr_media_freq_factor.attr,
+ &attr_media_freq_factor_scale.attr,
+@@ -744,6 +773,12 @@ void intel_gt_sysfs_pm_init(struct intel_gt *gt, struct kobject *kobj)
+ if (ret)
+ gt_warn(gt, "failed to create punit_req_freq_mhz sysfs (%pe)", ERR_PTR(ret));
+
++ if (intel_uc_uses_guc_slpc(>->uc)) {
++ ret = sysfs_create_file(kobj, &attr_slpc_ignore_eff_freq.attr);
++ if (ret)
++ gt_warn(gt, "failed to create ignore_eff_freq sysfs (%pe)", ERR_PTR(ret));
++ }
++
+ if (i915_mmio_reg_valid(intel_gt_perf_limit_reasons_reg(gt))) {
+ ret = sysfs_create_files(kobj, throttle_reason_attrs);
+ if (ret)
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+index 026d73855f36c..56dbba1ef6684 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+@@ -277,6 +277,7 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
+
+ slpc->max_freq_softlimit = 0;
+ slpc->min_freq_softlimit = 0;
++ slpc->ignore_eff_freq = false;
+ slpc->min_is_rpmax = false;
+
+ slpc->boost_freq = 0;
+@@ -457,6 +458,29 @@ int intel_guc_slpc_get_max_freq(struct intel_guc_slpc *slpc, u32 *val)
+ return ret;
+ }
+
++int intel_guc_slpc_set_ignore_eff_freq(struct intel_guc_slpc *slpc, bool val)
++{
++ struct drm_i915_private *i915 = slpc_to_i915(slpc);
++ intel_wakeref_t wakeref;
++ int ret;
++
++ mutex_lock(&slpc->lock);
++ wakeref = intel_runtime_pm_get(&i915->runtime_pm);
++
++ ret = slpc_set_param(slpc,
++ SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
++ val);
++ if (ret)
++ guc_probe_error(slpc_to_guc(slpc), "Failed to set efficient freq(%d): %pe\n",
++ val, ERR_PTR(ret));
++ else
++ slpc->ignore_eff_freq = val;
++
++ intel_runtime_pm_put(&i915->runtime_pm, wakeref);
++ mutex_unlock(&slpc->lock);
++ return ret;
++}
++
+ /**
+ * intel_guc_slpc_set_min_freq() - Set min frequency limit for SLPC.
+ * @slpc: pointer to intel_guc_slpc.
+@@ -482,16 +506,6 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val)
+ mutex_lock(&slpc->lock);
+ wakeref = intel_runtime_pm_get(&i915->runtime_pm);
+
+- /* Ignore efficient freq if lower min freq is requested */
+- ret = slpc_set_param(slpc,
+- SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY,
+- val < slpc->rp1_freq);
+- if (ret) {
+- guc_probe_error(slpc_to_guc(slpc), "Failed to toggle efficient freq: %pe\n",
+- ERR_PTR(ret));
+- goto out;
+- }
+-
+ ret = slpc_set_param(slpc,
+ SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
+ val);
+@@ -499,7 +513,6 @@ int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val)
+ if (!ret)
+ slpc->min_freq_softlimit = val;
+
+-out:
+ intel_runtime_pm_put(&i915->runtime_pm, wakeref);
+ mutex_unlock(&slpc->lock);
+
+@@ -752,6 +765,9 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
+ /* Set cached media freq ratio mode */
+ intel_guc_slpc_set_media_ratio_mode(slpc, slpc->media_ratio_mode);
+
++ /* Set cached value of ignore efficient freq */
++ intel_guc_slpc_set_ignore_eff_freq(slpc, slpc->ignore_eff_freq);
++
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
+index 17ed515f6a852..597eb5413ddf2 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h
+@@ -46,5 +46,6 @@ void intel_guc_slpc_boost(struct intel_guc_slpc *slpc);
+ void intel_guc_slpc_dec_waiters(struct intel_guc_slpc *slpc);
+ int intel_guc_slpc_unset_gucrc_mode(struct intel_guc_slpc *slpc);
+ int intel_guc_slpc_override_gucrc_mode(struct intel_guc_slpc *slpc, u32 mode);
++int intel_guc_slpc_set_ignore_eff_freq(struct intel_guc_slpc *slpc, bool val);
+
+ #endif
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h
+index a6ef53b04e047..a886513314977 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h
+@@ -31,6 +31,7 @@ struct intel_guc_slpc {
+ /* frequency softlimits */
+ u32 min_freq_softlimit;
+ u32 max_freq_softlimit;
++ bool ignore_eff_freq;
+
+ /* cached media ratio mode */
+ u32 media_ratio_mode;
+--
+2.39.2
+
--- /dev/null
+From 0a0fa49fd895b5034f9af3803e7139005dbbbe09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Apr 2023 04:13:29 +0300
+Subject: drm/msm/a5xx: really check for A510 in a5xx_gpu_init
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 736a9327365644b460e4498b1ce172ca411efcbc ]
+
+The commit 010c8bbad2cb ("drm: msm: adreno: Disable preemption on Adreno
+510") added special handling for a510 (this SKU doesn't seem to support
+preemption, so the driver should clamp nr_rings to 1). However the
+gpu->revn is not yet set (it is set later, in adreno_gpu_init()) and
+thus the condition is always false. Check config->rev instead.
+
+Fixes: 010c8bbad2cb ("drm: msm: adreno: Disable preemption on Adreno 510")
+Reported-by: Adam Skladowski <a39.skl@gmail.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Tested-by: Adam Skladowski <a39.skl@gmail.com>
+Patchwork: https://patchwork.freedesktop.org/patch/531511/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+index 0372f89082022..660c830c68764 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+@@ -1740,6 +1740,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
+ {
+ struct msm_drm_private *priv = dev->dev_private;
+ struct platform_device *pdev = priv->gpu_pdev;
++ struct adreno_platform_config *config = pdev->dev.platform_data;
+ struct a5xx_gpu *a5xx_gpu = NULL;
+ struct adreno_gpu *adreno_gpu;
+ struct msm_gpu *gpu;
+@@ -1766,7 +1767,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
+
+ nr_rings = 4;
+
+- if (adreno_is_a510(adreno_gpu))
++ if (adreno_cmp_rev(ADRENO_REV(5, 1, 0, ANY_ID), config->rev))
+ nr_rings = 1;
+
+ ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, nr_rings);
+--
+2.39.2
+
--- /dev/null
+From 03be83ecd27cf28950ee2ff3f9110826e5a6b1c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Apr 2023 21:52:26 +0300
+Subject: drm/msm/a6xx: don't set IO_PGTABLE_QUIRK_ARM_OUTER_WBWA with coherent
+ SMMU
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 38e27a6fbf2206b18417c5985dbcdeca0f2026b8 ]
+
+If the Adreno SMMU is dma-coherent, allocation will fail unless we
+disable IO_PGTABLE_QUIRK_ARM_OUTER_WBWA. Skip setting this quirk for the
+coherent SMMUs (like we have on sm8350 platform).
+
+Fixes: 54af0ceb7595 ("arm64: dts: qcom: sm8350: add GPU, GMU, GPU CC and SMMU nodes")
+Reported-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Tested-by: David Heidelberg <david@ixit.cz>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Tested-by: Konrad Dybcio <konrad.dybcio@linaro.org> # SM8450 HDK
+Patchwork: https://patchwork.freedesktop.org/patch/531562/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+index 2942d2548ce69..f74495dcbd966 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+@@ -1793,7 +1793,8 @@ a6xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev)
+ * This allows GPU to set the bus attributes required to use system
+ * cache on behalf of the iommu page table walker.
+ */
+- if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
++ if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice) &&
++ !device_iommu_capable(&pdev->dev, IOMMU_CAP_CACHE_COHERENCY))
+ quirks |= IO_PGTABLE_QUIRK_ARM_OUTER_WBWA;
+
+ return adreno_iommu_create_address_space(gpu, pdev, quirks);
+--
+2.39.2
+
--- /dev/null
+From fc60a0080561bf484497a7d6dbe29e7b128d6491 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Mar 2023 22:03:08 +0530
+Subject: drm/msm/disp/dpu: get timing engine status from intf status register
+
+From: Vinod Polimera <quic_vpolimer@quicinc.com>
+
+[ Upstream commit e3969eadc8ee78a5bdca65b8ed0a421a359e4090 ]
+
+Recommended way of reading the interface timing gen status is via
+status register. Timing gen status register will give a reliable status
+of the interface especially during ON/OFF transitions. This support was
+added from DPU version 5.0.0.
+
+Signed-off-by: Vinod Polimera <quic_vpolimer@quicinc.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/524724/
+Link: https://lore.kernel.org/r/1677774797-31063-6-git-send-email-quic_vpolimer@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Stable-dep-of: a7129231edf3 ("drm/msm/dpu: Set DPU_DATA_HCTL_EN for in INTF_SC7180_MASK")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 ++-
+ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 12 +++++++-----
+ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 8 +++++++-
+ 3 files changed, 16 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+index f7214c4401e19..900cdb40c7b40 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+@@ -94,7 +94,8 @@
+
+ #define INTF_SDM845_MASK (0)
+
+-#define INTF_SC7180_MASK BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE)
++#define INTF_SC7180_MASK \
++ (BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) | BIT(DPU_INTF_STATUS_SUPPORTED))
+
+ #define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+index 5f96dd8def092..d7d45e1e7b310 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+@@ -214,17 +214,19 @@ enum {
+
+ /**
+ * INTF sub-blocks
+- * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which
+- * pixel data arrives to this INTF
+- * @DPU_INTF_TE INTF block has TE configuration support
+- * @DPU_DATA_HCTL_EN Allows data to be transferred at different rate
+- than video timing
++ * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which
++ * pixel data arrives to this INTF
++ * @DPU_INTF_TE INTF block has TE configuration support
++ * @DPU_DATA_HCTL_EN Allows data to be transferred at different rate
++ * than video timing
++ * @DPU_INTF_STATUS_SUPPORTED INTF block has INTF_STATUS register
+ * @DPU_INTF_MAX
+ */
+ enum {
+ DPU_INTF_INPUT_CTRL = 0x1,
+ DPU_INTF_TE,
+ DPU_DATA_HCTL_EN,
++ DPU_INTF_STATUS_SUPPORTED,
+ DPU_INTF_MAX
+ };
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+index b2a94b9a3e987..b9dddf576c029 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+@@ -57,6 +57,7 @@
+ #define INTF_PROG_FETCH_START 0x170
+ #define INTF_PROG_ROT_START 0x174
+ #define INTF_MUX 0x25C
++#define INTF_STATUS 0x26C
+
+ #define INTF_CFG_ACTIVE_H_EN BIT(29)
+ #define INTF_CFG_ACTIVE_V_EN BIT(30)
+@@ -292,8 +293,13 @@ static void dpu_hw_intf_get_status(
+ struct intf_status *s)
+ {
+ struct dpu_hw_blk_reg_map *c = &intf->hw;
++ unsigned long cap = intf->cap->features;
++
++ if (cap & BIT(DPU_INTF_STATUS_SUPPORTED))
++ s->is_en = DPU_REG_READ(c, INTF_STATUS) & BIT(0);
++ else
++ s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN);
+
+- s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN);
+ s->is_prog_fetch_en = !!(DPU_REG_READ(c, INTF_CONFIG) & BIT(31));
+ if (s->is_en) {
+ s->frame_count = DPU_REG_READ(c, INTF_FRAME_COUNT);
+--
+2.39.2
+
--- /dev/null
+From e5819c0e48ef439cb3d28e621d492f57e75aebff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 15:01:06 -0700
+Subject: drm/msm/dp: Drop aux devices together with DP controller
+
+From: Bjorn Andersson <quic_bjorande@quicinc.com>
+
+[ Upstream commit a7bfb2ad2184a1fba78be35209b6019aa8cc8d4d ]
+
+Using devres to depopulate the aux bus made sure that upon a probe
+deferral the EDP panel device would be destroyed and recreated upon next
+attempt.
+
+But the struct device which the devres is tied to is the DPUs
+(drm_dev->dev), which may be happen after the DP controller is torn
+down.
+
+Indications of this can be seen in the commonly seen EDID-hexdump full
+of zeros in the log, or the occasional/rare KASAN fault where the
+panel's attempt to read the EDID information causes a use after free on
+DP resources.
+
+It's tempting to move the devres to the DP controller's struct device,
+but the resources used by the device(s) on the aux bus are explicitly
+torn down in the error path. The KASAN-reported use-after-free also
+remains, as the DP aux "module" explicitly frees its devres-allocated
+memory in this code path.
+
+As such, explicitly depopulate the aux bus in the error path, and in the
+component unbind path, to avoid these issues.
+
+Fixes: 2b57f726611e ("drm/msm/dp: fix aux-bus EP lifetime")
+Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Patchwork: https://patchwork.freedesktop.org/patch/542163/
+Link: https://lore.kernel.org/r/20230612220106.1884039-1-quic_bjorande@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dp/dp_display.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
+index 3f9a18410c0bb..97776f5e12524 100644
+--- a/drivers/gpu/drm/msm/dp/dp_display.c
++++ b/drivers/gpu/drm/msm/dp/dp_display.c
+@@ -325,6 +325,8 @@ static void dp_display_unbind(struct device *dev, struct device *master,
+
+ kthread_stop(dp->ev_tsk);
+
++ of_dp_aux_depopulate_bus(dp->aux);
++
+ dp_power_client_deinit(dp->power);
+ dp_unregister_audio_driver(dev, dp->audio);
+ dp_aux_unregister(dp->aux);
+@@ -1538,11 +1540,6 @@ 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;
+@@ -1571,12 +1568,6 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
+ 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;
+@@ -1601,6 +1592,7 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
+ error:
+ if (dp->is_edp) {
+ disable_irq(dp_priv->irq);
++ of_dp_aux_depopulate_bus(dp_priv->aux);
+ dp_display_host_phy_exit(dp_priv);
+ dp_display_host_deinit(dp_priv);
+ }
+--
+2.39.2
+
--- /dev/null
+From e8f0be0e32d370e7546e26e7d1989b17ea1ec094 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 15:02:59 -0700
+Subject: drm/msm/dp: Free resources after unregistering them
+
+From: Bjorn Andersson <quic_bjorande@quicinc.com>
+
+[ Upstream commit fa0048a4b1fa7a50c8b0e514f5b428abdf69a6f8 ]
+
+The DP component's unbind operation walks through the submodules to
+unregister and clean things up. But if the unbind happens because the DP
+controller itself is being removed, all the memory for those submodules
+has just been freed.
+
+Change the order of these operations to avoid the many use-after-free
+that otherwise happens in this code path.
+
+Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support")
+Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/542166/
+Link: https://lore.kernel.org/r/20230612220259.1884381-1-quic_bjorande@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dp/dp_display.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
+index 97776f5e12524..22967cf6a79d3 100644
+--- a/drivers/gpu/drm/msm/dp/dp_display.c
++++ b/drivers/gpu/drm/msm/dp/dp_display.c
+@@ -1354,9 +1354,9 @@ static int dp_display_remove(struct platform_device *pdev)
+ {
+ struct dp_display_private *dp = dev_get_dp_display_private(&pdev->dev);
+
++ component_del(&pdev->dev, &dp_display_comp_ops);
+ dp_display_deinit_sub_modules(dp);
+
+- component_del(&pdev->dev, &dp_display_comp_ops);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From fbd36b95cb7c5bf3e4152222d0fe8e5d87758b37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 May 2023 10:40:55 -0700
+Subject: drm/msm/dpu: always clear every individual pending flush mask
+
+From: Kuogee Hsieh <quic_khsieh@quicinc.com>
+
+[ Upstream commit 625cbb077007698060b12d0ae5657a4d8411b153 ]
+
+There are two tiers of pending flush control, top level and
+individual hardware block. Currently only the top level of
+flush mask is reset to 0 but the individual pending flush masks
+of particular hardware blocks are left at their previous values,
+eventually accumulating all possible bit values and typically
+flushing more than necessary.
+Reset all individual hardware block flush masks to 0 to avoid
+accidentally flushing them.
+
+Changes in V13:
+-- rewording commit text
+-- add an empty space line as suggested
+
+Changes in V14:
+-- add Fixes tag
+
+Fixes: 73bfb790ac78 ("msm:disp:dpu1: setup display datapath for SC7180 target")
+Signed-off-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Patchwork: https://patchwork.freedesktop.org/patch/539508/
+Link: https://lore.kernel.org/r/1685036458-22683-8-git-send-email-quic_khsieh@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+index 3ef2e37b41087..4072638c37918 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+@@ -115,6 +115,9 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx)
+ trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask,
+ dpu_hw_ctl_get_flush_register(ctx));
+ ctx->pending_flush_mask = 0x0;
++ ctx->pending_intf_flush_mask = 0;
++ ctx->pending_wb_flush_mask = 0;
++ ctx->pending_merge_3d_flush_mask = 0;
+ }
+
+ static inline void dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl *ctx,
+--
+2.39.2
+
--- /dev/null
+From 100d8107cddab16a727c6f9831cc4f9a5e488823 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 03:09:41 +0300
+Subject: drm/msm/dpu: correct MERGE_3D length
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 9a6c13b847d61b0c3796820ca6e976789df59cd8 ]
+
+Each MERGE_3D block has just two registers. Correct the block length
+accordingly.
+
+Fixes: 4369c93cf36b ("drm/msm/dpu: initial support for merge3D hardware block")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/542177/
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Link: https://lore.kernel.org/r/20230613001004.3426676-3-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+index f41bbceef70cf..c2462d58b67d6 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+@@ -1566,7 +1566,7 @@ static struct dpu_pingpong_cfg qcm2290_pp[] = {
+ #define MERGE_3D_BLK(_name, _id, _base) \
+ {\
+ .name = _name, .id = _id, \
+- .base = _base, .len = 0x100, \
++ .base = _base, .len = 0x8, \
+ .features = MERGE_3D_SM8150_MASK, \
+ .sblk = NULL \
+ }
+--
+2.39.2
+
--- /dev/null
+From 62a32985ee64fc12e9439011c5bb6c2c384151c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 21:25:33 +0300
+Subject: drm/msm/dpu: do not enable color-management if DSPPs are not
+ available
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 3bcfc7b90465efd337d39b91b43972162f0d1908 ]
+
+We can not support color management without DSPP blocks being provided
+in the HW catalog. Do not enable color management for CRTCs if num_dspps
+is 0.
+
+Fixes: 4259ff7ae509 ("drm/msm/dpu: add support for pcc color block in dpu driver")
+Reported-by: Yongqin Liu <yongqin.liu@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Sumit Semwal <sumit.semwal@linaro.org>
+Tested-by: Yongqin Liu <yongqin.liu@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/542141/
+Link: https://lore.kernel.org/r/20230612182534.3345805-1-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+index f29a339a37050..ce188452cd56a 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+@@ -1575,6 +1575,8 @@ static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = {
+ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
+ struct drm_plane *cursor)
+ {
++ struct msm_drm_private *priv = dev->dev_private;
++ struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
+ struct drm_crtc *crtc = NULL;
+ struct dpu_crtc *dpu_crtc = NULL;
+ int i;
+@@ -1606,7 +1608,8 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
+
+ drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs);
+
+- drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
++ if (dpu_kms->catalog->dspp_count)
++ drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
+
+ /* save user friendly CRTC name for later */
+ snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id);
+--
+2.39.2
+
--- /dev/null
+From 564f1e8edd686b6365d25fab12b2fbd9f750c398 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 May 2023 10:45:20 -0700
+Subject: drm/msm/dpu: Fix slice_last_group_size calculation
+
+From: Jessica Zhang <quic_jesszhan@quicinc.com>
+
+[ Upstream commit c223059e6f8340f7eac2319470984cbfc39c433b ]
+
+Correct the math for slice_last_group_size so that it matches the
+calculations downstream.
+
+Fixes: c110cfd1753e ("drm/msm/disp/dpu1: Add support for DSC")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/539269/
+Link: https://lore.kernel.org/r/20230329-rfc-msm-dsc-helper-v14-7-bafc7be95691@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+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 619926da1441e..68035745b7069 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
+@@ -54,9 +54,10 @@ 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->slice_width % 3);
++ slice_last_group_size = (dsc->slice_width + 2) % 3;
++
+ data = (initial_lines << 20);
+- data |= ((slice_last_group_size - 1) << 18);
++ data |= (slice_last_group_size << 18);
+ /* bpp is 6.4 format, 4 LSBs bits are for fractional part */
+ data |= (dsc->bits_per_pixel << 8);
+ data |= (dsc->block_pred_enable << 7);
+--
+2.39.2
+
--- /dev/null
+From 751705a209c6e3b68ecb3071eca023cbfbdafb84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 May 2023 20:49:59 +0200
+Subject: drm/msm/dpu: Set DPU_DATA_HCTL_EN for in INTF_SC7180_MASK
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit a7129231edf329a00e92dbd2d741f6da728a4a06 ]
+
+DPU5 and newer targets enable this unconditionally. Move it from the
+SC7280 mask to the SC7180 one.
+
+Fixes: 7e6ee55320f0 ("drm/msm/disp/dpu1: enable DATA_HCTL_EN for sc7280 target")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/538159/
+Link: https://lore.kernel.org/r/20230508-topic-hctl_en-v2-1-e7bea9f1f5dd@linaro.org
+[DB: removed BIT(DPU_INTF_DATA_COMPRESS), which is not yet merged]
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+index 900cdb40c7b40..f41bbceef70cf 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+@@ -95,9 +95,12 @@
+ #define INTF_SDM845_MASK (0)
+
+ #define INTF_SC7180_MASK \
+- (BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) | BIT(DPU_INTF_STATUS_SUPPORTED))
++ (BIT(DPU_INTF_INPUT_CTRL) | \
++ BIT(DPU_INTF_TE) | \
++ BIT(DPU_INTF_STATUS_SUPPORTED) | \
++ BIT(DPU_DATA_HCTL_EN))
+
+-#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)
++#define INTF_SC7280_MASK (INTF_SC7180_MASK)
+
+ #define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+--
+2.39.2
+
--- /dev/null
+From 875a3019efeb7e60b76c512a88f32c7c9b122478 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 May 2023 10:40:49 -0700
+Subject: drm/msm/dpu: set DSC flush bit correctly at MDP CTL flush register
+
+From: Kuogee Hsieh <quic_khsieh@quicinc.com>
+
+[ Upstream commit 12cef323c903bd8b13d1f6ff24a9695c2cdc360b ]
+
+The CTL_FLUSH register should be programmed with the 22th bit
+(DSC_IDX) to flush the DSC hardware blocks, not the literal value of
+22 (which corresponds to flushing VIG1, VIG2 and RGB1 instead).
+
+Changes in V12:
+-- split this patch out of "separate DSC flush update out of interface"
+
+Changes in V13:
+-- rewording the commit text
+
+Changes in V14:
+-- drop 'DSC" from "The DSC CTL_FLUSH register" at commit text
+
+Fixes: 77f6da90487c ("drm/msm/disp/dpu1: Add DSC support in hw_ctl")
+Signed-off-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Patchwork: https://patchwork.freedesktop.org/patch/539496/
+Link: https://lore.kernel.org/r/1685036458-22683-2-git-send-email-quic_khsieh@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+index 6c53ea560ffaa..3ef2e37b41087 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+@@ -505,7 +505,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
+ DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
+ BIT(cfg->merge_3d - MERGE_3D_0));
+ if (cfg->dsc) {
+- DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, DSC_IDX);
++ DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, BIT(DSC_IDX));
+ DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc);
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From e2b77ef9c11616fa37b171cc413a2eb64270d6f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 May 2023 04:12:57 +0300
+Subject: drm/msm/dsi: don't allow enabling 14nm VCO with unprogrammed rate
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 1e0a97f84d73ea1182740f62069690c7f3271abb ]
+
+If the dispcc uses CLK_OPS_PARENT_ENABLE (e.g. on QCM2290), CCF can try
+enabling VCO before the rate has been programmed. This can cause clock
+lockups and/or other boot issues. Program the VCO to the minimal PLL
+rate if the read rate is 0 Hz.
+
+Cc: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reported-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+Reported-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Fixes: f079f6d999cb ("drm/msm/dsi: Add PHY/PLL for 8x96")
+Patchwork: https://patchwork.freedesktop.org/patch/534813/
+Link: https://lore.kernel.org/r/20230501011257.3460103-1-dmitry.baryshkov@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
+index 9f488adea7f54..3ce45b023e637 100644
+--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
+@@ -539,6 +539,9 @@ static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw)
+ if (unlikely(pll_14nm->phy->pll_on))
+ return 0;
+
++ if (dsi_pll_14nm_vco_recalc_rate(hw, VCO_REF_CLK_RATE) == 0)
++ dsi_pll_14nm_vco_set_rate(hw, pll_14nm->phy->cfg->min_pll_rate, VCO_REF_CLK_RATE);
++
+ dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10);
+ dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1);
+
+--
+2.39.2
+
--- /dev/null
+From 5e0afeb8d719185d2312f03f8e68432ee49eb03a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 15:57:17 -0700
+Subject: drm/msm/dsi: Remove incorrect references to slice_count
+
+From: Jessica Zhang <quic_jesszhan@quicinc.com>
+
+[ Upstream commit 155fa3a91d64221eb0885fd221cc8085dbef908f ]
+
+Currently, slice_count is being used to calculate word count and
+pkt_per_line. Instead, these values should be calculated using slice per
+packet, which is not the same as slice_count.
+
+Slice count represents the number of slices per interface, and its value
+will not always match that of slice per packet. For example, it is possible
+to have cases where there are multiple slices per interface but the panel
+specifies only one slice per packet.
+
+Thus, use the default value of one slice per packet and remove slice_count
+from the aforementioned calculations.
+
+Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration")
+Fixes: bc6b6ff8135c ("drm/msm/dsi: Use DSC slice(s) packet size to compute word count")
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/541965/
+Link: https://lore.kernel.org/r/20230405-add-dsc-support-v6-5-95eab864d1b6@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dsi/dsi_host.c | 26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
+index 18fa30e1e8583..3ee770dddc2fd 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
+@@ -854,18 +854,17 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
+ */
+ slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->slice_width);
+
+- /*
+- * If slice_count is greater than slice_per_intf
+- * then default to 1. This can happen during partial
+- * update.
+- */
+- if (dsc->slice_count > slice_per_intf)
+- dsc->slice_count = 1;
+-
+ 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->slice_count;
++
++ /*
++ * Typically, pkt_per_line = slice_per_intf * slice_per_pkt.
++ *
++ * Since the current driver only supports slice_per_pkt = 1,
++ * pkt_per_line will be equal to slice per intf for now.
++ */
++ pkt_per_line = slice_per_intf;
+
+ if (is_cmd_mode) /* packet data type */
+ reg = DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE);
+@@ -989,7 +988,14 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+ if (!msm_host->dsc)
+ wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
+ else
+- wc = msm_host->dsc->slice_chunk_size * msm_host->dsc->slice_count + 1;
++ /*
++ * When DSC is enabled, WC = slice_chunk_size * slice_per_pkt + 1.
++ * Currently, the driver only supports default value of slice_per_pkt = 1
++ *
++ * TODO: Expand mipi_dsi_device struct to hold slice_per_pkt info
++ * and adjust DSC math to account for slice_per_pkt.
++ */
++ wc = msm_host->dsc->slice_chunk_size + 1;
+
+ dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL,
+ DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) |
+--
+2.39.2
+
--- /dev/null
+From 3fc72721f3e390d35882b4f11ee833b33cb09519 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 23:03:23 +0200
+Subject: drm/nouveau: dispnv50: fix missing-prototypes warning
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 504e72ed3a1b1c0d4450712a42ae6070d3a05a8e ]
+
+nv50_display_create() is declared in another header, along with
+a couple of declarations that are now outdated:
+
+drivers/gpu/drm/nouveau/dispnv50/disp.c:2517:1: error: no previous prototype for 'nv50_display_create'
+
+Fixes: ba801ef068c1 ("drm/nouveau/kms: display destroy/init/fini hooks can be static")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Karol Herbst <kherbst@redhat.com>
+Signed-off-by: Karol Herbst <kherbst@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230417210329.2469722-1-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/dispnv50/disp.c | 1 +
+ drivers/gpu/drm/nouveau/nv50_display.h | 4 +---
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
+index 5bb777ff13130..9b6824f6b9e4b 100644
+--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
++++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
+@@ -64,6 +64,7 @@
+ #include "nouveau_connector.h"
+ #include "nouveau_encoder.h"
+ #include "nouveau_fence.h"
++#include "nv50_display.h"
+
+ #include <subdev/bios/dp.h>
+
+diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h
+index fbd3b15583bc8..60f77766766e9 100644
+--- a/drivers/gpu/drm/nouveau/nv50_display.h
++++ b/drivers/gpu/drm/nouveau/nv50_display.h
+@@ -31,7 +31,5 @@
+ #include "nouveau_reg.h"
+
+ int nv50_display_create(struct drm_device *);
+-void nv50_display_destroy(struct drm_device *);
+-int nv50_display_init(struct drm_device *);
+-void nv50_display_fini(struct drm_device *);
++
+ #endif /* __NV50_DISPLAY_H__ */
+--
+2.39.2
+
--- /dev/null
+From d6eaceb3c56f7d2389dbf66f688169131cdc25f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 May 2023 20:26:38 +0300
+Subject: drm/panel: sharp-ls043t1le01: adjust mode settings
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit dee23b2c9e3ff46d59c5d45e1436eceb878e7c9a ]
+
+Using current settings causes panel flickering on APQ8074 dragonboard.
+Adjust panel settings to follow the vendor-provided mode. This also
+enables MIPI_DSI_MODE_VIDEO_SYNC_PULSE, which is also specified by the
+vendor dtsi for the mentioned dragonboard.
+
+Fixes: ee0172383190 ("drm/panel: Add Sharp LS043T1LE01 MIPI DSI panel")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230507172639.2320934-1-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
+index d1ec80a3e3c72..ef148504cf24a 100644
+--- a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
++++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
+@@ -192,15 +192,15 @@ static int sharp_nt_panel_enable(struct drm_panel *panel)
+ }
+
+ static const struct drm_display_mode default_mode = {
+- .clock = 41118,
++ .clock = (540 + 48 + 32 + 80) * (960 + 3 + 10 + 15) * 60 / 1000,
+ .hdisplay = 540,
+ .hsync_start = 540 + 48,
+- .hsync_end = 540 + 48 + 80,
+- .htotal = 540 + 48 + 80 + 32,
++ .hsync_end = 540 + 48 + 32,
++ .htotal = 540 + 48 + 32 + 80,
+ .vdisplay = 960,
+ .vsync_start = 960 + 3,
+- .vsync_end = 960 + 3 + 15,
+- .vtotal = 960 + 3 + 15 + 1,
++ .vsync_end = 960 + 3 + 10,
++ .vtotal = 960 + 3 + 10 + 15,
+ };
+
+ static int sharp_nt_panel_get_modes(struct drm_panel *panel,
+@@ -280,6 +280,7 @@ static int sharp_nt_panel_probe(struct mipi_dsi_device *dsi)
+ dsi->lanes = 2;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
++ MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
+ MIPI_DSI_MODE_VIDEO_HSE |
+ MIPI_DSI_CLOCK_NON_CONTINUOUS |
+ MIPI_DSI_MODE_NO_EOT_PACKET;
+--
+2.39.2
+
--- /dev/null
+From 06a93cdd2c7697f86a30f0d200b207885ba133dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 May 2023 10:50:39 +0200
+Subject: drm/panel: simple: fix active size for Ampire AM-480272H3TMQW-T01H
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit f24b49550814fdee4a98b9552e35e243ccafd4a8 ]
+
+The previous setting was related to the overall dimension and not to the
+active display area.
+In the "PHYSICAL SPECIFICATIONS" section, the datasheet shows the
+following parameters:
+
+ ----------------------------------------------------------
+| Item | Specifications | unit |
+ ----------------------------------------------------------
+| Display area | 98.7 (W) x 57.5 (H) | mm |
+ ----------------------------------------------------------
+| Overall dimension | 105.5(W) x 67.2(H) x 4.96(D) | mm |
+ ----------------------------------------------------------
+
+Fixes: 966fea78adf2 ("drm/panel: simple: Add support for Ampire AM-480272H3TMQW-T01H")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+[narmstrong: fixed Fixes commit id length]
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230516085039.3797303-1-dario.binacchi@amarulasolutions.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/panel-simple.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
+index 065f378bba9d2..d8efbcee9bc12 100644
+--- a/drivers/gpu/drm/panel/panel-simple.c
++++ b/drivers/gpu/drm/panel/panel-simple.c
+@@ -759,8 +759,8 @@ static const struct panel_desc ampire_am_480272h3tmqw_t01h = {
+ .num_modes = 1,
+ .bpc = 8,
+ .size = {
+- .width = 105,
+- .height = 67,
++ .width = 99,
++ .height = 58,
+ },
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+ };
+--
+2.39.2
+
--- /dev/null
+From 084f49bc429917e209346c9ee99b2b8926c65dfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 May 2023 08:33:27 -0700
+Subject: drm/radeon: fix possible division-by-zero errors
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 1becc57cd1a905e2aa0e1eca60d2a37744525c4a ]
+
+Function rv740_get_decoded_reference_divider() may return 0 due to
+unpredictable reference divider value calculated in
+radeon_atom_get_clock_dividers(). This will lead to
+division-by-zero error once that value is used as a divider
+in calculating 'clk_s'.
+While unlikely, this issue should nonetheless be prevented so add a
+sanity check for such cases by testing 'decoded_ref' value against 0.
+
+Found by Linux Verification Center (linuxtesting.org) with static
+analysis tool SVACE.
+
+v2: minor coding style fixes (Alex)
+In practice this should actually happen as the vbios should be
+properly populated.
+
+Fixes: 66229b200598 ("drm/radeon/kms: add dpm support for rv7xx (v4)")
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/cypress_dpm.c | 8 ++++++--
+ drivers/gpu/drm/radeon/ni_dpm.c | 8 ++++++--
+ drivers/gpu/drm/radeon/rv740_dpm.c | 8 ++++++--
+ 3 files changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c
+index fdddbbaecbb74..72a0768df00f7 100644
+--- a/drivers/gpu/drm/radeon/cypress_dpm.c
++++ b/drivers/gpu/drm/radeon/cypress_dpm.c
+@@ -557,8 +557,12 @@ static int cypress_populate_mclk_value(struct radeon_device *rdev,
+ ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
+ u32 reference_clock = rdev->clock.mpll.reference_freq;
+ u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
+- u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
+- u32 clk_v = ss.percentage *
++ u32 clk_s, clk_v;
++
++ if (!decoded_ref)
++ return -EINVAL;
++ clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
++ clk_v = ss.percentage *
+ (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
+
+ mpll_ss1 &= ~CLKV_MASK;
+diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
+index 672d2239293e0..3e1c1a392fb7b 100644
+--- a/drivers/gpu/drm/radeon/ni_dpm.c
++++ b/drivers/gpu/drm/radeon/ni_dpm.c
+@@ -2241,8 +2241,12 @@ static int ni_populate_mclk_value(struct radeon_device *rdev,
+ ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
+ u32 reference_clock = rdev->clock.mpll.reference_freq;
+ u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
+- u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
+- u32 clk_v = ss.percentage *
++ u32 clk_s, clk_v;
++
++ if (!decoded_ref)
++ return -EINVAL;
++ clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
++ clk_v = ss.percentage *
+ (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
+
+ mpll_ss1 &= ~CLKV_MASK;
+diff --git a/drivers/gpu/drm/radeon/rv740_dpm.c b/drivers/gpu/drm/radeon/rv740_dpm.c
+index d57a3e1df8d63..4464fd21a3029 100644
+--- a/drivers/gpu/drm/radeon/rv740_dpm.c
++++ b/drivers/gpu/drm/radeon/rv740_dpm.c
+@@ -249,8 +249,12 @@ int rv740_populate_mclk_value(struct radeon_device *rdev,
+ ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
+ u32 reference_clock = rdev->clock.mpll.reference_freq;
+ u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
+- u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
+- u32 clk_v = 0x40000 * ss.percentage *
++ u32 clk_s, clk_v;
++
++ if (!decoded_ref)
++ return -EINVAL;
++ clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
++ clk_v = 0x40000 * ss.percentage *
+ (dividers.whole_fb_div + (dividers.frac_fb_div / 8)) / (clk_s * 10000);
+
+ mpll_ss1 &= ~CLKV_MASK;
+--
+2.39.2
+
--- /dev/null
+From 333bd5fa96deb6863605a3e8c271b2f55bac2241 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Apr 2023 19:23:46 +0800
+Subject: drm: sun4i_tcon: use devm_clk_get_enabled in `sun4i_tcon_init_clocks`
+
+From: XuDong Liu <m202071377@hust.edu.cn>
+
+[ Upstream commit 123ee07ba5b7123e0ce0e0f9d64938026c16a2ce ]
+
+Smatch reports:
+drivers/gpu/drm/sun4i/sun4i_tcon.c:805 sun4i_tcon_init_clocks() warn:
+'tcon->clk' from clk_prepare_enable() not released on lines: 792,801.
+
+In the function sun4i_tcon_init_clocks(), tcon->clk and tcon->sclk0 are
+not disabled in the error handling, which affects the release of
+these variable. Although sun4i_tcon_bind(), which calls
+sun4i_tcon_init_clocks(), use sun4i_tcon_free_clocks to disable the
+variables mentioned, but the error handling branch of
+sun4i_tcon_init_clocks() ignores the required disable process.
+
+To fix this issue, use the devm_clk_get_enabled to automatically
+balance enable and disabled calls. As original implementation use
+sun4i_tcon_free_clocks() to disable clk explicitly, we delete the
+related calls and error handling that are no longer needed.
+
+Fixes: 9026e0d122ac ("drm: Add Allwinner A10 Display Engine support")
+Fixes: b14e945bda8a ("drm/sun4i: tcon: Prepare and enable TCON channel 0 clock at init")
+Fixes: 8e9240472522 ("drm/sun4i: support TCONs without channel 1")
+Fixes: 34d698f6e349 ("drm/sun4i: Add has_channel_0 TCON quirk")
+Signed-off-by: XuDong Liu <m202071377@hust.edu.cn>
+Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230430112347.4689-1-m202071377@hust.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/sun4i/sun4i_tcon.c | 19 ++++---------------
+ 1 file changed, 4 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
+index 523a6d7879210..936796851ffd3 100644
+--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
+@@ -778,21 +778,19 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private)
+ static int sun4i_tcon_init_clocks(struct device *dev,
+ struct sun4i_tcon *tcon)
+ {
+- tcon->clk = devm_clk_get(dev, "ahb");
++ tcon->clk = devm_clk_get_enabled(dev, "ahb");
+ if (IS_ERR(tcon->clk)) {
+ dev_err(dev, "Couldn't get the TCON bus clock\n");
+ return PTR_ERR(tcon->clk);
+ }
+- clk_prepare_enable(tcon->clk);
+
+ if (tcon->quirks->has_channel_0) {
+- tcon->sclk0 = devm_clk_get(dev, "tcon-ch0");
++ tcon->sclk0 = devm_clk_get_enabled(dev, "tcon-ch0");
+ if (IS_ERR(tcon->sclk0)) {
+ dev_err(dev, "Couldn't get the TCON channel 0 clock\n");
+ return PTR_ERR(tcon->sclk0);
+ }
+ }
+- clk_prepare_enable(tcon->sclk0);
+
+ if (tcon->quirks->has_channel_1) {
+ tcon->sclk1 = devm_clk_get(dev, "tcon-ch1");
+@@ -805,12 +803,6 @@ static int sun4i_tcon_init_clocks(struct device *dev,
+ return 0;
+ }
+
+-static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon)
+-{
+- clk_disable_unprepare(tcon->sclk0);
+- clk_disable_unprepare(tcon->clk);
+-}
+-
+ static int sun4i_tcon_init_irq(struct device *dev,
+ struct sun4i_tcon *tcon)
+ {
+@@ -1223,14 +1215,14 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
+ ret = sun4i_tcon_init_regmap(dev, tcon);
+ if (ret) {
+ dev_err(dev, "Couldn't init our TCON regmap\n");
+- goto err_free_clocks;
++ goto err_assert_reset;
+ }
+
+ if (tcon->quirks->has_channel_0) {
+ ret = sun4i_dclk_create(dev, tcon);
+ if (ret) {
+ dev_err(dev, "Couldn't create our TCON dot clock\n");
+- goto err_free_clocks;
++ goto err_assert_reset;
+ }
+ }
+
+@@ -1293,8 +1285,6 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
+ err_free_dotclock:
+ if (tcon->quirks->has_channel_0)
+ sun4i_dclk_free(tcon);
+-err_free_clocks:
+- sun4i_tcon_free_clocks(tcon);
+ err_assert_reset:
+ reset_control_assert(tcon->lcd_rst);
+ return ret;
+@@ -1308,7 +1298,6 @@ static void sun4i_tcon_unbind(struct device *dev, struct device *master,
+ list_del(&tcon->list);
+ if (tcon->quirks->has_channel_0)
+ sun4i_dclk_free(tcon);
+- sun4i_tcon_free_clocks(tcon);
+ }
+
+ static const struct component_ops sun4i_tcon_ops = {
+--
+2.39.2
+
--- /dev/null
+From 6e216356e8c21557c692abb814a0a1fb1a9c17b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 07:40:45 -0300
+Subject: drm/vkms: Fix RGB565 pixel conversion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+[ Upstream commit ab87f558dcfb2562c3497e89600dec798a446665 ]
+
+Currently, the pixel conversion isn't rounding the fixed-point values
+before assigning it to the RGB coefficients, which is causing the IGT
+pixel-format tests to fail. So, use the drm_fixp2int_round() fixed-point
+helper to round the values when assigning it to the RGB coefficients.
+
+Tested with igt@kms_plane@pixel-format and igt@kms_plane@pixel-format-source-clamping.
+
+[v2]:
+ * Use drm_fixp2int_round() to fix the pixel conversion instead of
+ casting the values to s32 (Melissa Wen).
+
+Fixes: 89b03aeaef16 ("drm/vkms: fix 32bit compilation error by replacing macros")
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Reviewed-by: Arthur Grillo <arthurgrillo@riseup.net>
+Signed-off-by: Maíra Canal <mairacanal@riseup.net>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230512104044.65034-2-mcanal@igalia.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vkms/vkms_formats.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
+index 8d948c73741ef..b11342026485f 100644
+--- a/drivers/gpu/drm/vkms/vkms_formats.c
++++ b/drivers/gpu/drm/vkms/vkms_formats.c
+@@ -97,9 +97,9 @@ static void RGB565_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
+ s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
+
+ out_pixel->a = (u16)0xffff;
+- out_pixel->r = drm_fixp2int(drm_fixp_mul(fp_r, fp_rb_ratio));
+- out_pixel->g = drm_fixp2int(drm_fixp_mul(fp_g, fp_g_ratio));
+- out_pixel->b = drm_fixp2int(drm_fixp_mul(fp_b, fp_rb_ratio));
++ out_pixel->r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio));
++ out_pixel->g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio));
++ out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
+ }
+
+ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y)
+@@ -216,9 +216,9 @@ static void argb_u16_to_RGB565(struct vkms_frame_info *frame_info,
+ s64 fp_g = drm_int2fixp(in_pixels[x].g);
+ s64 fp_b = drm_int2fixp(in_pixels[x].b);
+
+- u16 r = drm_fixp2int(drm_fixp_div(fp_r, fp_rb_ratio));
+- u16 g = drm_fixp2int(drm_fixp_div(fp_g, fp_g_ratio));
+- u16 b = drm_fixp2int(drm_fixp_div(fp_b, fp_rb_ratio));
++ u16 r = drm_fixp2int_round(drm_fixp_div(fp_r, fp_rb_ratio));
++ u16 g = drm_fixp2int_round(drm_fixp_div(fp_g, fp_g_ratio));
++ u16 b = drm_fixp2int_round(drm_fixp_div(fp_b, fp_rb_ratio));
+
+ *dst_pixels = cpu_to_le16(r << 11 | g << 5 | b);
+ }
+--
+2.39.2
+
--- /dev/null
+From 1e165fb0f18862316761e76b5326617e29919259 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Apr 2023 10:05:21 -0300
+Subject: drm/vkms: isolate pixel conversion functionality
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+[ Upstream commit 322d716a3e8a74fb75cd0f657647be4df253fd2f ]
+
+Currently, the pixel conversion functions repeat the same loop to
+iterate the rows. Instead of repeating the same code for each pixel
+format, create a function to wrap the loop and isolate the pixel
+conversion functionality.
+
+Suggested-by: Arthur Grillo <arthurgrillo@riseup.net>
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Reviewed-by: Arthur Grillo <arthurgrillo@riseup.net>
+Signed-off-by: Maíra Canal <mairacanal@riseup.net>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230418130525.128733-2-mcanal@igalia.com
+Stable-dep-of: ab87f558dcfb ("drm/vkms: Fix RGB565 pixel conversion")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vkms/vkms_composer.c | 4 +-
+ drivers/gpu/drm/vkms/vkms_drv.h | 4 +-
+ drivers/gpu/drm/vkms/vkms_formats.c | 125 +++++++++++----------------
+ drivers/gpu/drm/vkms/vkms_formats.h | 2 +-
+ drivers/gpu/drm/vkms/vkms_plane.c | 2 +-
+ 5 files changed, 56 insertions(+), 81 deletions(-)
+
+diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
+index 8e53fa80742b2..80164e79af006 100644
+--- a/drivers/gpu/drm/vkms/vkms_composer.c
++++ b/drivers/gpu/drm/vkms/vkms_composer.c
+@@ -99,7 +99,7 @@ static void blend(struct vkms_writeback_job *wb,
+ if (!check_y_limit(plane[i]->frame_info, y))
+ continue;
+
+- plane[i]->plane_read(stage_buffer, plane[i]->frame_info, y);
++ vkms_compose_row(stage_buffer, plane[i], y);
+ pre_mul_alpha_blend(plane[i]->frame_info, stage_buffer,
+ output_buffer);
+ }
+@@ -118,7 +118,7 @@ static int check_format_funcs(struct vkms_crtc_state *crtc_state,
+ u32 n_active_planes = crtc_state->num_active_planes;
+
+ for (size_t i = 0; i < n_active_planes; i++)
+- if (!planes[i]->plane_read)
++ if (!planes[i]->pixel_read)
+ return -1;
+
+ if (active_wb && !active_wb->wb_write)
+diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
+index 4a248567efb26..f152d54baf769 100644
+--- a/drivers/gpu/drm/vkms/vkms_drv.h
++++ b/drivers/gpu/drm/vkms/vkms_drv.h
+@@ -56,8 +56,7 @@ struct vkms_writeback_job {
+ struct vkms_plane_state {
+ struct drm_shadow_plane_state base;
+ struct vkms_frame_info *frame_info;
+- void (*plane_read)(struct line_buffer *buffer,
+- const struct vkms_frame_info *frame_info, int y);
++ void (*pixel_read)(u8 *src_buffer, struct pixel_argb_u16 *out_pixel);
+ };
+
+ struct vkms_plane {
+@@ -155,6 +154,7 @@ int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
+ /* Composer Support */
+ void vkms_composer_worker(struct work_struct *work);
+ void vkms_set_composer(struct vkms_output *out, bool enabled);
++void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y);
+
+ /* Writeback */
+ int vkms_enable_writeback_connector(struct vkms_device *vkmsdev);
+diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
+index d4950688b3f17..8d948c73741ef 100644
+--- a/drivers/gpu/drm/vkms/vkms_formats.c
++++ b/drivers/gpu/drm/vkms/vkms_formats.c
+@@ -42,100 +42,75 @@ static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int y
+ return packed_pixels_addr(frame_info, x_src, y_src);
+ }
+
+-static void ARGB8888_to_argb_u16(struct line_buffer *stage_buffer,
+- const struct vkms_frame_info *frame_info, int y)
++static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
+ {
+- struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
+- u8 *src_pixels = get_packed_src_addr(frame_info, y);
+- int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
+- stage_buffer->n_pixels);
+-
+- for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
+- /*
+- * The 257 is the "conversion ratio". This number is obtained by the
+- * (2^16 - 1) / (2^8 - 1) division. Which, in this case, tries to get
+- * the best color value in a pixel format with more possibilities.
+- * A similar idea applies to others RGB color conversions.
+- */
+- out_pixels[x].a = (u16)src_pixels[3] * 257;
+- out_pixels[x].r = (u16)src_pixels[2] * 257;
+- out_pixels[x].g = (u16)src_pixels[1] * 257;
+- out_pixels[x].b = (u16)src_pixels[0] * 257;
+- }
++ /*
++ * The 257 is the "conversion ratio". This number is obtained by the
++ * (2^16 - 1) / (2^8 - 1) division. Which, in this case, tries to get
++ * the best color value in a pixel format with more possibilities.
++ * A similar idea applies to others RGB color conversions.
++ */
++ out_pixel->a = (u16)src_pixels[3] * 257;
++ out_pixel->r = (u16)src_pixels[2] * 257;
++ out_pixel->g = (u16)src_pixels[1] * 257;
++ out_pixel->b = (u16)src_pixels[0] * 257;
+ }
+
+-static void XRGB8888_to_argb_u16(struct line_buffer *stage_buffer,
+- const struct vkms_frame_info *frame_info, int y)
++static void XRGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
+ {
+- struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
+- u8 *src_pixels = get_packed_src_addr(frame_info, y);
+- int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
+- stage_buffer->n_pixels);
+-
+- for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
+- out_pixels[x].a = (u16)0xffff;
+- out_pixels[x].r = (u16)src_pixels[2] * 257;
+- out_pixels[x].g = (u16)src_pixels[1] * 257;
+- out_pixels[x].b = (u16)src_pixels[0] * 257;
+- }
++ out_pixel->a = (u16)0xffff;
++ out_pixel->r = (u16)src_pixels[2] * 257;
++ out_pixel->g = (u16)src_pixels[1] * 257;
++ out_pixel->b = (u16)src_pixels[0] * 257;
+ }
+
+-static void ARGB16161616_to_argb_u16(struct line_buffer *stage_buffer,
+- const struct vkms_frame_info *frame_info,
+- int y)
++static void ARGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
+ {
+- struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
+- u16 *src_pixels = get_packed_src_addr(frame_info, y);
+- int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
+- stage_buffer->n_pixels);
++ u16 *pixels = (u16 *)src_pixels;
+
+- for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
+- out_pixels[x].a = le16_to_cpu(src_pixels[3]);
+- out_pixels[x].r = le16_to_cpu(src_pixels[2]);
+- out_pixels[x].g = le16_to_cpu(src_pixels[1]);
+- out_pixels[x].b = le16_to_cpu(src_pixels[0]);
+- }
++ out_pixel->a = le16_to_cpu(pixels[3]);
++ out_pixel->r = le16_to_cpu(pixels[2]);
++ out_pixel->g = le16_to_cpu(pixels[1]);
++ out_pixel->b = le16_to_cpu(pixels[0]);
+ }
+
+-static void XRGB16161616_to_argb_u16(struct line_buffer *stage_buffer,
+- const struct vkms_frame_info *frame_info,
+- int y)
++static void XRGB16161616_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
+ {
+- struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
+- u16 *src_pixels = get_packed_src_addr(frame_info, y);
+- int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
+- stage_buffer->n_pixels);
++ u16 *pixels = (u16 *)src_pixels;
+
+- for (size_t x = 0; x < x_limit; x++, src_pixels += 4) {
+- out_pixels[x].a = (u16)0xffff;
+- out_pixels[x].r = le16_to_cpu(src_pixels[2]);
+- out_pixels[x].g = le16_to_cpu(src_pixels[1]);
+- out_pixels[x].b = le16_to_cpu(src_pixels[0]);
+- }
++ out_pixel->a = (u16)0xffff;
++ out_pixel->r = le16_to_cpu(pixels[2]);
++ out_pixel->g = le16_to_cpu(pixels[1]);
++ out_pixel->b = le16_to_cpu(pixels[0]);
+ }
+
+-static void RGB565_to_argb_u16(struct line_buffer *stage_buffer,
+- const struct vkms_frame_info *frame_info, int y)
++static void RGB565_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel)
+ {
+- struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
+- u16 *src_pixels = get_packed_src_addr(frame_info, y);
+- int x_limit = min_t(size_t, drm_rect_width(&frame_info->dst),
+- stage_buffer->n_pixels);
++ u16 *pixels = (u16 *)src_pixels;
+
+ s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31));
+ s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63));
+
+- for (size_t x = 0; x < x_limit; x++, src_pixels++) {
+- u16 rgb_565 = le16_to_cpu(*src_pixels);
+- s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f);
+- s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
+- s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
++ u16 rgb_565 = le16_to_cpu(*pixels);
++ s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f);
++ s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
++ s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
+
+- out_pixels[x].a = (u16)0xffff;
+- out_pixels[x].r = drm_fixp2int(drm_fixp_mul(fp_r, fp_rb_ratio));
+- out_pixels[x].g = drm_fixp2int(drm_fixp_mul(fp_g, fp_g_ratio));
+- out_pixels[x].b = drm_fixp2int(drm_fixp_mul(fp_b, fp_rb_ratio));
+- }
++ out_pixel->a = (u16)0xffff;
++ out_pixel->r = drm_fixp2int(drm_fixp_mul(fp_r, fp_rb_ratio));
++ out_pixel->g = drm_fixp2int(drm_fixp_mul(fp_g, fp_g_ratio));
++ out_pixel->b = drm_fixp2int(drm_fixp_mul(fp_b, fp_rb_ratio));
++}
++
++void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state *plane, int y)
++{
++ struct pixel_argb_u16 *out_pixels = stage_buffer->pixels;
++ struct vkms_frame_info *frame_info = plane->frame_info;
++ u8 *src_pixels = get_packed_src_addr(frame_info, y);
++ int limit = min_t(size_t, drm_rect_width(&frame_info->dst), stage_buffer->n_pixels);
++
++ for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp)
++ plane->pixel_read(src_pixels, &out_pixels[x]);
+ }
+
+ /*
+@@ -249,7 +224,7 @@ static void argb_u16_to_RGB565(struct vkms_frame_info *frame_info,
+ }
+ }
+
+-void *get_frame_to_line_function(u32 format)
++void *get_pixel_conversion_function(u32 format)
+ {
+ switch (format) {
+ case DRM_FORMAT_ARGB8888:
+diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
+index 43b7c19790181..c5b113495d0c0 100644
+--- a/drivers/gpu/drm/vkms/vkms_formats.h
++++ b/drivers/gpu/drm/vkms/vkms_formats.h
+@@ -5,7 +5,7 @@
+
+ #include "vkms_drv.h"
+
+-void *get_frame_to_line_function(u32 format);
++void *get_pixel_conversion_function(u32 format);
+
+ void *get_line_to_frame_function(u32 format);
+
+diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
+index b3f8a115cc234..eaee51358a49b 100644
+--- a/drivers/gpu/drm/vkms/vkms_plane.c
++++ b/drivers/gpu/drm/vkms/vkms_plane.c
+@@ -123,7 +123,7 @@ static void vkms_plane_atomic_update(struct drm_plane *plane,
+ frame_info->offset = fb->offsets[0];
+ frame_info->pitch = fb->pitches[0];
+ frame_info->cpp = fb->format->cpp[0];
+- vkms_plane_state->plane_read = get_frame_to_line_function(fmt);
++ vkms_plane_state->pixel_read = get_pixel_conversion_function(fmt);
+ }
+
+ static int vkms_plane_atomic_check(struct drm_plane *plane,
+--
+2.39.2
+
--- /dev/null
+From 4a8b67cd6e249f8e462da1a74b9d3063c9b4df22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 May 2023 08:09:16 +0800
+Subject: drm/vram-helper: fix function names in vram helper doc
+
+From: Luc Ma <luc@sietium.com>
+
+[ Upstream commit b8e392245105b50706f18418054821e71e637288 ]
+
+Refer to drmm_vram_helper_init() instead of the non-existent
+drmm_vram_helper_alloc_mm().
+
+Fixes: a5f23a72355d ("drm/vram-helper: Managed vram helpers")
+Signed-off-by: Luc Ma <luc@sietium.com>
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/64583db2.630a0220.eb75d.8f51@mx.google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_gem_vram_helper.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c
+index d40b3edb52d07..f1539d4448c69 100644
+--- a/drivers/gpu/drm/drm_gem_vram_helper.c
++++ b/drivers/gpu/drm/drm_gem_vram_helper.c
+@@ -45,7 +45,7 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
+ * the frame's scanout buffer or the cursor image. If there's no more space
+ * left in VRAM, inactive GEM objects can be moved to system memory.
+ *
+- * To initialize the VRAM helper library call drmm_vram_helper_alloc_mm().
++ * To initialize the VRAM helper library call drmm_vram_helper_init().
+ * The function allocates and initializes an instance of &struct drm_vram_mm
+ * in &struct drm_device.vram_mm . Use &DRM_GEM_VRAM_DRIVER to initialize
+ * &struct drm_driver and &DRM_VRAM_MM_FILE_OPERATIONS to initialize
+@@ -73,7 +73,7 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
+ * // setup device, vram base and size
+ * // ...
+ *
+- * ret = drmm_vram_helper_alloc_mm(dev, vram_base, vram_size);
++ * ret = drmm_vram_helper_init(dev, vram_base, vram_size);
+ * if (ret)
+ * return ret;
+ * return 0;
+@@ -86,7 +86,7 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
+ * to userspace.
+ *
+ * You don't have to clean up the instance of VRAM MM.
+- * drmm_vram_helper_alloc_mm() is a managed interface that installs a
++ * drmm_vram_helper_init() is a managed interface that installs a
+ * clean-up handler to run during the DRM device's release.
+ *
+ * For drawing or scanout operations, rsp. buffer objects have to be pinned
+--
+2.39.2
+
--- /dev/null
+From 9dcded5e8dbc40ce28ecd48ef2107cf65cf9c51c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jun 2023 09:33:09 +0200
+Subject: efi/libstub: Disable PCI DMA before grabbing the EFI memory map
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit 2e28a798c3092ea42b968fa16ac835969d124898 ]
+
+Currently, the EFI stub will disable PCI DMA as the very last thing it
+does before calling ExitBootServices(), to avoid interfering with the
+firmware's normal operation as much as possible.
+
+However, the stub will invoke DisconnectController() on all endpoints
+downstream of the PCI bridges it disables, and this may affect the
+layout of the EFI memory map, making it substantially more likely that
+ExitBootServices() will fail the first time around, and that the EFI
+memory map needs to be reloaded.
+
+This, in turn, increases the likelihood that the slack space we
+allocated is insufficient (and we can no longer allocate memory via boot
+services after having called ExitBootServices() once), causing the
+second call to GetMemoryMap (and therefore the boot) to fail. This makes
+the PCI DMA disable feature a bit more fragile than it already is, so
+let's make it more robust, by allocating the space for the EFI memory
+map after disabling PCI DMA.
+
+Fixes: 4444f8541dad16fe ("efi: Allow disabling PCI busmastering on bridges during boot")
+Reported-by: Glenn Washburn <development@efficientek.com>
+Acked-by: Matthew Garrett <mjg59@srcf.ucam.org>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/libstub/efi-stub-helper.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
+index 1e0203d74691f..732984295295f 100644
+--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
++++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
+@@ -378,6 +378,9 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv,
+ struct efi_boot_memmap *map;
+ efi_status_t status;
+
++ if (efi_disable_pci_dma)
++ efi_pci_disable_bridge_busmaster();
++
+ status = efi_get_memory_map(&map, true);
+ if (status != EFI_SUCCESS)
+ return status;
+@@ -388,9 +391,6 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv,
+ return status;
+ }
+
+- if (efi_disable_pci_dma)
+- efi_pci_disable_bridge_busmaster();
+-
+ status = efi_bs_call(exit_boot_services, handle, map->map_key);
+
+ if (status == EFI_INVALID_PARAMETER) {
+--
+2.39.2
+
--- /dev/null
+From 107ac67f5a5ec264382fa1e573d6fc4546997afb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 19:23:41 +0800
+Subject: erofs: fix compact 4B support for 16k block size
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+[ Upstream commit 001b8ccd0650727e54ec16ef72bf1b8eeab7168e ]
+
+In compact 4B, two adjacent lclusters are packed together as a unit to
+form on-disk indexes for effective random access, as below:
+
+(amortized = 4, vcnt = 2)
+ _____________________________________________
+ |___@_____ encoded bits __________|_ blkaddr _|
+ 0 . amortized * vcnt = 8
+ . .
+ . . amortized * vcnt - 4 = 4
+ . .
+ .____________________________.
+ |_type (2 bits)_|_clusterofs_|
+
+Therefore, encoded bits for each pack are 32 bits (4 bytes). IOWs,
+since each lcluster can get 16 bits for its type and clusterofs, the
+maximum supported lclustersize for compact 4B format is 16k (14 bits).
+
+Fix this to enable compact 4B format for 16k lclusters (blocks), which
+is tested on an arm64 server with 16k page size.
+
+Fixes: 152a333a5895 ("staging: erofs: add compacted compression indexes support")
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20230601112341.56960-1-hsiangkao@linux.alibaba.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/zmap.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
+index b5f4086537548..322f110b3c8f4 100644
+--- a/fs/erofs/zmap.c
++++ b/fs/erofs/zmap.c
+@@ -148,7 +148,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
+ u8 *in, type;
+ bool big_pcluster;
+
+- if (1 << amortizedshift == 4)
++ if (1 << amortizedshift == 4 && lclusterbits <= 14)
+ vcnt = 2;
+ else if (1 << amortizedshift == 2 && lclusterbits == 12)
+ vcnt = 16;
+@@ -250,7 +250,6 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m,
+ {
+ struct inode *const inode = m->inode;
+ struct erofs_inode *const vi = EROFS_I(inode);
+- const unsigned int lclusterbits = vi->z_logical_clusterbits;
+ const erofs_off_t ebase = sizeof(struct z_erofs_map_header) +
+ ALIGN(erofs_iloc(inode) + vi->inode_isize + vi->xattr_isize, 8);
+ const unsigned int totalidx = DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ);
+@@ -258,9 +257,6 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m,
+ unsigned int amortizedshift;
+ erofs_off_t pos;
+
+- if (lclusterbits != 12)
+- return -EOPNOTSUPP;
+-
+ if (lcn >= totalidx)
+ return -EINVAL;
+
+--
+2.39.2
+
--- /dev/null
+From 3b9e86b5d28464eb8d4c1a8b2eb9a3f526441bbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 May 2023 04:14:56 +0800
+Subject: erofs: kill hooked chains to avoid loops on deduplicated compressed
+ images
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+[ Upstream commit 967c28b23f6c89bb8eef6a046ea88afe0d7c1029 ]
+
+After heavily stressing EROFS with several images which include a
+hand-crafted image of repeated patterns for more than 46 days, I found
+two chains could be linked with each other almost simultaneously and
+form a loop so that the entire loop won't be submitted. As a
+consequence, the corresponding file pages will remain locked forever.
+
+It can be _only_ observed on data-deduplicated compressed images.
+For example, consider two chains with five pclusters in total:
+ Chain 1: 2->3->4->5 -- The tail pcluster is 5;
+ Chain 2: 5->1->2 -- The tail pcluster is 2.
+
+Chain 2 could link to Chain 1 with pcluster 5; and Chain 1 could link
+to Chain 2 at the same time with pcluster 2.
+
+Since hooked chains are all linked locklessly now, I have no idea how
+to simply avoid the race. Instead, let's avoid hooked chains completely
+until I could work out a proper way to fix this and end users finally
+tell us that it's needed to add it back.
+
+Actually, this optimization can be found with multi-threaded workloads
+(especially even more often on deduplicated compressed images), yet I'm
+not sure about the overall system impacts of not having this compared
+with implementation complexity.
+
+Fixes: 267f2492c8f7 ("erofs: introduce multi-reference pclusters (fully-referenced)")
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Reviewed-by: Yue Hu <huyue2@coolpad.com>
+Link: https://lore.kernel.org/r/20230526201459.128169-4-hsiangkao@linux.alibaba.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/zdata.c | 72 ++++++++----------------------------------------
+ 1 file changed, 11 insertions(+), 61 deletions(-)
+
+diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
+index d7add72a09437..72325d4b98f9d 100644
+--- a/fs/erofs/zdata.c
++++ b/fs/erofs/zdata.c
+@@ -94,11 +94,8 @@ struct z_erofs_pcluster {
+
+ /* let's avoid the valid 32-bit kernel addresses */
+
+-/* the chained workgroup has't submitted io (still open) */
++/* the end of a chain of pclusters */
+ #define Z_EROFS_PCLUSTER_TAIL ((void *)0x5F0ECAFE)
+-/* the chained workgroup has already submitted io */
+-#define Z_EROFS_PCLUSTER_TAIL_CLOSED ((void *)0x5F0EDEAD)
+-
+ #define Z_EROFS_PCLUSTER_NIL (NULL)
+
+ struct z_erofs_decompressqueue {
+@@ -499,20 +496,6 @@ int __init z_erofs_init_zip_subsystem(void)
+
+ enum z_erofs_pclustermode {
+ Z_EROFS_PCLUSTER_INFLIGHT,
+- /*
+- * The current pclusters was the tail of an exist chain, in addition
+- * that the previous processed chained pclusters are all decided to
+- * be hooked up to it.
+- * A new chain will be created for the remaining pclusters which are
+- * not processed yet, so different from Z_EROFS_PCLUSTER_FOLLOWED,
+- * the next pcluster cannot reuse the whole page safely for inplace I/O
+- * in the following scenario:
+- * ________________________________________________________________
+- * | tail (partial) page | head (partial) page |
+- * | (belongs to the next pcl) | (belongs to the current pcl) |
+- * |_______PCLUSTER_FOLLOWED______|________PCLUSTER_HOOKED__________|
+- */
+- Z_EROFS_PCLUSTER_HOOKED,
+ /*
+ * a weak form of Z_EROFS_PCLUSTER_FOLLOWED, the difference is that it
+ * could be dispatched into bypass queue later due to uptodated managed
+@@ -530,8 +513,8 @@ enum z_erofs_pclustermode {
+ * ________________________________________________________________
+ * | tail (partial) page | head (partial) page |
+ * | (of the current cl) | (of the previous collection) |
+- * | PCLUSTER_FOLLOWED or | |
+- * |_____PCLUSTER_HOOKED__|___________PCLUSTER_FOLLOWED____________|
++ * | | |
++ * |__PCLUSTER_FOLLOWED___|___________PCLUSTER_FOLLOWED____________|
+ *
+ * [ (*) the above page can be used as inplace I/O. ]
+ */
+@@ -544,7 +527,7 @@ struct z_erofs_decompress_frontend {
+ struct z_erofs_bvec_iter biter;
+
+ struct page *candidate_bvpage;
+- struct z_erofs_pcluster *pcl, *tailpcl;
++ struct z_erofs_pcluster *pcl;
+ z_erofs_next_pcluster_t owned_head;
+ enum z_erofs_pclustermode mode;
+
+@@ -750,19 +733,7 @@ static void z_erofs_try_to_claim_pcluster(struct z_erofs_decompress_frontend *f)
+ return;
+ }
+
+- /*
+- * type 2, link to the end of an existing open chain, be careful
+- * that its submission is controlled by the original attached chain.
+- */
+- if (*owned_head != &pcl->next && pcl != f->tailpcl &&
+- cmpxchg(&pcl->next, Z_EROFS_PCLUSTER_TAIL,
+- *owned_head) == Z_EROFS_PCLUSTER_TAIL) {
+- *owned_head = Z_EROFS_PCLUSTER_TAIL;
+- f->mode = Z_EROFS_PCLUSTER_HOOKED;
+- f->tailpcl = NULL;
+- return;
+- }
+- /* type 3, it belongs to a chain, but it isn't the end of the chain */
++ /* type 2, it belongs to an ongoing chain */
+ f->mode = Z_EROFS_PCLUSTER_INFLIGHT;
+ }
+
+@@ -823,9 +794,6 @@ static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe)
+ goto err_out;
+ }
+ }
+- /* used to check tail merging loop due to corrupted images */
+- if (fe->owned_head == Z_EROFS_PCLUSTER_TAIL)
+- fe->tailpcl = pcl;
+ fe->owned_head = &pcl->next;
+ fe->pcl = pcl;
+ return 0;
+@@ -846,7 +814,6 @@ static int z_erofs_collector_begin(struct z_erofs_decompress_frontend *fe)
+
+ /* must be Z_EROFS_PCLUSTER_TAIL or pointed to previous pcluster */
+ DBG_BUGON(fe->owned_head == Z_EROFS_PCLUSTER_NIL);
+- DBG_BUGON(fe->owned_head == Z_EROFS_PCLUSTER_TAIL_CLOSED);
+
+ if (!(map->m_flags & EROFS_MAP_META)) {
+ grp = erofs_find_workgroup(fe->inode->i_sb,
+@@ -865,10 +832,6 @@ static int z_erofs_collector_begin(struct z_erofs_decompress_frontend *fe)
+
+ if (ret == -EEXIST) {
+ mutex_lock(&fe->pcl->lock);
+- /* used to check tail merging loop due to corrupted images */
+- if (fe->owned_head == Z_EROFS_PCLUSTER_TAIL)
+- fe->tailpcl = fe->pcl;
+-
+ z_erofs_try_to_claim_pcluster(fe);
+ } else if (ret) {
+ return ret;
+@@ -1025,8 +988,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe,
+ * those chains are handled asynchronously thus the page cannot be used
+ * for inplace I/O or bvpage (should be processed in a strict order.)
+ */
+- tight &= (fe->mode >= Z_EROFS_PCLUSTER_HOOKED &&
+- fe->mode != Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE);
++ tight &= (fe->mode > Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE);
+
+ cur = end - min_t(unsigned int, offset + end - map->m_la, end);
+ if (!(map->m_flags & EROFS_MAP_MAPPED)) {
+@@ -1407,10 +1369,7 @@ static void z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io,
+ };
+ z_erofs_next_pcluster_t owned = io->head;
+
+- while (owned != Z_EROFS_PCLUSTER_TAIL_CLOSED) {
+- /* impossible that 'owned' equals Z_EROFS_WORK_TPTR_TAIL */
+- DBG_BUGON(owned == Z_EROFS_PCLUSTER_TAIL);
+- /* impossible that 'owned' equals Z_EROFS_PCLUSTER_NIL */
++ while (owned != Z_EROFS_PCLUSTER_TAIL) {
+ DBG_BUGON(owned == Z_EROFS_PCLUSTER_NIL);
+
+ be.pcl = container_of(owned, struct z_erofs_pcluster, next);
+@@ -1427,7 +1386,7 @@ static void z_erofs_decompressqueue_work(struct work_struct *work)
+ container_of(work, struct z_erofs_decompressqueue, u.work);
+ struct page *pagepool = NULL;
+
+- DBG_BUGON(bgq->head == Z_EROFS_PCLUSTER_TAIL_CLOSED);
++ DBG_BUGON(bgq->head == Z_EROFS_PCLUSTER_TAIL);
+ z_erofs_decompress_queue(bgq, &pagepool);
+ erofs_release_pages(&pagepool);
+ kvfree(bgq);
+@@ -1615,7 +1574,7 @@ static struct z_erofs_decompressqueue *jobqueue_init(struct super_block *sb,
+ q->sync = true;
+ }
+ q->sb = sb;
+- q->head = Z_EROFS_PCLUSTER_TAIL_CLOSED;
++ q->head = Z_EROFS_PCLUSTER_TAIL;
+ return q;
+ }
+
+@@ -1633,11 +1592,7 @@ static void move_to_bypass_jobqueue(struct z_erofs_pcluster *pcl,
+ z_erofs_next_pcluster_t *const submit_qtail = qtail[JQ_SUBMIT];
+ z_erofs_next_pcluster_t *const bypass_qtail = qtail[JQ_BYPASS];
+
+- DBG_BUGON(owned_head == Z_EROFS_PCLUSTER_TAIL_CLOSED);
+- if (owned_head == Z_EROFS_PCLUSTER_TAIL)
+- owned_head = Z_EROFS_PCLUSTER_TAIL_CLOSED;
+-
+- WRITE_ONCE(pcl->next, Z_EROFS_PCLUSTER_TAIL_CLOSED);
++ WRITE_ONCE(pcl->next, Z_EROFS_PCLUSTER_TAIL);
+
+ WRITE_ONCE(*submit_qtail, owned_head);
+ WRITE_ONCE(*bypass_qtail, &pcl->next);
+@@ -1708,15 +1663,10 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f,
+ unsigned int i = 0;
+ bool bypass = true;
+
+- /* no possible 'owned_head' equals the following */
+- DBG_BUGON(owned_head == Z_EROFS_PCLUSTER_TAIL_CLOSED);
+ DBG_BUGON(owned_head == Z_EROFS_PCLUSTER_NIL);
+-
+ pcl = container_of(owned_head, struct z_erofs_pcluster, next);
++ owned_head = READ_ONCE(pcl->next);
+
+- /* close the main owned chain at first */
+- owned_head = cmpxchg(&pcl->next, Z_EROFS_PCLUSTER_TAIL,
+- Z_EROFS_PCLUSTER_TAIL_CLOSED);
+ if (z_erofs_is_inline_pcluster(pcl)) {
+ move_to_bypass_jobqueue(pcl, qtail, owned_head);
+ continue;
+--
+2.39.2
+
--- /dev/null
+From 1de3ba41521b33696a4229cb2e8c30c134252aab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Mar 2023 11:40:36 +0100
+Subject: evm: Complete description of evm_inode_setattr()
+
+From: Roberto Sassu <roberto.sassu@huawei.com>
+
+[ Upstream commit b1de86d4248b273cb12c4cd7d20c08d459519f7d ]
+
+Add the description for missing parameters of evm_inode_setattr() to
+avoid the warning arising with W=n compile option.
+
+Fixes: 817b54aa45db ("evm: add evm_inode_setattr to prevent updating an invalid security.evm") # v3.2+
+Fixes: c1632a0f1120 ("fs: port ->setattr() to pass mnt_idmap") # v6.3+
+Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
+Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/evm/evm_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
+index cf24c5255583c..b1c2197473a21 100644
+--- a/security/integrity/evm/evm_main.c
++++ b/security/integrity/evm/evm_main.c
+@@ -795,7 +795,9 @@ static int evm_attr_change(struct mnt_idmap *idmap,
+
+ /**
+ * evm_inode_setattr - prevent updating an invalid EVM extended attribute
++ * @idmap: idmap of the mount
+ * @dentry: pointer to the affected dentry
++ * @attr: iattr structure containing the new file attributes
+ *
+ * Permit update of file attributes when files have a valid EVM signature,
+ * except in the case of them having an immutable portable signature.
+--
+2.39.2
+
--- /dev/null
+From fcb4b4d1b1bbebe524192905920080773b79d889 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 09:41:12 +0200
+Subject: evm: Fix build warnings
+
+From: Roberto Sassu <roberto.sassu@huawei.com>
+
+[ Upstream commit 996e0a97ebd7b11cb785794e2a83c20c1add9d92 ]
+
+Fix build warnings (function parameters description) for
+evm_read_protected_xattrs(), evm_set_key() and evm_verifyxattr().
+
+Fixes: 7626676320f3 ("evm: provide a function to set the EVM key from the kernel") # v4.5+
+Fixes: 8314b6732ae4 ("ima: Define new template fields xattrnames, xattrlengths and xattrvalues") # v5.14+
+Fixes: 2960e6cb5f7c ("evm: additional parameter to pass integrity cache entry 'iint'") # v3.2+
+Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/evm/evm_crypto.c | 2 +-
+ security/integrity/evm/evm_main.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
+index 033804f5a5f20..0dae649f3740c 100644
+--- a/security/integrity/evm/evm_crypto.c
++++ b/security/integrity/evm/evm_crypto.c
+@@ -40,7 +40,7 @@ static const char evm_hmac[] = "hmac(sha1)";
+ /**
+ * evm_set_key() - set EVM HMAC key from the kernel
+ * @key: pointer to a buffer with the key data
+- * @size: length of the key data
++ * @keylen: length of the key data
+ *
+ * This function allows setting the EVM HMAC key from the kernel
+ * without using the "encrypted" key subsystem keys. It can be used
+diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
+index b1c2197473a21..c9b6e2a43478a 100644
+--- a/security/integrity/evm/evm_main.c
++++ b/security/integrity/evm/evm_main.c
+@@ -318,7 +318,6 @@ int evm_protected_xattr_if_enabled(const char *req_xattr_name)
+ /**
+ * evm_read_protected_xattrs - read EVM protected xattr names, lengths, values
+ * @dentry: dentry of the read xattrs
+- * @inode: inode of the read xattrs
+ * @buffer: buffer xattr names, lengths or values are copied to
+ * @buffer_size: size of buffer
+ * @type: n: names, l: lengths, v: values
+@@ -390,6 +389,7 @@ int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
+ * @xattr_name: requested xattr
+ * @xattr_value: requested xattr value
+ * @xattr_value_len: requested xattr value length
++ * @iint: inode integrity metadata
+ *
+ * Calculate the HMAC for the given dentry and verify it against the stored
+ * security.evm xattr. For performance, use the xattr value and length
+--
+2.39.2
+
--- /dev/null
+From f5c50b5819caef10fa7ada975f4d829e0b0f5267 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Jun 2023 17:42:28 +0200
+Subject: fbdev: omapfb: lcd_mipid: Fix an error handling path in
+ mipid_spi_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 79a3908d1ea6c35157a6d907b1a9d8ec06015e7a ]
+
+If 'mipid_detect()' fails, we must free 'md' to avoid a memory leak.
+
+Fixes: 66d2f99d0bb5 ("omapfb: add support for MIPI-DCS compatible LCDs")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/omap/lcd_mipid.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/omap/lcd_mipid.c b/drivers/video/fbdev/omap/lcd_mipid.c
+index 03cff39d392db..cc1079aad61f2 100644
+--- a/drivers/video/fbdev/omap/lcd_mipid.c
++++ b/drivers/video/fbdev/omap/lcd_mipid.c
+@@ -563,11 +563,15 @@ static int mipid_spi_probe(struct spi_device *spi)
+
+ r = mipid_detect(md);
+ if (r < 0)
+- return r;
++ goto free_md;
+
+ omapfb_register_panel(&md->panel);
+
+ return 0;
++
++free_md:
++ kfree(md);
++ return r;
+ }
+
+ static void mipid_spi_remove(struct spi_device *spi)
+--
+2.39.2
+
--- /dev/null
+From 460f7adace506af5703b1608b9e4d1fd66fdc38b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 May 2023 21:56:12 +0200
+Subject: fs: pipe: reveal missing function protoypes
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 247c8d2f9837a3e29e3b6b7a4aa9c36c37659dd4 ]
+
+A couple of functions from fs/pipe.c are used both internally
+and for the watch queue code, but the declaration is only
+visible when the latter is enabled:
+
+fs/pipe.c:1254:5: error: no previous prototype for 'pipe_resize_ring'
+fs/pipe.c:758:15: error: no previous prototype for 'account_pipe_buffers'
+fs/pipe.c:764:6: error: no previous prototype for 'too_many_pipe_buffers_soft'
+fs/pipe.c:771:6: error: no previous prototype for 'too_many_pipe_buffers_hard'
+fs/pipe.c:777:6: error: no previous prototype for 'pipe_is_unprivileged_user'
+
+Make the visible unconditionally to avoid these warnings.
+
+Fixes: c73be61cede5 ("pipe: Add general notification queue support")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Message-Id: <20230516195629.551602-1-arnd@kernel.org>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/pipe_fs_i.h | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
+index d2c3f16cf6b18..02e0086b10f6f 100644
+--- a/include/linux/pipe_fs_i.h
++++ b/include/linux/pipe_fs_i.h
+@@ -261,18 +261,14 @@ void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
+
+ extern const struct pipe_buf_operations nosteal_pipe_buf_ops;
+
+-#ifdef CONFIG_WATCH_QUEUE
+ unsigned long account_pipe_buffers(struct user_struct *user,
+ unsigned long old, unsigned long new);
+ bool too_many_pipe_buffers_soft(unsigned long user_bufs);
+ bool too_many_pipe_buffers_hard(unsigned long user_bufs);
+ bool pipe_is_unprivileged_user(void);
+-#endif
+
+ /* for F_SETPIPE_SZ and F_GETPIPE_SZ */
+-#ifdef CONFIG_WATCH_QUEUE
+ int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots);
+-#endif
+ long pipe_fcntl(struct file *, unsigned int, unsigned long arg);
+ struct pipe_inode_info *get_pipe_info(struct file *file, bool for_splice);
+
+--
+2.39.2
+
--- /dev/null
+From c624ec2666cd52dba9f0c8e4e3df57320cc77eaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Jun 2023 19:21:01 -0700
+Subject: fsverity: don't use bio_first_page_all() in fsverity_verify_bio()
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit d1f0c5ea04cd0a93309de0246278f0b22394692d ]
+
+bio_first_page_all(bio)->mapping->host is not compatible with large
+folios, since the first page of the bio is not necessarily the head page
+of the folio, and therefore it might not have the mapping pointer set.
+
+Therefore, move the dereference of ->mapping->host into
+verify_data_blocks(), which works with a folio.
+
+(Like the commit that this Fixes, this hasn't actually been tested with
+large folios yet, since the filesystems that use fs/verity/ don't
+support that yet. But based on code review, I think this is needed.)
+
+Fixes: 5d0f0e57ed90 ("fsverity: support verifying data from large folios")
+Link: https://lore.kernel.org/r/20230604022101.48342-1-ebiggers@kernel.org
+Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/verity/verify.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/fs/verity/verify.c b/fs/verity/verify.c
+index e9ae1eef5f191..cf40e2fe6ace7 100644
+--- a/fs/verity/verify.c
++++ b/fs/verity/verify.c
+@@ -256,9 +256,10 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi,
+ }
+
+ static bool
+-verify_data_blocks(struct inode *inode, struct folio *data_folio,
+- size_t len, size_t offset, unsigned long max_ra_pages)
++verify_data_blocks(struct folio *data_folio, size_t len, size_t offset,
++ unsigned long max_ra_pages)
+ {
++ struct inode *inode = data_folio->mapping->host;
+ struct fsverity_info *vi = inode->i_verity_info;
+ const unsigned int block_size = vi->tree_params.block_size;
+ u64 pos = (u64)data_folio->index << PAGE_SHIFT;
+@@ -298,7 +299,7 @@ verify_data_blocks(struct inode *inode, struct folio *data_folio,
+ */
+ bool fsverity_verify_blocks(struct folio *folio, size_t len, size_t offset)
+ {
+- return verify_data_blocks(folio->mapping->host, folio, len, offset, 0);
++ return verify_data_blocks(folio, len, offset, 0);
+ }
+ EXPORT_SYMBOL_GPL(fsverity_verify_blocks);
+
+@@ -319,7 +320,6 @@ EXPORT_SYMBOL_GPL(fsverity_verify_blocks);
+ */
+ void fsverity_verify_bio(struct bio *bio)
+ {
+- struct inode *inode = bio_first_page_all(bio)->mapping->host;
+ struct folio_iter fi;
+ unsigned long max_ra_pages = 0;
+
+@@ -337,7 +337,7 @@ void fsverity_verify_bio(struct bio *bio)
+ }
+
+ bio_for_each_folio_all(fi, bio) {
+- if (!verify_data_blocks(inode, fi.folio, fi.length, fi.offset,
++ if (!verify_data_blocks(fi.folio, fi.length, fi.offset,
+ max_ra_pages)) {
+ bio->bi_status = BLK_STS_IOERR;
+ break;
+--
+2.39.2
+
--- /dev/null
+From bc218478ab0433e37e2d3fa76ce52cb45b262b17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 22:12:16 -0700
+Subject: fsverity: use shash API instead of ahash API
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit 8fcd94add6c5c93ed3b9314456e8420914401530 ]
+
+The "ahash" API, like the other scatterlist-based crypto APIs such as
+"skcipher", comes with some well-known limitations. First, it can't
+easily be used with vmalloc addresses. Second, the request struct can't
+be allocated on the stack. This adds complexity and a possible failure
+point that needs to be worked around, e.g. using a mempool.
+
+The only benefit of ahash over "shash" is that ahash is needed to access
+traditional memory-to-memory crypto accelerators, i.e. drivers/crypto/.
+However, this style of crypto acceleration has largely fallen out of
+favor and been superseded by CPU-based acceleration or inline crypto
+engines. Also, ahash needs to be used asynchronously to take full
+advantage of such hardware, but fs/verity/ has never done this.
+
+On all systems that aren't actually using one of these ahash-only crypto
+accelerators, ahash just adds unnecessary overhead as it sits between
+the user and the underlying shash algorithms.
+
+Also, XFS is planned to cache fsverity Merkle tree blocks in the
+existing XFS buffer cache. As a result, it will be possible for a
+single Merkle tree block to be split across discontiguous pages
+(https://lore.kernel.org/r/20230405233753.GU3223426@dread.disaster.area).
+This data will need to be hashed. It is easiest to work with a vmapped
+address in this case. However, ahash is incompatible with this.
+
+Therefore, let's convert fs/verity/ from ahash to shash. This
+simplifies the code, and it should also slightly improve performance for
+everyone who wasn't actually using one of these ahash-only crypto
+accelerators, i.e. almost everyone (or maybe even everyone)!
+
+Link: https://lore.kernel.org/r/20230516052306.99600-1-ebiggers@kernel.org
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Stable-dep-of: d1f0c5ea04cd ("fsverity: don't use bio_first_page_all() in fsverity_verify_bio()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/verity/enable.c | 19 ++---
+ fs/verity/fsverity_private.h | 13 +---
+ fs/verity/hash_algs.c | 131 ++++++-----------------------------
+ fs/verity/verify.c | 109 +++++++++++------------------
+ 4 files changed, 71 insertions(+), 201 deletions(-)
+
+diff --git a/fs/verity/enable.c b/fs/verity/enable.c
+index fc4c50e5219dc..bd86b25ac084b 100644
+--- a/fs/verity/enable.c
++++ b/fs/verity/enable.c
+@@ -7,6 +7,7 @@
+
+ #include "fsverity_private.h"
+
++#include <crypto/hash.h>
+ #include <linux/mount.h>
+ #include <linux/sched/signal.h>
+ #include <linux/uaccess.h>
+@@ -20,7 +21,7 @@ struct block_buffer {
+ /* Hash a block, writing the result to the next level's pending block buffer. */
+ static int hash_one_block(struct inode *inode,
+ const struct merkle_tree_params *params,
+- struct ahash_request *req, struct block_buffer *cur)
++ struct block_buffer *cur)
+ {
+ struct block_buffer *next = cur + 1;
+ int err;
+@@ -36,8 +37,7 @@ static int hash_one_block(struct inode *inode,
+ /* Zero-pad the block if it's shorter than the block size. */
+ memset(&cur->data[cur->filled], 0, params->block_size - cur->filled);
+
+- err = fsverity_hash_block(params, inode, req, virt_to_page(cur->data),
+- offset_in_page(cur->data),
++ err = fsverity_hash_block(params, inode, cur->data,
+ &next->data[next->filled]);
+ if (err)
+ return err;
+@@ -76,7 +76,6 @@ static int build_merkle_tree(struct file *filp,
+ struct inode *inode = file_inode(filp);
+ const u64 data_size = inode->i_size;
+ const int num_levels = params->num_levels;
+- struct ahash_request *req;
+ struct block_buffer _buffers[1 + FS_VERITY_MAX_LEVELS + 1] = {};
+ struct block_buffer *buffers = &_buffers[1];
+ unsigned long level_offset[FS_VERITY_MAX_LEVELS];
+@@ -90,9 +89,6 @@ static int build_merkle_tree(struct file *filp,
+ return 0;
+ }
+
+- /* This allocation never fails, since it's mempool-backed. */
+- req = fsverity_alloc_hash_request(params->hash_alg, GFP_KERNEL);
+-
+ /*
+ * Allocate the block buffers. Buffer "-1" is for data blocks.
+ * Buffers 0 <= level < num_levels are for the actual tree levels.
+@@ -130,7 +126,7 @@ static int build_merkle_tree(struct file *filp,
+ fsverity_err(inode, "Short read of file data");
+ goto out;
+ }
+- err = hash_one_block(inode, params, req, &buffers[-1]);
++ err = hash_one_block(inode, params, &buffers[-1]);
+ if (err)
+ goto out;
+ for (level = 0; level < num_levels; level++) {
+@@ -141,8 +137,7 @@ static int build_merkle_tree(struct file *filp,
+ }
+ /* Next block at @level is full */
+
+- err = hash_one_block(inode, params, req,
+- &buffers[level]);
++ err = hash_one_block(inode, params, &buffers[level]);
+ if (err)
+ goto out;
+ err = write_merkle_tree_block(inode,
+@@ -162,8 +157,7 @@ static int build_merkle_tree(struct file *filp,
+ /* Finish all nonempty pending tree blocks. */
+ for (level = 0; level < num_levels; level++) {
+ if (buffers[level].filled != 0) {
+- err = hash_one_block(inode, params, req,
+- &buffers[level]);
++ err = hash_one_block(inode, params, &buffers[level]);
+ if (err)
+ goto out;
+ err = write_merkle_tree_block(inode,
+@@ -183,7 +177,6 @@ static int build_merkle_tree(struct file *filp,
+ out:
+ for (level = -1; level < num_levels; level++)
+ kfree(buffers[level].data);
+- fsverity_free_hash_request(params->hash_alg, req);
+ return err;
+ }
+
+diff --git a/fs/verity/fsverity_private.h b/fs/verity/fsverity_private.h
+index d34dcc033d723..8527beca2a454 100644
+--- a/fs/verity/fsverity_private.h
++++ b/fs/verity/fsverity_private.h
+@@ -11,9 +11,6 @@
+ #define pr_fmt(fmt) "fs-verity: " fmt
+
+ #include <linux/fsverity.h>
+-#include <linux/mempool.h>
+-
+-struct ahash_request;
+
+ /*
+ * Implementation limit: maximum depth of the Merkle tree. For now 8 is plenty;
+@@ -23,11 +20,10 @@ struct ahash_request;
+
+ /* A hash algorithm supported by fs-verity */
+ struct fsverity_hash_alg {
+- struct crypto_ahash *tfm; /* hash tfm, allocated on demand */
++ struct crypto_shash *tfm; /* hash tfm, allocated on demand */
+ const char *name; /* crypto API name, e.g. sha256 */
+ unsigned int digest_size; /* digest size in bytes, e.g. 32 for SHA-256 */
+ unsigned int block_size; /* block size in bytes, e.g. 64 for SHA-256 */
+- mempool_t req_pool; /* mempool with a preallocated hash request */
+ /*
+ * The HASH_ALGO_* constant for this algorithm. This is different from
+ * FS_VERITY_HASH_ALG_*, which uses a different numbering scheme.
+@@ -85,15 +81,10 @@ extern struct fsverity_hash_alg fsverity_hash_algs[];
+
+ struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode,
+ unsigned int num);
+-struct ahash_request *fsverity_alloc_hash_request(struct fsverity_hash_alg *alg,
+- gfp_t gfp_flags);
+-void fsverity_free_hash_request(struct fsverity_hash_alg *alg,
+- struct ahash_request *req);
+ const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
+ const u8 *salt, size_t salt_size);
+ int fsverity_hash_block(const struct merkle_tree_params *params,
+- const struct inode *inode, struct ahash_request *req,
+- struct page *page, unsigned int offset, u8 *out);
++ const struct inode *inode, const void *data, u8 *out);
+ int fsverity_hash_buffer(struct fsverity_hash_alg *alg,
+ const void *data, size_t size, u8 *out);
+ void __init fsverity_check_hash_algs(void);
+diff --git a/fs/verity/hash_algs.c b/fs/verity/hash_algs.c
+index ea00dbedf756b..e7e982412e23a 100644
+--- a/fs/verity/hash_algs.c
++++ b/fs/verity/hash_algs.c
+@@ -8,7 +8,6 @@
+ #include "fsverity_private.h"
+
+ #include <crypto/hash.h>
+-#include <linux/scatterlist.h>
+
+ /* The hash algorithms supported by fs-verity */
+ struct fsverity_hash_alg fsverity_hash_algs[] = {
+@@ -44,7 +43,7 @@ struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode,
+ unsigned int num)
+ {
+ struct fsverity_hash_alg *alg;
+- struct crypto_ahash *tfm;
++ struct crypto_shash *tfm;
+ int err;
+
+ if (num >= ARRAY_SIZE(fsverity_hash_algs) ||
+@@ -63,11 +62,7 @@ struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode,
+ if (alg->tfm != NULL)
+ goto out_unlock;
+
+- /*
+- * Using the shash API would make things a bit simpler, but the ahash
+- * API is preferable as it allows the use of crypto accelerators.
+- */
+- tfm = crypto_alloc_ahash(alg->name, 0, 0);
++ tfm = crypto_alloc_shash(alg->name, 0, 0);
+ if (IS_ERR(tfm)) {
+ if (PTR_ERR(tfm) == -ENOENT) {
+ fsverity_warn(inode,
+@@ -84,68 +79,26 @@ struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode,
+ }
+
+ err = -EINVAL;
+- if (WARN_ON_ONCE(alg->digest_size != crypto_ahash_digestsize(tfm)))
++ if (WARN_ON_ONCE(alg->digest_size != crypto_shash_digestsize(tfm)))
+ goto err_free_tfm;
+- if (WARN_ON_ONCE(alg->block_size != crypto_ahash_blocksize(tfm)))
+- goto err_free_tfm;
+-
+- err = mempool_init_kmalloc_pool(&alg->req_pool, 1,
+- sizeof(struct ahash_request) +
+- crypto_ahash_reqsize(tfm));
+- if (err)
++ if (WARN_ON_ONCE(alg->block_size != crypto_shash_blocksize(tfm)))
+ goto err_free_tfm;
+
+ pr_info("%s using implementation \"%s\"\n",
+- alg->name, crypto_ahash_driver_name(tfm));
++ alg->name, crypto_shash_driver_name(tfm));
+
+ /* pairs with smp_load_acquire() above */
+ smp_store_release(&alg->tfm, tfm);
+ goto out_unlock;
+
+ err_free_tfm:
+- crypto_free_ahash(tfm);
++ crypto_free_shash(tfm);
+ alg = ERR_PTR(err);
+ out_unlock:
+ mutex_unlock(&fsverity_hash_alg_init_mutex);
+ return alg;
+ }
+
+-/**
+- * fsverity_alloc_hash_request() - allocate a hash request object
+- * @alg: the hash algorithm for which to allocate the request
+- * @gfp_flags: memory allocation flags
+- *
+- * This is mempool-backed, so this never fails if __GFP_DIRECT_RECLAIM is set in
+- * @gfp_flags. However, in that case this might need to wait for all
+- * previously-allocated requests to be freed. So to avoid deadlocks, callers
+- * must never need multiple requests at a time to make forward progress.
+- *
+- * Return: the request object on success; NULL on failure (but see above)
+- */
+-struct ahash_request *fsverity_alloc_hash_request(struct fsverity_hash_alg *alg,
+- gfp_t gfp_flags)
+-{
+- struct ahash_request *req = mempool_alloc(&alg->req_pool, gfp_flags);
+-
+- if (req)
+- ahash_request_set_tfm(req, alg->tfm);
+- return req;
+-}
+-
+-/**
+- * fsverity_free_hash_request() - free a hash request object
+- * @alg: the hash algorithm
+- * @req: the hash request object to free
+- */
+-void fsverity_free_hash_request(struct fsverity_hash_alg *alg,
+- struct ahash_request *req)
+-{
+- if (req) {
+- ahash_request_zero(req);
+- mempool_free(req, &alg->req_pool);
+- }
+-}
+-
+ /**
+ * fsverity_prepare_hash_state() - precompute the initial hash state
+ * @alg: hash algorithm
+@@ -159,23 +112,20 @@ const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
+ const u8 *salt, size_t salt_size)
+ {
+ u8 *hashstate = NULL;
+- struct ahash_request *req = NULL;
++ SHASH_DESC_ON_STACK(desc, alg->tfm);
+ u8 *padded_salt = NULL;
+ size_t padded_salt_size;
+- struct scatterlist sg;
+- DECLARE_CRYPTO_WAIT(wait);
+ int err;
+
++ desc->tfm = alg->tfm;
++
+ if (salt_size == 0)
+ return NULL;
+
+- hashstate = kmalloc(crypto_ahash_statesize(alg->tfm), GFP_KERNEL);
++ hashstate = kmalloc(crypto_shash_statesize(alg->tfm), GFP_KERNEL);
+ if (!hashstate)
+ return ERR_PTR(-ENOMEM);
+
+- /* This allocation never fails, since it's mempool-backed. */
+- req = fsverity_alloc_hash_request(alg, GFP_KERNEL);
+-
+ /*
+ * Zero-pad the salt to the next multiple of the input size of the hash
+ * algorithm's compression function, e.g. 64 bytes for SHA-256 or 128
+@@ -190,26 +140,18 @@ const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
+ goto err_free;
+ }
+ memcpy(padded_salt, salt, salt_size);
+-
+- sg_init_one(&sg, padded_salt, padded_salt_size);
+- ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
+- CRYPTO_TFM_REQ_MAY_BACKLOG,
+- crypto_req_done, &wait);
+- ahash_request_set_crypt(req, &sg, NULL, padded_salt_size);
+-
+- err = crypto_wait_req(crypto_ahash_init(req), &wait);
++ err = crypto_shash_init(desc);
+ if (err)
+ goto err_free;
+
+- err = crypto_wait_req(crypto_ahash_update(req), &wait);
++ err = crypto_shash_update(desc, padded_salt, padded_salt_size);
+ if (err)
+ goto err_free;
+
+- err = crypto_ahash_export(req, hashstate);
++ err = crypto_shash_export(desc, hashstate);
+ if (err)
+ goto err_free;
+ out:
+- fsverity_free_hash_request(alg, req);
+ kfree(padded_salt);
+ return hashstate;
+
+@@ -223,9 +165,7 @@ const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
+ * fsverity_hash_block() - hash a single data or hash block
+ * @params: the Merkle tree's parameters
+ * @inode: inode for which the hashing is being done
+- * @req: preallocated hash request
+- * @page: the page containing the block to hash
+- * @offset: the offset of the block within @page
++ * @data: virtual address of a buffer containing the block to hash
+ * @out: output digest, size 'params->digest_size' bytes
+ *
+ * Hash a single data or hash block. The hash is salted if a salt is specified
+@@ -234,33 +174,24 @@ const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
+ * Return: 0 on success, -errno on failure
+ */
+ int fsverity_hash_block(const struct merkle_tree_params *params,
+- const struct inode *inode, struct ahash_request *req,
+- struct page *page, unsigned int offset, u8 *out)
++ const struct inode *inode, const void *data, u8 *out)
+ {
+- struct scatterlist sg;
+- DECLARE_CRYPTO_WAIT(wait);
++ SHASH_DESC_ON_STACK(desc, params->hash_alg->tfm);
+ int err;
+
+- sg_init_table(&sg, 1);
+- sg_set_page(&sg, page, params->block_size, offset);
+- ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
+- CRYPTO_TFM_REQ_MAY_BACKLOG,
+- crypto_req_done, &wait);
+- ahash_request_set_crypt(req, &sg, out, params->block_size);
++ desc->tfm = params->hash_alg->tfm;
+
+ if (params->hashstate) {
+- err = crypto_ahash_import(req, params->hashstate);
++ err = crypto_shash_import(desc, params->hashstate);
+ if (err) {
+ fsverity_err(inode,
+ "Error %d importing hash state", err);
+ return err;
+ }
+- err = crypto_ahash_finup(req);
++ err = crypto_shash_finup(desc, data, params->block_size, out);
+ } else {
+- err = crypto_ahash_digest(req);
++ err = crypto_shash_digest(desc, data, params->block_size, out);
+ }
+-
+- err = crypto_wait_req(err, &wait);
+ if (err)
+ fsverity_err(inode, "Error %d computing block hash", err);
+ return err;
+@@ -273,32 +204,12 @@ int fsverity_hash_block(const struct merkle_tree_params *params,
+ * @size: size of data to hash, in bytes
+ * @out: output digest, size 'alg->digest_size' bytes
+ *
+- * Hash some data which is located in physically contiguous memory (i.e. memory
+- * allocated by kmalloc(), not by vmalloc()). No salt is used.
+- *
+ * Return: 0 on success, -errno on failure
+ */
+ int fsverity_hash_buffer(struct fsverity_hash_alg *alg,
+ const void *data, size_t size, u8 *out)
+ {
+- struct ahash_request *req;
+- struct scatterlist sg;
+- DECLARE_CRYPTO_WAIT(wait);
+- int err;
+-
+- /* This allocation never fails, since it's mempool-backed. */
+- req = fsverity_alloc_hash_request(alg, GFP_KERNEL);
+-
+- sg_init_one(&sg, data, size);
+- ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
+- CRYPTO_TFM_REQ_MAY_BACKLOG,
+- crypto_req_done, &wait);
+- ahash_request_set_crypt(req, &sg, out, size);
+-
+- err = crypto_wait_req(crypto_ahash_digest(req), &wait);
+-
+- fsverity_free_hash_request(alg, req);
+- return err;
++ return crypto_shash_tfm_digest(alg->tfm, data, size, out);
+ }
+
+ void __init fsverity_check_hash_algs(void)
+diff --git a/fs/verity/verify.c b/fs/verity/verify.c
+index e2508222750b3..e9ae1eef5f191 100644
+--- a/fs/verity/verify.c
++++ b/fs/verity/verify.c
+@@ -29,21 +29,6 @@ static inline int cmp_hashes(const struct fsverity_info *vi,
+ return -EBADMSG;
+ }
+
+-static bool data_is_zeroed(struct inode *inode, struct page *page,
+- unsigned int len, unsigned int offset)
+-{
+- void *virt = kmap_local_page(page);
+-
+- if (memchr_inv(virt + offset, 0, len)) {
+- kunmap_local(virt);
+- fsverity_err(inode,
+- "FILE CORRUPTED! Data past EOF is not zeroed");
+- return false;
+- }
+- kunmap_local(virt);
+- return true;
+-}
+-
+ /*
+ * Returns true if the hash block with index @hblock_idx in the tree, located in
+ * @hpage, has already been verified.
+@@ -122,9 +107,7 @@ static bool is_hash_block_verified(struct fsverity_info *vi, struct page *hpage,
+ */
+ static bool
+ verify_data_block(struct inode *inode, struct fsverity_info *vi,
+- struct ahash_request *req, struct page *data_page,
+- u64 data_pos, unsigned int dblock_offset_in_page,
+- unsigned long max_ra_pages)
++ const void *data, u64 data_pos, unsigned long max_ra_pages)
+ {
+ const struct merkle_tree_params *params = &vi->tree_params;
+ const unsigned int hsize = params->digest_size;
+@@ -136,11 +119,11 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi,
+ struct {
+ /* Page containing the hash block */
+ struct page *page;
++ /* Mapped address of the hash block (will be within @page) */
++ const void *addr;
+ /* Index of the hash block in the tree overall */
+ unsigned long index;
+- /* Byte offset of the hash block within @page */
+- unsigned int offset_in_page;
+- /* Byte offset of the wanted hash within @page */
++ /* Byte offset of the wanted hash relative to @addr */
+ unsigned int hoffset;
+ } hblocks[FS_VERITY_MAX_LEVELS];
+ /*
+@@ -150,6 +133,9 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi,
+ u64 hidx = data_pos >> params->log_blocksize;
+ int err;
+
++ /* Up to 1 + FS_VERITY_MAX_LEVELS pages may be mapped at once */
++ BUILD_BUG_ON(1 + FS_VERITY_MAX_LEVELS > KM_MAX_IDX);
++
+ if (unlikely(data_pos >= inode->i_size)) {
+ /*
+ * This can happen in the data page spanning EOF when the Merkle
+@@ -159,8 +145,12 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi,
+ * any part past EOF should be all zeroes. Therefore, we need
+ * to verify that any data blocks fully past EOF are all zeroes.
+ */
+- return data_is_zeroed(inode, data_page, params->block_size,
+- dblock_offset_in_page);
++ if (memchr_inv(data, 0, params->block_size)) {
++ fsverity_err(inode,
++ "FILE CORRUPTED! Data past EOF is not zeroed");
++ return false;
++ }
++ return true;
+ }
+
+ /*
+@@ -175,6 +165,7 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi,
+ unsigned int hblock_offset_in_page;
+ unsigned int hoffset;
+ struct page *hpage;
++ const void *haddr;
+
+ /*
+ * The index of the block in the current level; also the index
+@@ -192,10 +183,9 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi,
+ hblock_offset_in_page =
+ (hblock_idx << params->log_blocksize) & ~PAGE_MASK;
+
+- /* Byte offset of the hash within the page */
+- hoffset = hblock_offset_in_page +
+- ((hidx << params->log_digestsize) &
+- (params->block_size - 1));
++ /* Byte offset of the hash within the block */
++ hoffset = (hidx << params->log_digestsize) &
++ (params->block_size - 1);
+
+ hpage = inode->i_sb->s_vop->read_merkle_tree_page(inode,
+ hpage_idx, level == 0 ? min(max_ra_pages,
+@@ -207,15 +197,17 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi,
+ err, hpage_idx);
+ goto out;
+ }
++ haddr = kmap_local_page(hpage) + hblock_offset_in_page;
+ if (is_hash_block_verified(vi, hpage, hblock_idx)) {
+- memcpy_from_page(_want_hash, hpage, hoffset, hsize);
++ memcpy(_want_hash, haddr + hoffset, hsize);
+ want_hash = _want_hash;
++ kunmap_local(haddr);
+ put_page(hpage);
+ goto descend;
+ }
+ hblocks[level].page = hpage;
++ hblocks[level].addr = haddr;
+ hblocks[level].index = hblock_idx;
+- hblocks[level].offset_in_page = hblock_offset_in_page;
+ hblocks[level].hoffset = hoffset;
+ hidx = next_hidx;
+ }
+@@ -225,13 +217,11 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi,
+ /* Descend the tree verifying hash blocks. */
+ for (; level > 0; level--) {
+ struct page *hpage = hblocks[level - 1].page;
++ const void *haddr = hblocks[level - 1].addr;
+ unsigned long hblock_idx = hblocks[level - 1].index;
+- unsigned int hblock_offset_in_page =
+- hblocks[level - 1].offset_in_page;
+ unsigned int hoffset = hblocks[level - 1].hoffset;
+
+- err = fsverity_hash_block(params, inode, req, hpage,
+- hblock_offset_in_page, real_hash);
++ err = fsverity_hash_block(params, inode, haddr, real_hash);
+ if (err)
+ goto out;
+ err = cmp_hashes(vi, want_hash, real_hash, data_pos, level - 1);
+@@ -246,29 +236,30 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi,
+ set_bit(hblock_idx, vi->hash_block_verified);
+ else
+ SetPageChecked(hpage);
+- memcpy_from_page(_want_hash, hpage, hoffset, hsize);
++ memcpy(_want_hash, haddr + hoffset, hsize);
+ want_hash = _want_hash;
++ kunmap_local(haddr);
+ put_page(hpage);
+ }
+
+ /* Finally, verify the data block. */
+- err = fsverity_hash_block(params, inode, req, data_page,
+- dblock_offset_in_page, real_hash);
++ err = fsverity_hash_block(params, inode, data, real_hash);
+ if (err)
+ goto out;
+ err = cmp_hashes(vi, want_hash, real_hash, data_pos, -1);
+ out:
+- for (; level > 0; level--)
++ for (; level > 0; level--) {
++ kunmap_local(hblocks[level - 1].addr);
+ put_page(hblocks[level - 1].page);
+-
++ }
+ return err == 0;
+ }
+
+ static bool
+-verify_data_blocks(struct inode *inode, struct fsverity_info *vi,
+- struct ahash_request *req, struct folio *data_folio,
++verify_data_blocks(struct inode *inode, struct folio *data_folio,
+ size_t len, size_t offset, unsigned long max_ra_pages)
+ {
++ struct fsverity_info *vi = inode->i_verity_info;
+ const unsigned int block_size = vi->tree_params.block_size;
+ u64 pos = (u64)data_folio->index << PAGE_SHIFT;
+
+@@ -278,11 +269,14 @@ verify_data_blocks(struct inode *inode, struct fsverity_info *vi,
+ folio_test_uptodate(data_folio)))
+ return false;
+ do {
+- struct page *data_page =
+- folio_page(data_folio, offset >> PAGE_SHIFT);
+-
+- if (!verify_data_block(inode, vi, req, data_page, pos + offset,
+- offset & ~PAGE_MASK, max_ra_pages))
++ void *data;
++ bool valid;
++
++ data = kmap_local_folio(data_folio, offset);
++ valid = verify_data_block(inode, vi, data, pos + offset,
++ max_ra_pages);
++ kunmap_local(data);
++ if (!valid)
+ return false;
+ offset += block_size;
+ len -= block_size;
+@@ -304,19 +298,7 @@ verify_data_blocks(struct inode *inode, struct fsverity_info *vi,
+ */
+ bool fsverity_verify_blocks(struct folio *folio, size_t len, size_t offset)
+ {
+- struct inode *inode = folio->mapping->host;
+- struct fsverity_info *vi = inode->i_verity_info;
+- struct ahash_request *req;
+- bool valid;
+-
+- /* This allocation never fails, since it's mempool-backed. */
+- req = fsverity_alloc_hash_request(vi->tree_params.hash_alg, GFP_NOFS);
+-
+- valid = verify_data_blocks(inode, vi, req, folio, len, offset, 0);
+-
+- fsverity_free_hash_request(vi->tree_params.hash_alg, req);
+-
+- return valid;
++ return verify_data_blocks(folio->mapping->host, folio, len, offset, 0);
+ }
+ EXPORT_SYMBOL_GPL(fsverity_verify_blocks);
+
+@@ -338,14 +320,9 @@ EXPORT_SYMBOL_GPL(fsverity_verify_blocks);
+ void fsverity_verify_bio(struct bio *bio)
+ {
+ struct inode *inode = bio_first_page_all(bio)->mapping->host;
+- struct fsverity_info *vi = inode->i_verity_info;
+- struct ahash_request *req;
+ struct folio_iter fi;
+ unsigned long max_ra_pages = 0;
+
+- /* This allocation never fails, since it's mempool-backed. */
+- req = fsverity_alloc_hash_request(vi->tree_params.hash_alg, GFP_NOFS);
+-
+ if (bio->bi_opf & REQ_RAHEAD) {
+ /*
+ * If this bio is for data readahead, then we also do readahead
+@@ -360,14 +337,12 @@ void fsverity_verify_bio(struct bio *bio)
+ }
+
+ bio_for_each_folio_all(fi, bio) {
+- if (!verify_data_blocks(inode, vi, req, fi.folio, fi.length,
+- fi.offset, max_ra_pages)) {
++ if (!verify_data_blocks(inode, fi.folio, fi.length, fi.offset,
++ max_ra_pages)) {
+ bio->bi_status = BLK_STS_IOERR;
+ break;
+ }
+ }
+-
+- fsverity_free_hash_request(vi->tree_params.hash_alg, req);
+ }
+ EXPORT_SYMBOL_GPL(fsverity_verify_bio);
+ #endif /* CONFIG_BLOCK */
+--
+2.39.2
+
--- /dev/null
+From 0f2ca98e0e6d414c26d094ad017b554dc44fbed2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Mar 2023 21:03:26 -0700
+Subject: fsverity: use WARN_ON_ONCE instead of WARN_ON
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit 8eb8af4b3df5965dc65a24a32768043f39d82d59 ]
+
+As per Linus's suggestion
+(https://lore.kernel.org/r/CAHk-=whefxRGyNGzCzG6BVeM=5vnvgb-XhSeFJVxJyAxAF8XRA@mail.gmail.com),
+use WARN_ON_ONCE instead of WARN_ON. This barely adds any extra
+overhead, and it makes it so that if any of these ever becomes reachable
+(they shouldn't, but that's the point), the logs can't be flooded.
+
+Link: https://lore.kernel.org/r/20230406181542.38894-1-ebiggers@kernel.org
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Stable-dep-of: d1f0c5ea04cd ("fsverity: don't use bio_first_page_all() in fsverity_verify_bio()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/verity/enable.c | 4 ++--
+ fs/verity/hash_algs.c | 4 ++--
+ fs/verity/open.c | 2 +-
+ include/linux/fsverity.h | 6 +++---
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/fs/verity/enable.c b/fs/verity/enable.c
+index c547ca4eb05a7..fc4c50e5219dc 100644
+--- a/fs/verity/enable.c
++++ b/fs/verity/enable.c
+@@ -175,7 +175,7 @@ static int build_merkle_tree(struct file *filp,
+ }
+ }
+ /* The root hash was filled by the last call to hash_one_block(). */
+- if (WARN_ON(buffers[num_levels].filled != params->digest_size)) {
++ if (WARN_ON_ONCE(buffers[num_levels].filled != params->digest_size)) {
+ err = -EINVAL;
+ goto out;
+ }
+@@ -287,7 +287,7 @@ static int enable_verity(struct file *filp,
+ fsverity_err(inode, "%ps() failed with err %d",
+ vops->end_enable_verity, err);
+ fsverity_free_info(vi);
+- } else if (WARN_ON(!IS_VERITY(inode))) {
++ } else if (WARN_ON_ONCE(!IS_VERITY(inode))) {
+ err = -EINVAL;
+ fsverity_free_info(vi);
+ } else {
+diff --git a/fs/verity/hash_algs.c b/fs/verity/hash_algs.c
+index 13fcf31be8441..ea00dbedf756b 100644
+--- a/fs/verity/hash_algs.c
++++ b/fs/verity/hash_algs.c
+@@ -84,9 +84,9 @@ struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode,
+ }
+
+ err = -EINVAL;
+- if (WARN_ON(alg->digest_size != crypto_ahash_digestsize(tfm)))
++ if (WARN_ON_ONCE(alg->digest_size != crypto_ahash_digestsize(tfm)))
+ goto err_free_tfm;
+- if (WARN_ON(alg->block_size != crypto_ahash_blocksize(tfm)))
++ if (WARN_ON_ONCE(alg->block_size != crypto_ahash_blocksize(tfm)))
+ goto err_free_tfm;
+
+ err = mempool_init_kmalloc_pool(&alg->req_pool, 1,
+diff --git a/fs/verity/open.c b/fs/verity/open.c
+index 9366b441d01ca..52048b7630dcc 100644
+--- a/fs/verity/open.c
++++ b/fs/verity/open.c
+@@ -83,7 +83,7 @@ int fsverity_init_merkle_tree_params(struct merkle_tree_params *params,
+ params->log_blocks_per_page = PAGE_SHIFT - log_blocksize;
+ params->blocks_per_page = 1 << params->log_blocks_per_page;
+
+- if (WARN_ON(!is_power_of_2(params->digest_size))) {
++ if (WARN_ON_ONCE(!is_power_of_2(params->digest_size))) {
+ err = -EINVAL;
+ goto out_err;
+ }
+diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h
+index 119a3266791fd..e76605d5b36ee 100644
+--- a/include/linux/fsverity.h
++++ b/include/linux/fsverity.h
+@@ -233,18 +233,18 @@ static inline int fsverity_ioctl_read_metadata(struct file *filp,
+ static inline bool fsverity_verify_blocks(struct folio *folio, size_t len,
+ size_t offset)
+ {
+- WARN_ON(1);
++ WARN_ON_ONCE(1);
+ return false;
+ }
+
+ static inline void fsverity_verify_bio(struct bio *bio)
+ {
+- WARN_ON(1);
++ WARN_ON_ONCE(1);
+ }
+
+ static inline void fsverity_enqueue_verify_work(struct work_struct *work)
+ {
+- WARN_ON(1);
++ WARN_ON_ONCE(1);
+ }
+
+ #endif /* !CONFIG_FS_VERITY */
+--
+2.39.2
+
--- /dev/null
+From 87c95b62f1fccb3c52295cf4fdc5de7fa1d1c584 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 14:32:31 -0700
+Subject: gtp: Fix use-after-free in __gtp_encap_destroy().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit ce3aee7114c575fab32a5e9e939d4bbb3dcca79f ]
+
+syzkaller reported use-after-free in __gtp_encap_destroy(). [0]
+
+It shows the same process freed sk and touched it illegally.
+
+Commit e198987e7dd7 ("gtp: fix suspicious RCU usage") added lock_sock()
+and release_sock() in __gtp_encap_destroy() to protect sk->sk_user_data,
+but release_sock() is called after sock_put() releases the last refcnt.
+
+[0]:
+BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:96 [inline]
+BUG: KASAN: slab-use-after-free in atomic_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:541 [inline]
+BUG: KASAN: slab-use-after-free in queued_spin_lock include/asm-generic/qspinlock.h:111 [inline]
+BUG: KASAN: slab-use-after-free in do_raw_spin_lock include/linux/spinlock.h:186 [inline]
+BUG: KASAN: slab-use-after-free in __raw_spin_lock_bh include/linux/spinlock_api_smp.h:127 [inline]
+BUG: KASAN: slab-use-after-free in _raw_spin_lock_bh+0x75/0xe0 kernel/locking/spinlock.c:178
+Write of size 4 at addr ffff88800dbef398 by task syz-executor.2/2401
+
+CPU: 1 PID: 2401 Comm: syz-executor.2 Not tainted 6.4.0-rc5-01219-gfa0e21fa4443 #2
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x72/0xa0 lib/dump_stack.c:106
+ print_address_description mm/kasan/report.c:351 [inline]
+ print_report+0xcc/0x620 mm/kasan/report.c:462
+ kasan_report+0xb2/0xe0 mm/kasan/report.c:572
+ check_region_inline mm/kasan/generic.c:181 [inline]
+ kasan_check_range+0x39/0x1c0 mm/kasan/generic.c:187
+ instrument_atomic_read_write include/linux/instrumented.h:96 [inline]
+ atomic_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:541 [inline]
+ queued_spin_lock include/asm-generic/qspinlock.h:111 [inline]
+ do_raw_spin_lock include/linux/spinlock.h:186 [inline]
+ __raw_spin_lock_bh include/linux/spinlock_api_smp.h:127 [inline]
+ _raw_spin_lock_bh+0x75/0xe0 kernel/locking/spinlock.c:178
+ spin_lock_bh include/linux/spinlock.h:355 [inline]
+ release_sock+0x1f/0x1a0 net/core/sock.c:3526
+ gtp_encap_disable_sock drivers/net/gtp.c:651 [inline]
+ gtp_encap_disable+0xb9/0x220 drivers/net/gtp.c:664
+ gtp_dev_uninit+0x19/0x50 drivers/net/gtp.c:728
+ unregister_netdevice_many_notify+0x97e/0x1520 net/core/dev.c:10841
+ rtnl_delete_link net/core/rtnetlink.c:3216 [inline]
+ rtnl_dellink+0x3c0/0xb30 net/core/rtnetlink.c:3268
+ rtnetlink_rcv_msg+0x450/0xb10 net/core/rtnetlink.c:6423
+ netlink_rcv_skb+0x15d/0x450 net/netlink/af_netlink.c:2548
+ netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline]
+ netlink_unicast+0x700/0x930 net/netlink/af_netlink.c:1365
+ netlink_sendmsg+0x91c/0xe30 net/netlink/af_netlink.c:1913
+ sock_sendmsg_nosec net/socket.c:724 [inline]
+ sock_sendmsg+0x1b7/0x200 net/socket.c:747
+ ____sys_sendmsg+0x75a/0x990 net/socket.c:2493
+ ___sys_sendmsg+0x11d/0x1c0 net/socket.c:2547
+ __sys_sendmsg+0xfe/0x1d0 net/socket.c:2576
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+RIP: 0033:0x7f1168b1fe5d
+Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 9f 1b 00 f7 d8 64 89 01 48
+RSP: 002b:00007f1167edccc8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00000000004bbf80 RCX: 00007f1168b1fe5d
+RDX: 0000000000000000 RSI: 00000000200002c0 RDI: 0000000000000003
+RBP: 00000000004bbf80 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 000000000000000b R14: 00007f1168b80530 R15: 0000000000000000
+ </TASK>
+
+Allocated by task 1483:
+ kasan_save_stack+0x22/0x50 mm/kasan/common.c:45
+ kasan_set_track+0x25/0x30 mm/kasan/common.c:52
+ __kasan_slab_alloc+0x59/0x70 mm/kasan/common.c:328
+ kasan_slab_alloc include/linux/kasan.h:186 [inline]
+ slab_post_alloc_hook mm/slab.h:711 [inline]
+ slab_alloc_node mm/slub.c:3451 [inline]
+ slab_alloc mm/slub.c:3459 [inline]
+ __kmem_cache_alloc_lru mm/slub.c:3466 [inline]
+ kmem_cache_alloc+0x16d/0x340 mm/slub.c:3475
+ sk_prot_alloc+0x5f/0x280 net/core/sock.c:2073
+ sk_alloc+0x34/0x6c0 net/core/sock.c:2132
+ inet6_create net/ipv6/af_inet6.c:192 [inline]
+ inet6_create+0x2c7/0xf20 net/ipv6/af_inet6.c:119
+ __sock_create+0x2a1/0x530 net/socket.c:1535
+ sock_create net/socket.c:1586 [inline]
+ __sys_socket_create net/socket.c:1623 [inline]
+ __sys_socket_create net/socket.c:1608 [inline]
+ __sys_socket+0x137/0x250 net/socket.c:1651
+ __do_sys_socket net/socket.c:1664 [inline]
+ __se_sys_socket net/socket.c:1662 [inline]
+ __x64_sys_socket+0x72/0xb0 net/socket.c:1662
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+
+Freed by task 2401:
+ kasan_save_stack+0x22/0x50 mm/kasan/common.c:45
+ kasan_set_track+0x25/0x30 mm/kasan/common.c:52
+ kasan_save_free_info+0x2e/0x50 mm/kasan/generic.c:521
+ ____kasan_slab_free mm/kasan/common.c:236 [inline]
+ ____kasan_slab_free mm/kasan/common.c:200 [inline]
+ __kasan_slab_free+0x10c/0x1b0 mm/kasan/common.c:244
+ kasan_slab_free include/linux/kasan.h:162 [inline]
+ slab_free_hook mm/slub.c:1781 [inline]
+ slab_free_freelist_hook mm/slub.c:1807 [inline]
+ slab_free mm/slub.c:3786 [inline]
+ kmem_cache_free+0xb4/0x490 mm/slub.c:3808
+ sk_prot_free net/core/sock.c:2113 [inline]
+ __sk_destruct+0x500/0x720 net/core/sock.c:2207
+ sk_destruct+0xc1/0xe0 net/core/sock.c:2222
+ __sk_free+0xed/0x3d0 net/core/sock.c:2233
+ sk_free+0x7c/0xa0 net/core/sock.c:2244
+ sock_put include/net/sock.h:1981 [inline]
+ __gtp_encap_destroy+0x165/0x1b0 drivers/net/gtp.c:634
+ gtp_encap_disable_sock drivers/net/gtp.c:651 [inline]
+ gtp_encap_disable+0xb9/0x220 drivers/net/gtp.c:664
+ gtp_dev_uninit+0x19/0x50 drivers/net/gtp.c:728
+ unregister_netdevice_many_notify+0x97e/0x1520 net/core/dev.c:10841
+ rtnl_delete_link net/core/rtnetlink.c:3216 [inline]
+ rtnl_dellink+0x3c0/0xb30 net/core/rtnetlink.c:3268
+ rtnetlink_rcv_msg+0x450/0xb10 net/core/rtnetlink.c:6423
+ netlink_rcv_skb+0x15d/0x450 net/netlink/af_netlink.c:2548
+ netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline]
+ netlink_unicast+0x700/0x930 net/netlink/af_netlink.c:1365
+ netlink_sendmsg+0x91c/0xe30 net/netlink/af_netlink.c:1913
+ sock_sendmsg_nosec net/socket.c:724 [inline]
+ sock_sendmsg+0x1b7/0x200 net/socket.c:747
+ ____sys_sendmsg+0x75a/0x990 net/socket.c:2493
+ ___sys_sendmsg+0x11d/0x1c0 net/socket.c:2547
+ __sys_sendmsg+0xfe/0x1d0 net/socket.c:2576
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+
+The buggy address belongs to the object at ffff88800dbef300
+ which belongs to the cache UDPv6 of size 1344
+The buggy address is located 152 bytes inside of
+ freed 1344-byte region [ffff88800dbef300, ffff88800dbef840)
+
+The buggy address belongs to the physical page:
+page:00000000d31bfed5 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff88800dbeed40 pfn:0xdbe8
+head:00000000d31bfed5 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+memcg:ffff888008ee0801
+flags: 0x100000000010200(slab|head|node=0|zone=1)
+page_type: 0xffffffff()
+raw: 0100000000010200 ffff88800c7a3000 dead000000000122 0000000000000000
+raw: ffff88800dbeed40 0000000080160015 00000001ffffffff ffff888008ee0801
+page dumped because: kasan: bad access detected
+
+Memory state around the buggy address:
+ ffff88800dbef280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+ ffff88800dbef300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+>ffff88800dbef380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ^
+ ffff88800dbef400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff88800dbef480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+
+Fixes: e198987e7dd7 ("gtp: fix suspicious RCU usage")
+Reported-by: syzkaller <syzkaller@googlegroups.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Link: https://lore.kernel.org/r/20230622213231.24651-1-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/gtp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
+index 15c7dc82107f4..acb20ad4e37eb 100644
+--- a/drivers/net/gtp.c
++++ b/drivers/net/gtp.c
+@@ -631,7 +631,9 @@ static void __gtp_encap_destroy(struct sock *sk)
+ gtp->sk1u = NULL;
+ udp_sk(sk)->encap_type = 0;
+ rcu_assign_sk_user_data(sk, NULL);
++ release_sock(sk);
+ sock_put(sk);
++ return;
+ }
+ release_sock(sk);
+ }
+--
+2.39.2
+
--- /dev/null
+From bc087c7885870c02de6aa9e84915100536ab47b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 May 2023 17:10:59 +0200
+Subject: HID: uclogic: Modular KUnit tests should not depend on KUNIT=y
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 49904a0ebf23b15aad288a10f5354e7cd8193121 ]
+
+While KUnit tests that cannot be built as a loadable module must depend
+on "KUNIT=y", this is not true for modular tests, where it adds an
+unnecessary limitation.
+
+Fix this by relaxing the dependency to "KUNIT".
+
+Fixes: 08809e482a1c44d9 ("HID: uclogic: KUnit best practices and naming conventions")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: David Gow <davidgow@google.com>
+Reviewed-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index 4ce012f83253e..b977450cac752 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -1285,7 +1285,7 @@ config HID_MCP2221
+
+ config HID_KUNIT_TEST
+ tristate "KUnit tests for HID" if !KUNIT_ALL_TESTS
+- depends on KUNIT=y
++ depends on KUNIT
+ depends on HID_BATTERY_STRENGTH
+ depends on HID_UCLOGIC
+ default KUNIT_ALL_TESTS
+--
+2.39.2
+
--- /dev/null
+From e7c40a060bd15a80f3cadb25e5f670c303489f40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 May 2023 07:35:37 -0700
+Subject: hwmon: (f71882fg) prevent possible division by zero
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 0babf89c9cca7e074d6e59893e462e4886f481cc ]
+
+In the unlikely event that something goes wrong with the device and
+its registers, the fan_from_reg() function may return 0. This value
+will cause a division-by-zero error in the show_pwm() function.
+
+To prevent this, test the value of
+fan_from_reg(data->fan_full_speed[nr]) against 0 before performing
+the division. If the division-by-zero error is avoided, assign 0 to
+the val variable.
+
+Found by Linux Verification Center (linuxtesting.org) with static
+analysis tool SVACE.
+
+Fixes: df9ec2dae094 ("hwmon: (f71882fg) Reorder symbols to get rid of a few forward declarations")
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Link: https://lore.kernel.org/r/20230510143537.145060-1-n.zhandarovich@fintech.ru
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/f71882fg.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
+index 70121482a6173..27207ec6f7feb 100644
+--- a/drivers/hwmon/f71882fg.c
++++ b/drivers/hwmon/f71882fg.c
+@@ -1096,8 +1096,11 @@ static ssize_t show_pwm(struct device *dev,
+ val = data->pwm[nr];
+ else {
+ /* RPM mode */
+- val = 255 * fan_from_reg(data->fan_target[nr])
+- / fan_from_reg(data->fan_full_speed[nr]);
++ if (fan_from_reg(data->fan_full_speed[nr]))
++ val = 255 * fan_from_reg(data->fan_target[nr])
++ / fan_from_reg(data->fan_full_speed[nr]);
++ else
++ val = 0;
+ }
+ mutex_unlock(&data->update_lock);
+ return sprintf(buf, "%d\n", val);
+--
+2.39.2
+
--- /dev/null
+From 2db2941f39ea11d1e4796b8be647213bc5975592 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 08:30:04 -0700
+Subject: hwmon: (gsc-hwmon) fix fan pwm temperature scaling
+
+From: Tim Harvey <tharvey@gateworks.com>
+
+[ Upstream commit a6d80df47ee2c69db99e4f2f8871aa4db154620b ]
+
+The GSC fan pwm temperature register is in centidegrees celcius but the
+Linux hwmon convention is to use milidegrees celcius. Fix the scaling.
+
+Fixes: 3bce5377ef66 ("hwmon: Add Gateworks System Controller support")
+Signed-off-by: Tim Harvey <tharvey@gateworks.com>
+Link: https://lore.kernel.org/r/20230606153004.1448086-1-tharvey@gateworks.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/gsc-hwmon.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/hwmon/gsc-hwmon.c b/drivers/hwmon/gsc-hwmon.c
+index 73e5d92b200b0..1501ceb551e79 100644
+--- a/drivers/hwmon/gsc-hwmon.c
++++ b/drivers/hwmon/gsc-hwmon.c
+@@ -82,8 +82,8 @@ static ssize_t pwm_auto_point_temp_store(struct device *dev,
+ if (kstrtol(buf, 10, &temp))
+ return -EINVAL;
+
+- temp = clamp_val(temp, 0, 10000);
+- temp = DIV_ROUND_CLOSEST(temp, 10);
++ temp = clamp_val(temp, 0, 100000);
++ temp = DIV_ROUND_CLOSEST(temp, 100);
+
+ regs[0] = temp & 0xff;
+ regs[1] = (temp >> 8) & 0xff;
+@@ -100,7 +100,7 @@ static ssize_t pwm_auto_point_pwm_show(struct device *dev,
+ {
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+
+- return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10)) / 100);
++ return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10)));
+ }
+
+ static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point1_pwm, pwm_auto_point_pwm, 0);
+--
+2.39.2
+
--- /dev/null
+From 7c87edb88e513037e1d5db672265edf75299b688 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 14:34:47 -0700
+Subject: hwmon: (pmbus/adm1275) Fix problems with temperature monitoring on
+ ADM1272
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit b153a0bb4199566abd337119207f82b59a8cd1ca ]
+
+The PMON_CONFIG register on ADM1272 is a 16 bit register. Writing a 8 bit
+value into it clears the upper 8 bits of the register, resulting in
+unexpected side effects. Fix by writing the 16 bit register value.
+
+Also, it has been reported that temperature readings are sometimes widely
+inaccurate, to the point where readings may result in device shutdown due
+to errant overtemperature faults. Improve by enabling temperature sampling.
+
+While at it, move the common code for ADM1272 and ADM1278 into a separate
+function, and clarify in the error message that an attempt was made to
+enable both VOUT and temperature monitoring.
+
+Last but not least, return the error code reported by the underlying I2C
+controller and not -ENODEV if updating the PMON_CONFIG register fails.
+After all, this does not indicate that the chip is not present, but an
+error in the communication with the chip.
+
+Fixes: 4ff0ce227a1e ("hwmon: (pmbus/adm1275) Add support for ADM1272")
+Fixes: 9da9c2dc57b2 ("hwmon: (adm1275) enable adm1272 temperature reporting")
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20230602213447.3557346-1-linux@roeck-us.net
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/pmbus/adm1275.c | 52 +++++++++++++++++------------------
+ 1 file changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c
+index 3b07bfb43e937..b8543c06d022a 100644
+--- a/drivers/hwmon/pmbus/adm1275.c
++++ b/drivers/hwmon/pmbus/adm1275.c
+@@ -37,10 +37,13 @@ enum chips { adm1075, adm1272, adm1275, adm1276, adm1278, adm1293, adm1294 };
+
+ #define ADM1272_IRANGE BIT(0)
+
++#define ADM1278_TSFILT BIT(15)
+ #define ADM1278_TEMP1_EN BIT(3)
+ #define ADM1278_VIN_EN BIT(2)
+ #define ADM1278_VOUT_EN BIT(1)
+
++#define ADM1278_PMON_DEFCONFIG (ADM1278_VOUT_EN | ADM1278_TEMP1_EN | ADM1278_TSFILT)
++
+ #define ADM1293_IRANGE_25 0
+ #define ADM1293_IRANGE_50 BIT(6)
+ #define ADM1293_IRANGE_100 BIT(7)
+@@ -462,6 +465,22 @@ static const struct i2c_device_id adm1275_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, adm1275_id);
+
++/* Enable VOUT & TEMP1 if not enabled (disabled by default) */
++static int adm1275_enable_vout_temp(struct i2c_client *client, int config)
++{
++ int ret;
++
++ if ((config & ADM1278_PMON_DEFCONFIG) != ADM1278_PMON_DEFCONFIG) {
++ config |= ADM1278_PMON_DEFCONFIG;
++ ret = i2c_smbus_write_word_data(client, ADM1275_PMON_CONFIG, config);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to enable VOUT/TEMP1 monitoring\n");
++ return ret;
++ }
++ }
++ return 0;
++}
++
+ static int adm1275_probe(struct i2c_client *client)
+ {
+ s32 (*config_read_fn)(const struct i2c_client *client, u8 reg);
+@@ -615,19 +634,10 @@ static int adm1275_probe(struct i2c_client *client)
+ PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+ PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
+
+- /* Enable VOUT & TEMP1 if not enabled (disabled by default) */
+- if ((config & (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) !=
+- (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) {
+- config |= ADM1278_VOUT_EN | ADM1278_TEMP1_EN;
+- ret = i2c_smbus_write_byte_data(client,
+- ADM1275_PMON_CONFIG,
+- config);
+- if (ret < 0) {
+- dev_err(&client->dev,
+- "Failed to enable VOUT monitoring\n");
+- return -ENODEV;
+- }
+- }
++ ret = adm1275_enable_vout_temp(client, config);
++ if (ret)
++ return ret;
++
+ if (config & ADM1278_VIN_EN)
+ info->func[0] |= PMBUS_HAVE_VIN;
+ break;
+@@ -684,19 +694,9 @@ static int adm1275_probe(struct i2c_client *client)
+ PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+ PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
+
+- /* Enable VOUT & TEMP1 if not enabled (disabled by default) */
+- if ((config & (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) !=
+- (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) {
+- config |= ADM1278_VOUT_EN | ADM1278_TEMP1_EN;
+- ret = i2c_smbus_write_word_data(client,
+- ADM1275_PMON_CONFIG,
+- config);
+- if (ret < 0) {
+- dev_err(&client->dev,
+- "Failed to enable VOUT monitoring\n");
+- return -ENODEV;
+- }
+- }
++ ret = adm1275_enable_vout_temp(client, config);
++ if (ret)
++ return ret;
+
+ if (config & ADM1278_VIN_EN)
+ info->func[0] |= PMBUS_HAVE_VIN;
+--
+2.39.2
+
--- /dev/null
+From 2117f0aa204a35b9ee90e67523fd2d8559e0d691 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 09:58:13 +0100
+Subject: hwrng: st - keep clock enabled while hwrng is registered
+
+From: Martin Kaiser <martin@kaiser.cx>
+
+[ Upstream commit 501e197a02d4aef157f53ba3a0b9049c3e52fedc ]
+
+The st-rng driver uses devres to register itself with the hwrng core,
+the driver will be unregistered from hwrng when its device goes out of
+scope. This happens after the driver's remove function is called.
+
+However, st-rng's clock is disabled in the remove function. There's a
+short timeframe where st-rng is still registered with the hwrng core
+although its clock is disabled. I suppose the clock must be active to
+access the hardware and serve requests from the hwrng core.
+
+Switch to devm_clk_get_enabled and let devres disable the clock and
+unregister the hwrng. This avoids the race condition.
+
+Fixes: 3e75241be808 ("hwrng: drivers - Use device-managed registration API")
+Signed-off-by: Martin Kaiser <martin@kaiser.cx>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/st-rng.c | 21 +--------------------
+ 1 file changed, 1 insertion(+), 20 deletions(-)
+
+diff --git a/drivers/char/hw_random/st-rng.c b/drivers/char/hw_random/st-rng.c
+index 15ba1e6fae4d2..6e9dfac9fc9f4 100644
+--- a/drivers/char/hw_random/st-rng.c
++++ b/drivers/char/hw_random/st-rng.c
+@@ -42,7 +42,6 @@
+
+ struct st_rng_data {
+ void __iomem *base;
+- struct clk *clk;
+ struct hwrng ops;
+ };
+
+@@ -85,26 +84,18 @@ static int st_rng_probe(struct platform_device *pdev)
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+- clk = devm_clk_get(&pdev->dev, NULL);
++ clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+- ret = clk_prepare_enable(clk);
+- if (ret)
+- return ret;
+-
+ ddata->ops.priv = (unsigned long)ddata;
+ ddata->ops.read = st_rng_read;
+ ddata->ops.name = pdev->name;
+ ddata->base = base;
+- ddata->clk = clk;
+-
+- dev_set_drvdata(&pdev->dev, ddata);
+
+ ret = devm_hwrng_register(&pdev->dev, &ddata->ops);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register HW RNG\n");
+- clk_disable_unprepare(clk);
+ return ret;
+ }
+
+@@ -113,15 +104,6 @@ static int st_rng_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int st_rng_remove(struct platform_device *pdev)
+-{
+- struct st_rng_data *ddata = dev_get_drvdata(&pdev->dev);
+-
+- clk_disable_unprepare(ddata->clk);
+-
+- return 0;
+-}
+-
+ static const struct of_device_id st_rng_match[] __maybe_unused = {
+ { .compatible = "st,rng" },
+ {},
+@@ -134,7 +116,6 @@ static struct platform_driver st_rng_driver = {
+ .of_match_table = of_match_ptr(st_rng_match),
+ },
+ .probe = st_rng_probe,
+- .remove = st_rng_remove
+ };
+
+ module_platform_driver(st_rng_driver);
+--
+2.39.2
+
--- /dev/null
+From 3455a124e484653c73867d31b45d8309f4593ec6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 May 2023 11:59:32 +0800
+Subject: hwrng: virtio - Fix race on data_avail and actual data
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit ac52578d6e8d300dd50f790f29a24169b1edd26c ]
+
+The virtio rng device kicks off a new entropy request whenever the
+data available reaches zero. When a new request occurs at the end
+of a read operation, that is, when the result of that request is
+only needed by the next reader, then there is a race between the
+writing of the new data and the next reader.
+
+This is because there is no synchronisation whatsoever between the
+writer and the reader.
+
+Fix this by writing data_avail with smp_store_release and reading
+it with smp_load_acquire when we first enter read. The subsequent
+reads are safe because they're either protected by the first load
+acquire, or by the completion mechanism.
+
+Also remove the redundant zeroing of data_idx in random_recv_done
+(data_idx must already be zero at this point) and data_avail in
+request_entropy (ditto).
+
+Reported-by: syzbot+726dc8c62c3536431ceb@syzkaller.appspotmail.com
+Fixes: f7f510ec1957 ("virtio: An entropy device, as suggested by hpa.")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/virtio-rng.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
+index f7690e0f92ede..e41a84e6b4b56 100644
+--- a/drivers/char/hw_random/virtio-rng.c
++++ b/drivers/char/hw_random/virtio-rng.c
+@@ -4,6 +4,7 @@
+ * Copyright (C) 2007, 2008 Rusty Russell IBM Corporation
+ */
+
++#include <asm/barrier.h>
+ #include <linux/err.h>
+ #include <linux/hw_random.h>
+ #include <linux/scatterlist.h>
+@@ -37,13 +38,13 @@ struct virtrng_info {
+ static void random_recv_done(struct virtqueue *vq)
+ {
+ struct virtrng_info *vi = vq->vdev->priv;
++ unsigned int len;
+
+ /* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
+- if (!virtqueue_get_buf(vi->vq, &vi->data_avail))
++ if (!virtqueue_get_buf(vi->vq, &len))
+ return;
+
+- vi->data_idx = 0;
+-
++ smp_store_release(&vi->data_avail, len);
+ complete(&vi->have_data);
+ }
+
+@@ -52,7 +53,6 @@ static void request_entropy(struct virtrng_info *vi)
+ struct scatterlist sg;
+
+ reinit_completion(&vi->have_data);
+- vi->data_avail = 0;
+ vi->data_idx = 0;
+
+ sg_init_one(&sg, vi->data, sizeof(vi->data));
+@@ -88,7 +88,7 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
+ read = 0;
+
+ /* copy available data */
+- if (vi->data_avail) {
++ if (smp_load_acquire(&vi->data_avail)) {
+ chunk = copy_data(vi, buf, size);
+ size -= chunk;
+ read += chunk;
+--
+2.39.2
+
--- /dev/null
+From 01570ae13eecc77e9c0a57638335b5d8fecedacb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 May 2023 22:51:38 +0200
+Subject: i2c: Convert to platform remove callback returning void
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit e190a0c389e60178fba3d532abf936dcae223e7d ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is (mostly) ignored
+and this typically results in resource leaks. To improve here there is a
+quest to make the remove callback return void. In the first step of this
+quest all drivers are converted to .remove_new() which already returns
+void.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Alain Volmat <alain.volmat@foss.st.com>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Acked-by: Baruch Siach <baruch@tkos.co.il>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Acked-by: Heiko Stuebner <heiko@sntech.de>
+Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Acked-by: Jochen Friedrich <jochen@scram.de>
+Acked-by: Peter Rosin <peda@axentia.se>
+Acked-by: Vadim Pasternak <vadimp@nvidia.com>
+Reviewed-by: Asmaa Mnebhi <asnaa@nvidia.com>
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
+Reviewed-by: Chris Pringle <chris.pringle@phabrix.com>
+Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Jean Delvare <jdelvare@suse.de>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
+Reviewed-by: Tali Perry <tali.perry@nuvoton.com>
+Reviewed-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 9e1a1ee93f6b ("i2c: ocores: use devm_ managed clks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-altera.c | 6 ++----
+ drivers/i2c/busses/i2c-amd-mp2-plat.c | 5 ++---
+ drivers/i2c/busses/i2c-aspeed.c | 6 ++----
+ drivers/i2c/busses/i2c-at91-core.c | 6 ++----
+ drivers/i2c/busses/i2c-au1550.c | 5 ++---
+ drivers/i2c/busses/i2c-axxia.c | 6 ++----
+ drivers/i2c/busses/i2c-bcm-iproc.c | 6 ++----
+ drivers/i2c/busses/i2c-bcm-kona.c | 6 ++----
+ drivers/i2c/busses/i2c-bcm2835.c | 6 ++----
+ drivers/i2c/busses/i2c-brcmstb.c | 5 ++---
+ drivers/i2c/busses/i2c-cadence.c | 6 ++----
+ drivers/i2c/busses/i2c-cbus-gpio.c | 6 ++----
+ drivers/i2c/busses/i2c-cht-wc.c | 6 ++----
+ drivers/i2c/busses/i2c-cpm.c | 6 ++----
+ drivers/i2c/busses/i2c-cros-ec-tunnel.c | 6 ++----
+ drivers/i2c/busses/i2c-davinci.c | 14 ++++++--------
+ drivers/i2c/busses/i2c-designware-platdrv.c | 6 ++----
+ drivers/i2c/busses/i2c-digicolor.c | 6 ++----
+ drivers/i2c/busses/i2c-dln2.c | 6 ++----
+ drivers/i2c/busses/i2c-emev2.c | 6 ++----
+ drivers/i2c/busses/i2c-exynos5.c | 6 ++----
+ drivers/i2c/busses/i2c-gpio.c | 6 ++----
+ drivers/i2c/busses/i2c-gxp.c | 6 ++----
+ drivers/i2c/busses/i2c-highlander.c | 6 ++----
+ drivers/i2c/busses/i2c-hix5hd2.c | 6 ++----
+ drivers/i2c/busses/i2c-ibm_iic.c | 6 ++----
+ drivers/i2c/busses/i2c-img-scb.c | 6 ++----
+ drivers/i2c/busses/i2c-imx-lpi2c.c | 6 ++----
+ drivers/i2c/busses/i2c-imx.c | 6 ++----
+ drivers/i2c/busses/i2c-iop3xx.c | 6 ++----
+ drivers/i2c/busses/i2c-isch.c | 6 ++----
+ drivers/i2c/busses/i2c-jz4780.c | 5 ++---
+ drivers/i2c/busses/i2c-kempld.c | 6 ++----
+ drivers/i2c/busses/i2c-lpc2k.c | 6 ++----
+ drivers/i2c/busses/i2c-meson.c | 6 ++----
+ drivers/i2c/busses/i2c-microchip-corei2c.c | 6 ++----
+ drivers/i2c/busses/i2c-mlxbf.c | 6 ++----
+ drivers/i2c/busses/i2c-mlxcpld.c | 6 ++----
+ drivers/i2c/busses/i2c-mpc.c | 6 ++----
+ drivers/i2c/busses/i2c-mt65xx.c | 6 ++----
+ drivers/i2c/busses/i2c-mt7621.c | 6 ++----
+ drivers/i2c/busses/i2c-mv64xxx.c | 6 ++----
+ drivers/i2c/busses/i2c-mxs.c | 6 ++----
+ drivers/i2c/busses/i2c-npcm7xx.c | 5 ++---
+ drivers/i2c/busses/i2c-ocores.c | 6 ++----
+ drivers/i2c/busses/i2c-octeon-platdrv.c | 5 ++---
+ drivers/i2c/busses/i2c-omap.c | 6 ++----
+ drivers/i2c/busses/i2c-opal.c | 6 ++----
+ drivers/i2c/busses/i2c-pasemi-platform.c | 5 ++---
+ drivers/i2c/busses/i2c-pca-platform.c | 6 ++----
+ drivers/i2c/busses/i2c-pnx.c | 6 ++----
+ drivers/i2c/busses/i2c-powermac.c | 6 ++----
+ drivers/i2c/busses/i2c-pxa.c | 6 ++----
+ drivers/i2c/busses/i2c-qcom-cci.c | 6 ++----
+ drivers/i2c/busses/i2c-qcom-geni.c | 5 ++---
+ drivers/i2c/busses/i2c-qup.c | 5 ++---
+ drivers/i2c/busses/i2c-rcar.c | 6 ++----
+ drivers/i2c/busses/i2c-riic.c | 6 ++----
+ drivers/i2c/busses/i2c-rk3x.c | 6 ++----
+ drivers/i2c/busses/i2c-rzv2m.c | 6 ++----
+ drivers/i2c/busses/i2c-s3c2410.c | 6 ++----
+ drivers/i2c/busses/i2c-scmi.c | 6 ++----
+ drivers/i2c/busses/i2c-sh7760.c | 6 ++----
+ drivers/i2c/busses/i2c-sh_mobile.c | 5 ++---
+ drivers/i2c/busses/i2c-simtec.c | 6 ++----
+ drivers/i2c/busses/i2c-st.c | 6 ++----
+ drivers/i2c/busses/i2c-stm32f4.c | 6 ++----
+ drivers/i2c/busses/i2c-stm32f7.c | 6 ++----
+ drivers/i2c/busses/i2c-sun6i-p2wi.c | 6 ++----
+ drivers/i2c/busses/i2c-synquacer.c | 6 ++----
+ drivers/i2c/busses/i2c-tegra-bpmp.c | 6 ++----
+ drivers/i2c/busses/i2c-tegra.c | 6 ++----
+ drivers/i2c/busses/i2c-uniphier-f.c | 6 ++----
+ drivers/i2c/busses/i2c-uniphier.c | 6 ++----
+ drivers/i2c/busses/i2c-versatile.c | 5 ++---
+ drivers/i2c/busses/i2c-viperboard.c | 6 ++----
+ drivers/i2c/busses/i2c-wmt.c | 6 ++----
+ drivers/i2c/busses/i2c-xgene-slimpro.c | 6 ++----
+ drivers/i2c/busses/i2c-xiic.c | 6 ++----
+ drivers/i2c/busses/i2c-xlp9xx.c | 6 ++----
+ drivers/i2c/busses/scx200_acb.c | 6 ++----
+ drivers/i2c/muxes/i2c-arb-gpio-challenge.c | 5 ++---
+ drivers/i2c/muxes/i2c-demux-pinctrl.c | 6 ++----
+ drivers/i2c/muxes/i2c-mux-gpio.c | 6 ++----
+ drivers/i2c/muxes/i2c-mux-gpmux.c | 6 ++----
+ drivers/i2c/muxes/i2c-mux-mlxcpld.c | 5 ++---
+ drivers/i2c/muxes/i2c-mux-pinctrl.c | 6 ++----
+ drivers/i2c/muxes/i2c-mux-reg.c | 6 ++----
+ 88 files changed, 180 insertions(+), 343 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-altera.c b/drivers/i2c/busses/i2c-altera.c
+index 50e7f3f670b6f..252fbd175fb1c 100644
+--- a/drivers/i2c/busses/i2c-altera.c
++++ b/drivers/i2c/busses/i2c-altera.c
+@@ -465,14 +465,12 @@ static int altr_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int altr_i2c_remove(struct platform_device *pdev)
++static void altr_i2c_remove(struct platform_device *pdev)
+ {
+ struct altr_i2c_dev *idev = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(idev->i2c_clk);
+ i2c_del_adapter(&idev->adapter);
+-
+- return 0;
+ }
+
+ /* Match table for of_platform binding */
+@@ -484,7 +482,7 @@ MODULE_DEVICE_TABLE(of, altr_i2c_of_match);
+
+ static struct platform_driver altr_i2c_driver = {
+ .probe = altr_i2c_probe,
+- .remove = altr_i2c_remove,
++ .remove_new = altr_i2c_remove,
+ .driver = {
+ .name = "altera-i2c",
+ .of_match_table = altr_i2c_of_match,
+diff --git a/drivers/i2c/busses/i2c-amd-mp2-plat.c b/drivers/i2c/busses/i2c-amd-mp2-plat.c
+index 423fe0c8a471e..112fe2bc5662b 100644
+--- a/drivers/i2c/busses/i2c-amd-mp2-plat.c
++++ b/drivers/i2c/busses/i2c-amd-mp2-plat.c
+@@ -322,7 +322,7 @@ static int i2c_amd_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int i2c_amd_remove(struct platform_device *pdev)
++static void i2c_amd_remove(struct platform_device *pdev)
+ {
+ struct amd_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+ struct amd_i2c_common *i2c_common = &i2c_dev->common;
+@@ -336,7 +336,6 @@ static int i2c_amd_remove(struct platform_device *pdev)
+ i2c_unlock_bus(&i2c_dev->adap, I2C_LOCK_ROOT_ADAPTER);
+
+ i2c_del_adapter(&i2c_dev->adap);
+- return 0;
+ }
+
+ static const struct acpi_device_id i2c_amd_acpi_match[] = {
+@@ -347,7 +346,7 @@ MODULE_DEVICE_TABLE(acpi, i2c_amd_acpi_match);
+
+ static struct platform_driver i2c_amd_plat_driver = {
+ .probe = i2c_amd_probe,
+- .remove = i2c_amd_remove,
++ .remove_new = i2c_amd_remove,
+ .driver = {
+ .name = "i2c_amd_mp2",
+ .acpi_match_table = ACPI_PTR(i2c_amd_acpi_match),
+diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
+index d3c99c5b32478..2e5acfeb76c81 100644
+--- a/drivers/i2c/busses/i2c-aspeed.c
++++ b/drivers/i2c/busses/i2c-aspeed.c
+@@ -1061,7 +1061,7 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int aspeed_i2c_remove_bus(struct platform_device *pdev)
++static void aspeed_i2c_remove_bus(struct platform_device *pdev)
+ {
+ struct aspeed_i2c_bus *bus = platform_get_drvdata(pdev);
+ unsigned long flags;
+@@ -1077,13 +1077,11 @@ static int aspeed_i2c_remove_bus(struct platform_device *pdev)
+ reset_control_assert(bus->rst);
+
+ i2c_del_adapter(&bus->adap);
+-
+- return 0;
+ }
+
+ static struct platform_driver aspeed_i2c_bus_driver = {
+ .probe = aspeed_i2c_probe_bus,
+- .remove = aspeed_i2c_remove_bus,
++ .remove_new = aspeed_i2c_remove_bus,
+ .driver = {
+ .name = "aspeed-i2c-bus",
+ .of_match_table = aspeed_i2c_bus_of_table,
+diff --git a/drivers/i2c/busses/i2c-at91-core.c b/drivers/i2c/busses/i2c-at91-core.c
+index 2df9df5851314..05ad3bc3578ac 100644
+--- a/drivers/i2c/busses/i2c-at91-core.c
++++ b/drivers/i2c/busses/i2c-at91-core.c
+@@ -273,7 +273,7 @@ static int at91_twi_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int at91_twi_remove(struct platform_device *pdev)
++static void at91_twi_remove(struct platform_device *pdev)
+ {
+ struct at91_twi_dev *dev = platform_get_drvdata(pdev);
+
+@@ -282,8 +282,6 @@ static int at91_twi_remove(struct platform_device *pdev)
+
+ pm_runtime_disable(dev->dev);
+ pm_runtime_set_suspended(dev->dev);
+-
+- return 0;
+ }
+
+ static int __maybe_unused at91_twi_runtime_suspend(struct device *dev)
+@@ -342,7 +340,7 @@ static const struct dev_pm_ops __maybe_unused at91_twi_pm = {
+
+ static struct platform_driver at91_twi_driver = {
+ .probe = at91_twi_probe,
+- .remove = at91_twi_remove,
++ .remove_new = at91_twi_remove,
+ .id_table = at91_twi_devtypes,
+ .driver = {
+ .name = "at91_i2c",
+diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
+index 7b42d35b12942..e66c12ecf2706 100644
+--- a/drivers/i2c/busses/i2c-au1550.c
++++ b/drivers/i2c/busses/i2c-au1550.c
+@@ -334,13 +334,12 @@ i2c_au1550_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int i2c_au1550_remove(struct platform_device *pdev)
++static void i2c_au1550_remove(struct platform_device *pdev)
+ {
+ struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&priv->adap);
+ i2c_au1550_disable(priv);
+- return 0;
+ }
+
+ #ifdef CONFIG_PM
+@@ -379,7 +378,7 @@ static struct platform_driver au1xpsc_smbus_driver = {
+ .pm = AU1XPSC_SMBUS_PMOPS,
+ },
+ .probe = i2c_au1550_probe,
+- .remove = i2c_au1550_remove,
++ .remove_new = i2c_au1550_remove,
+ };
+
+ module_platform_driver(au1xpsc_smbus_driver);
+diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c
+index c1c74ce084071..d7f1e98777ace 100644
+--- a/drivers/i2c/busses/i2c-axxia.c
++++ b/drivers/i2c/busses/i2c-axxia.c
+@@ -804,14 +804,12 @@ static int axxia_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int axxia_i2c_remove(struct platform_device *pdev)
++static void axxia_i2c_remove(struct platform_device *pdev)
+ {
+ struct axxia_i2c_dev *idev = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(idev->i2c_clk);
+ i2c_del_adapter(&idev->adapter);
+-
+- return 0;
+ }
+
+ /* Match table for of_platform binding */
+@@ -824,7 +822,7 @@ MODULE_DEVICE_TABLE(of, axxia_i2c_of_match);
+
+ static struct platform_driver axxia_i2c_driver = {
+ .probe = axxia_i2c_probe,
+- .remove = axxia_i2c_remove,
++ .remove_new = axxia_i2c_remove,
+ .driver = {
+ .name = "axxia-i2c",
+ .of_match_table = axxia_i2c_of_match,
+diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c
+index 85d8a6b048856..2d8342fdc25de 100644
+--- a/drivers/i2c/busses/i2c-bcm-iproc.c
++++ b/drivers/i2c/busses/i2c-bcm-iproc.c
+@@ -1107,7 +1107,7 @@ static int bcm_iproc_i2c_probe(struct platform_device *pdev)
+ return i2c_add_adapter(adap);
+ }
+
+-static int bcm_iproc_i2c_remove(struct platform_device *pdev)
++static void bcm_iproc_i2c_remove(struct platform_device *pdev)
+ {
+ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev);
+
+@@ -1123,8 +1123,6 @@ static int bcm_iproc_i2c_remove(struct platform_device *pdev)
+
+ i2c_del_adapter(&iproc_i2c->adapter);
+ bcm_iproc_i2c_enable_disable(iproc_i2c, false);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_PM_SLEEP
+@@ -1260,7 +1258,7 @@ static struct platform_driver bcm_iproc_i2c_driver = {
+ .pm = BCM_IPROC_I2C_PM_OPS,
+ },
+ .probe = bcm_iproc_i2c_probe,
+- .remove = bcm_iproc_i2c_remove,
++ .remove_new = bcm_iproc_i2c_remove,
+ };
+ module_platform_driver(bcm_iproc_i2c_driver);
+
+diff --git a/drivers/i2c/busses/i2c-bcm-kona.c b/drivers/i2c/busses/i2c-bcm-kona.c
+index f3e369f0fd402..a57088ec2b064 100644
+--- a/drivers/i2c/busses/i2c-bcm-kona.c
++++ b/drivers/i2c/busses/i2c-bcm-kona.c
+@@ -859,13 +859,11 @@ static int bcm_kona_i2c_probe(struct platform_device *pdev)
+ return rc;
+ }
+
+-static int bcm_kona_i2c_remove(struct platform_device *pdev)
++static void bcm_kona_i2c_remove(struct platform_device *pdev)
+ {
+ struct bcm_kona_i2c_dev *dev = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&dev->adapter);
+-
+- return 0;
+ }
+
+ static const struct of_device_id bcm_kona_i2c_of_match[] = {
+@@ -880,7 +878,7 @@ static struct platform_driver bcm_kona_i2c_driver = {
+ .of_match_table = bcm_kona_i2c_of_match,
+ },
+ .probe = bcm_kona_i2c_probe,
+- .remove = bcm_kona_i2c_remove,
++ .remove_new = bcm_kona_i2c_remove,
+ };
+ module_platform_driver(bcm_kona_i2c_driver);
+
+diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
+index 09a077b31bfe1..8ce6d3f495516 100644
+--- a/drivers/i2c/busses/i2c-bcm2835.c
++++ b/drivers/i2c/busses/i2c-bcm2835.c
+@@ -503,7 +503,7 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int bcm2835_i2c_remove(struct platform_device *pdev)
++static void bcm2835_i2c_remove(struct platform_device *pdev)
+ {
+ struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+
+@@ -512,8 +512,6 @@ static int bcm2835_i2c_remove(struct platform_device *pdev)
+
+ free_irq(i2c_dev->irq, i2c_dev);
+ i2c_del_adapter(&i2c_dev->adapter);
+-
+- return 0;
+ }
+
+ static const struct of_device_id bcm2835_i2c_of_match[] = {
+@@ -525,7 +523,7 @@ MODULE_DEVICE_TABLE(of, bcm2835_i2c_of_match);
+
+ static struct platform_driver bcm2835_i2c_driver = {
+ .probe = bcm2835_i2c_probe,
+- .remove = bcm2835_i2c_remove,
++ .remove_new = bcm2835_i2c_remove,
+ .driver = {
+ .name = "i2c-bcm2835",
+ .of_match_table = bcm2835_i2c_of_match,
+diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c
+index 69383be479059..26ee25f5f631c 100644
+--- a/drivers/i2c/busses/i2c-brcmstb.c
++++ b/drivers/i2c/busses/i2c-brcmstb.c
+@@ -692,12 +692,11 @@ static int brcmstb_i2c_probe(struct platform_device *pdev)
+ return rc;
+ }
+
+-static int brcmstb_i2c_remove(struct platform_device *pdev)
++static void brcmstb_i2c_remove(struct platform_device *pdev)
+ {
+ struct brcmstb_i2c_dev *dev = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&dev->adapter);
+- return 0;
+ }
+
+ #ifdef CONFIG_PM_SLEEP
+@@ -738,7 +737,7 @@ static struct platform_driver brcmstb_i2c_driver = {
+ .pm = &brcmstb_i2c_pm,
+ },
+ .probe = brcmstb_i2c_probe,
+- .remove = brcmstb_i2c_remove,
++ .remove_new = brcmstb_i2c_remove,
+ };
+ module_platform_driver(brcmstb_i2c_driver);
+
+diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
+index 982c207d473b7..5749340474a2f 100644
+--- a/drivers/i2c/busses/i2c-cadence.c
++++ b/drivers/i2c/busses/i2c-cadence.c
+@@ -1359,7 +1359,7 @@ static int cdns_i2c_probe(struct platform_device *pdev)
+ *
+ * Return: 0 always
+ */
+-static int cdns_i2c_remove(struct platform_device *pdev)
++static void cdns_i2c_remove(struct platform_device *pdev)
+ {
+ struct cdns_i2c *id = platform_get_drvdata(pdev);
+
+@@ -1370,8 +1370,6 @@ static int cdns_i2c_remove(struct platform_device *pdev)
+ i2c_del_adapter(&id->adap);
+ clk_notifier_unregister(id->clk, &id->clk_rate_change_nb);
+ clk_disable_unprepare(id->clk);
+-
+- return 0;
+ }
+
+ static struct platform_driver cdns_i2c_drv = {
+@@ -1381,7 +1379,7 @@ static struct platform_driver cdns_i2c_drv = {
+ .pm = &cdns_i2c_dev_pm_ops,
+ },
+ .probe = cdns_i2c_probe,
+- .remove = cdns_i2c_remove,
++ .remove_new = cdns_i2c_remove,
+ };
+
+ module_platform_driver(cdns_i2c_drv);
+diff --git a/drivers/i2c/busses/i2c-cbus-gpio.c b/drivers/i2c/busses/i2c-cbus-gpio.c
+index d97c61eec95c1..fdc1758a32756 100644
+--- a/drivers/i2c/busses/i2c-cbus-gpio.c
++++ b/drivers/i2c/busses/i2c-cbus-gpio.c
+@@ -200,13 +200,11 @@ static const struct i2c_algorithm cbus_i2c_algo = {
+ .functionality = cbus_i2c_func,
+ };
+
+-static int cbus_i2c_remove(struct platform_device *pdev)
++static void cbus_i2c_remove(struct platform_device *pdev)
+ {
+ struct i2c_adapter *adapter = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(adapter);
+-
+- return 0;
+ }
+
+ static int cbus_i2c_probe(struct platform_device *pdev)
+@@ -266,7 +264,7 @@ MODULE_DEVICE_TABLE(of, i2c_cbus_dt_ids);
+
+ static struct platform_driver cbus_i2c_driver = {
+ .probe = cbus_i2c_probe,
+- .remove = cbus_i2c_remove,
++ .remove_new = cbus_i2c_remove,
+ .driver = {
+ .name = "i2c-cbus-gpio",
+ .of_match_table = of_match_ptr(i2c_cbus_dt_ids),
+diff --git a/drivers/i2c/busses/i2c-cht-wc.c b/drivers/i2c/busses/i2c-cht-wc.c
+index 2b2c3d090089e..0209933b9a847 100644
+--- a/drivers/i2c/busses/i2c-cht-wc.c
++++ b/drivers/i2c/busses/i2c-cht-wc.c
+@@ -529,15 +529,13 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev)
++static void cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev)
+ {
+ struct cht_wc_i2c_adap *adap = platform_get_drvdata(pdev);
+
+ i2c_unregister_device(adap->client);
+ i2c_del_adapter(&adap->adapter);
+ irq_domain_remove(adap->irq_domain);
+-
+- return 0;
+ }
+
+ static const struct platform_device_id cht_wc_i2c_adap_id_table[] = {
+@@ -548,7 +546,7 @@ MODULE_DEVICE_TABLE(platform, cht_wc_i2c_adap_id_table);
+
+ static struct platform_driver cht_wc_i2c_adap_driver = {
+ .probe = cht_wc_i2c_adap_i2c_probe,
+- .remove = cht_wc_i2c_adap_i2c_remove,
++ .remove_new = cht_wc_i2c_adap_i2c_remove,
+ .driver = {
+ .name = "cht_wcove_ext_chgr",
+ },
+diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
+index 24d584a1c9a78..732daf6a932b3 100644
+--- a/drivers/i2c/busses/i2c-cpm.c
++++ b/drivers/i2c/busses/i2c-cpm.c
+@@ -676,7 +676,7 @@ static int cpm_i2c_probe(struct platform_device *ofdev)
+ return result;
+ }
+
+-static int cpm_i2c_remove(struct platform_device *ofdev)
++static void cpm_i2c_remove(struct platform_device *ofdev)
+ {
+ struct cpm_i2c *cpm = platform_get_drvdata(ofdev);
+
+@@ -685,8 +685,6 @@ static int cpm_i2c_remove(struct platform_device *ofdev)
+ cpm_i2c_shutdown(cpm);
+
+ kfree(cpm);
+-
+- return 0;
+ }
+
+ static const struct of_device_id cpm_i2c_match[] = {
+@@ -703,7 +701,7 @@ MODULE_DEVICE_TABLE(of, cpm_i2c_match);
+
+ static struct platform_driver cpm_i2c_driver = {
+ .probe = cpm_i2c_probe,
+- .remove = cpm_i2c_remove,
++ .remove_new = cpm_i2c_remove,
+ .driver = {
+ .name = "fsl-i2c-cpm",
+ .of_match_table = cpm_i2c_match,
+diff --git a/drivers/i2c/busses/i2c-cros-ec-tunnel.c b/drivers/i2c/busses/i2c-cros-ec-tunnel.c
+index 4e787dc709f91..d3fb1a86296fd 100644
+--- a/drivers/i2c/busses/i2c-cros-ec-tunnel.c
++++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c
+@@ -283,13 +283,11 @@ static int ec_i2c_probe(struct platform_device *pdev)
+ return err;
+ }
+
+-static int ec_i2c_remove(struct platform_device *dev)
++static void ec_i2c_remove(struct platform_device *dev)
+ {
+ struct ec_i2c_device *bus = platform_get_drvdata(dev);
+
+ i2c_del_adapter(&bus->adap);
+-
+- return 0;
+ }
+
+ static const struct of_device_id cros_ec_i2c_of_match[] = {
+@@ -306,7 +304,7 @@ MODULE_DEVICE_TABLE(acpi, cros_ec_i2c_tunnel_acpi_id);
+
+ static struct platform_driver ec_i2c_tunnel_driver = {
+ .probe = ec_i2c_probe,
+- .remove = ec_i2c_remove,
++ .remove_new = ec_i2c_remove,
+ .driver = {
+ .name = "cros-ec-i2c-tunnel",
+ .acpi_match_table = ACPI_PTR(cros_ec_i2c_tunnel_acpi_id),
+diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
+index c836cf8841850..5010501e8e87e 100644
+--- a/drivers/i2c/busses/i2c-davinci.c
++++ b/drivers/i2c/busses/i2c-davinci.c
+@@ -888,7 +888,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
+ return r;
+ }
+
+-static int davinci_i2c_remove(struct platform_device *pdev)
++static void davinci_i2c_remove(struct platform_device *pdev)
+ {
+ struct davinci_i2c_dev *dev = platform_get_drvdata(pdev);
+ int ret;
+@@ -897,17 +897,15 @@ static int davinci_i2c_remove(struct platform_device *pdev)
+
+ i2c_del_adapter(&dev->adapter);
+
+- ret = pm_runtime_resume_and_get(&pdev->dev);
++ ret = pm_runtime_get_sync(&pdev->dev);
+ if (ret < 0)
+- return ret;
+-
+- davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0);
++ dev_err(&pdev->dev, "Failed to resume device\n");
++ else
++ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0);
+
+ pm_runtime_dont_use_autosuspend(dev->dev);
+ pm_runtime_put_sync(dev->dev);
+ pm_runtime_disable(dev->dev);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_PM
+@@ -948,7 +946,7 @@ MODULE_ALIAS("platform:i2c_davinci");
+
+ static struct platform_driver davinci_i2c_driver = {
+ .probe = davinci_i2c_probe,
+- .remove = davinci_i2c_remove,
++ .remove_new = davinci_i2c_remove,
+ .driver = {
+ .name = "i2c_davinci",
+ .pm = davinci_i2c_pm_ops,
+diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
+index 74182db03a88b..21537b1cd03f0 100644
+--- a/drivers/i2c/busses/i2c-designware-platdrv.c
++++ b/drivers/i2c/busses/i2c-designware-platdrv.c
+@@ -385,7 +385,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int dw_i2c_plat_remove(struct platform_device *pdev)
++static void dw_i2c_plat_remove(struct platform_device *pdev)
+ {
+ struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
+
+@@ -402,8 +402,6 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
+ i2c_dw_remove_lock_support(dev);
+
+ reset_control_assert(dev->rst);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_PM_SLEEP
+@@ -482,7 +480,7 @@ MODULE_ALIAS("platform:i2c_designware");
+
+ static struct platform_driver dw_i2c_driver = {
+ .probe = dw_i2c_plat_probe,
+- .remove = dw_i2c_plat_remove,
++ .remove_new = dw_i2c_plat_remove,
+ .driver = {
+ .name = "i2c_designware",
+ .of_match_table = of_match_ptr(dw_i2c_of_match),
+diff --git a/drivers/i2c/busses/i2c-digicolor.c b/drivers/i2c/busses/i2c-digicolor.c
+index 50925d97fa429..3462f2bc0fa87 100644
+--- a/drivers/i2c/busses/i2c-digicolor.c
++++ b/drivers/i2c/busses/i2c-digicolor.c
+@@ -347,14 +347,12 @@ static int dc_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int dc_i2c_remove(struct platform_device *pdev)
++static void dc_i2c_remove(struct platform_device *pdev)
+ {
+ struct dc_i2c *i2c = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c->adap);
+ clk_disable_unprepare(i2c->clk);
+-
+- return 0;
+ }
+
+ static const struct of_device_id dc_i2c_match[] = {
+@@ -365,7 +363,7 @@ MODULE_DEVICE_TABLE(of, dc_i2c_match);
+
+ static struct platform_driver dc_i2c_driver = {
+ .probe = dc_i2c_probe,
+- .remove = dc_i2c_remove,
++ .remove_new = dc_i2c_remove,
+ .driver = {
+ .name = "digicolor-i2c",
+ .of_match_table = dc_i2c_match,
+diff --git a/drivers/i2c/busses/i2c-dln2.c b/drivers/i2c/busses/i2c-dln2.c
+index 2a2089db71a5e..4f02cc2fb5675 100644
+--- a/drivers/i2c/busses/i2c-dln2.c
++++ b/drivers/i2c/busses/i2c-dln2.c
+@@ -236,20 +236,18 @@ static int dln2_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int dln2_i2c_remove(struct platform_device *pdev)
++static void dln2_i2c_remove(struct platform_device *pdev)
+ {
+ struct dln2_i2c *dln2 = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&dln2->adapter);
+ dln2_i2c_enable(dln2, false);
+-
+- return 0;
+ }
+
+ static struct platform_driver dln2_i2c_driver = {
+ .driver.name = "dln2-i2c",
+ .probe = dln2_i2c_probe,
+- .remove = dln2_i2c_remove,
++ .remove_new = dln2_i2c_remove,
+ };
+
+ module_platform_driver(dln2_i2c_driver);
+diff --git a/drivers/i2c/busses/i2c-emev2.c b/drivers/i2c/busses/i2c-emev2.c
+index f2e537b137b20..4ba93cd91c0f0 100644
+--- a/drivers/i2c/busses/i2c-emev2.c
++++ b/drivers/i2c/busses/i2c-emev2.c
+@@ -419,14 +419,12 @@ static int em_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int em_i2c_remove(struct platform_device *dev)
++static void em_i2c_remove(struct platform_device *dev)
+ {
+ struct em_i2c_device *priv = platform_get_drvdata(dev);
+
+ i2c_del_adapter(&priv->adap);
+ clk_disable_unprepare(priv->sclk);
+-
+- return 0;
+ }
+
+ static const struct of_device_id em_i2c_ids[] = {
+@@ -436,7 +434,7 @@ static const struct of_device_id em_i2c_ids[] = {
+
+ static struct platform_driver em_i2c_driver = {
+ .probe = em_i2c_probe,
+- .remove = em_i2c_remove,
++ .remove_new = em_i2c_remove,
+ .driver = {
+ .name = "em-i2c",
+ .of_match_table = em_i2c_ids,
+diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
+index 4a6260d04db28..f378cd479e558 100644
+--- a/drivers/i2c/busses/i2c-exynos5.c
++++ b/drivers/i2c/busses/i2c-exynos5.c
+@@ -882,7 +882,7 @@ static int exynos5_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int exynos5_i2c_remove(struct platform_device *pdev)
++static void exynos5_i2c_remove(struct platform_device *pdev)
+ {
+ struct exynos5_i2c *i2c = platform_get_drvdata(pdev);
+
+@@ -890,8 +890,6 @@ static int exynos5_i2c_remove(struct platform_device *pdev)
+
+ clk_unprepare(i2c->clk);
+ clk_unprepare(i2c->pclk);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_PM_SLEEP
+@@ -945,7 +943,7 @@ static const struct dev_pm_ops exynos5_i2c_dev_pm_ops = {
+
+ static struct platform_driver exynos5_i2c_driver = {
+ .probe = exynos5_i2c_probe,
+- .remove = exynos5_i2c_remove,
++ .remove_new = exynos5_i2c_remove,
+ .driver = {
+ .name = "exynos5-hsi2c",
+ .pm = &exynos5_i2c_dev_pm_ops,
+diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
+index 1794c0399f22d..e5a5b9e8bf2c7 100644
+--- a/drivers/i2c/busses/i2c-gpio.c
++++ b/drivers/i2c/busses/i2c-gpio.c
+@@ -475,7 +475,7 @@ static int i2c_gpio_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int i2c_gpio_remove(struct platform_device *pdev)
++static void i2c_gpio_remove(struct platform_device *pdev)
+ {
+ struct i2c_gpio_private_data *priv;
+ struct i2c_adapter *adap;
+@@ -486,8 +486,6 @@ static int i2c_gpio_remove(struct platform_device *pdev)
+ adap = &priv->adap;
+
+ i2c_del_adapter(adap);
+-
+- return 0;
+ }
+
+ static const struct of_device_id i2c_gpio_dt_ids[] = {
+@@ -510,7 +508,7 @@ static struct platform_driver i2c_gpio_driver = {
+ .acpi_match_table = i2c_gpio_acpi_match,
+ },
+ .probe = i2c_gpio_probe,
+- .remove = i2c_gpio_remove,
++ .remove_new = i2c_gpio_remove,
+ };
+
+ static int __init i2c_gpio_init(void)
+diff --git a/drivers/i2c/busses/i2c-gxp.c b/drivers/i2c/busses/i2c-gxp.c
+index 8ea3fb5e4c7f7..70b0de07ed99a 100644
+--- a/drivers/i2c/busses/i2c-gxp.c
++++ b/drivers/i2c/busses/i2c-gxp.c
+@@ -577,15 +577,13 @@ static int gxp_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int gxp_i2c_remove(struct platform_device *pdev)
++static void gxp_i2c_remove(struct platform_device *pdev)
+ {
+ struct gxp_i2c_drvdata *drvdata = platform_get_drvdata(pdev);
+
+ /* Disable interrupt */
+ regmap_update_bits(i2cg_map, GXP_I2CINTEN, BIT(drvdata->engine), 0);
+ i2c_del_adapter(&drvdata->adapter);
+-
+- return 0;
+ }
+
+ static const struct of_device_id gxp_i2c_of_match[] = {
+@@ -596,7 +594,7 @@ MODULE_DEVICE_TABLE(of, gxp_i2c_of_match);
+
+ static struct platform_driver gxp_i2c_driver = {
+ .probe = gxp_i2c_probe,
+- .remove = gxp_i2c_remove,
++ .remove_new = gxp_i2c_remove,
+ .driver = {
+ .name = "gxp-i2c",
+ .of_match_table = gxp_i2c_of_match,
+diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c
+index 4374a86772717..7922bc917c33a 100644
+--- a/drivers/i2c/busses/i2c-highlander.c
++++ b/drivers/i2c/busses/i2c-highlander.c
+@@ -435,7 +435,7 @@ static int highlander_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int highlander_i2c_remove(struct platform_device *pdev)
++static void highlander_i2c_remove(struct platform_device *pdev)
+ {
+ struct highlander_i2c_dev *dev = platform_get_drvdata(pdev);
+
+@@ -446,8 +446,6 @@ static int highlander_i2c_remove(struct platform_device *pdev)
+
+ iounmap(dev->base);
+ kfree(dev);
+-
+- return 0;
+ }
+
+ static struct platform_driver highlander_i2c_driver = {
+@@ -456,7 +454,7 @@ static struct platform_driver highlander_i2c_driver = {
+ },
+
+ .probe = highlander_i2c_probe,
+- .remove = highlander_i2c_remove,
++ .remove_new = highlander_i2c_remove,
+ };
+
+ module_platform_driver(highlander_i2c_driver);
+diff --git a/drivers/i2c/busses/i2c-hix5hd2.c b/drivers/i2c/busses/i2c-hix5hd2.c
+index 0e34cbaca22dc..64feaa9dca619 100644
+--- a/drivers/i2c/busses/i2c-hix5hd2.c
++++ b/drivers/i2c/busses/i2c-hix5hd2.c
+@@ -464,7 +464,7 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int hix5hd2_i2c_remove(struct platform_device *pdev)
++static void hix5hd2_i2c_remove(struct platform_device *pdev)
+ {
+ struct hix5hd2_i2c_priv *priv = platform_get_drvdata(pdev);
+
+@@ -472,8 +472,6 @@ static int hix5hd2_i2c_remove(struct platform_device *pdev)
+ pm_runtime_disable(priv->dev);
+ pm_runtime_set_suspended(priv->dev);
+ clk_disable_unprepare(priv->clk);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_PM
+@@ -511,7 +509,7 @@ MODULE_DEVICE_TABLE(of, hix5hd2_i2c_match);
+
+ static struct platform_driver hix5hd2_i2c_driver = {
+ .probe = hix5hd2_i2c_probe,
+- .remove = hix5hd2_i2c_remove,
++ .remove_new = hix5hd2_i2c_remove,
+ .driver = {
+ .name = "hix5hd2-i2c",
+ .pm = &hix5hd2_i2c_pm_ops,
+diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
+index eeb80e34f9ad7..2d11577ded38a 100644
+--- a/drivers/i2c/busses/i2c-ibm_iic.c
++++ b/drivers/i2c/busses/i2c-ibm_iic.c
+@@ -769,7 +769,7 @@ static int iic_probe(struct platform_device *ofdev)
+ /*
+ * Cleanup initialized IIC interface
+ */
+-static int iic_remove(struct platform_device *ofdev)
++static void iic_remove(struct platform_device *ofdev)
+ {
+ struct ibm_iic_private *dev = platform_get_drvdata(ofdev);
+
+@@ -782,8 +782,6 @@ static int iic_remove(struct platform_device *ofdev)
+
+ iounmap(dev->vaddr);
+ kfree(dev);
+-
+- return 0;
+ }
+
+ static const struct of_device_id ibm_iic_match[] = {
+@@ -798,7 +796,7 @@ static struct platform_driver ibm_iic_driver = {
+ .of_match_table = ibm_iic_match,
+ },
+ .probe = iic_probe,
+- .remove = iic_remove,
++ .remove_new = iic_remove,
+ };
+
+ module_platform_driver(ibm_iic_driver);
+diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c
+index 8e987945ed450..fea2940dbf2e7 100644
+--- a/drivers/i2c/busses/i2c-img-scb.c
++++ b/drivers/i2c/busses/i2c-img-scb.c
+@@ -1413,7 +1413,7 @@ static int img_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int img_i2c_remove(struct platform_device *dev)
++static void img_i2c_remove(struct platform_device *dev)
+ {
+ struct img_i2c *i2c = platform_get_drvdata(dev);
+
+@@ -1421,8 +1421,6 @@ static int img_i2c_remove(struct platform_device *dev)
+ pm_runtime_disable(&dev->dev);
+ if (!pm_runtime_status_suspended(&dev->dev))
+ img_i2c_runtime_suspend(&dev->dev);
+-
+- return 0;
+ }
+
+ static int img_i2c_runtime_suspend(struct device *dev)
+@@ -1506,7 +1504,7 @@ static struct platform_driver img_scb_i2c_driver = {
+ .pm = &img_i2c_pm,
+ },
+ .probe = img_i2c_probe,
+- .remove = img_i2c_remove,
++ .remove_new = img_i2c_remove,
+ };
+ module_platform_driver(img_scb_i2c_driver);
+
+diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
+index ff12018bc2060..20092e8236cb0 100644
+--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
++++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
+@@ -623,7 +623,7 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int lpi2c_imx_remove(struct platform_device *pdev)
++static void lpi2c_imx_remove(struct platform_device *pdev)
+ {
+ struct lpi2c_imx_struct *lpi2c_imx = platform_get_drvdata(pdev);
+
+@@ -631,8 +631,6 @@ static int lpi2c_imx_remove(struct platform_device *pdev)
+
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+-
+- return 0;
+ }
+
+ static int __maybe_unused lpi2c_runtime_suspend(struct device *dev)
+@@ -669,7 +667,7 @@ static const struct dev_pm_ops lpi2c_pm_ops = {
+
+ static struct platform_driver lpi2c_imx_driver = {
+ .probe = lpi2c_imx_probe,
+- .remove = lpi2c_imx_remove,
++ .remove_new = lpi2c_imx_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = lpi2c_imx_of_match,
+diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
+index cf5bacf3a4884..f093fdb584373 100644
+--- a/drivers/i2c/busses/i2c-imx.c
++++ b/drivers/i2c/busses/i2c-imx.c
+@@ -1568,7 +1568,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int i2c_imx_remove(struct platform_device *pdev)
++static void i2c_imx_remove(struct platform_device *pdev)
+ {
+ struct imx_i2c_struct *i2c_imx = platform_get_drvdata(pdev);
+ int irq, ret;
+@@ -1602,8 +1602,6 @@ static int i2c_imx_remove(struct platform_device *pdev)
+
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+-
+- return 0;
+ }
+
+ static int __maybe_unused i2c_imx_runtime_suspend(struct device *dev)
+@@ -1634,7 +1632,7 @@ static const struct dev_pm_ops i2c_imx_pm_ops = {
+
+ static struct platform_driver i2c_imx_driver = {
+ .probe = i2c_imx_probe,
+- .remove = i2c_imx_remove,
++ .remove_new = i2c_imx_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .pm = &i2c_imx_pm_ops,
+diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
+index 4a6ff54d87fe8..f2f7ebeeaecb0 100644
+--- a/drivers/i2c/busses/i2c-iop3xx.c
++++ b/drivers/i2c/busses/i2c-iop3xx.c
+@@ -388,7 +388,7 @@ static const struct i2c_algorithm iop3xx_i2c_algo = {
+ .functionality = iop3xx_i2c_func,
+ };
+
+-static int
++static void
+ iop3xx_i2c_remove(struct platform_device *pdev)
+ {
+ struct i2c_adapter *padapter = platform_get_drvdata(pdev);
+@@ -408,8 +408,6 @@ iop3xx_i2c_remove(struct platform_device *pdev)
+ release_mem_region(res->start, IOP3XX_I2C_IO_SIZE);
+ kfree(adapter_data);
+ kfree(padapter);
+-
+- return 0;
+ }
+
+ static int
+@@ -529,7 +527,7 @@ MODULE_DEVICE_TABLE(of, i2c_iop3xx_match);
+
+ static struct platform_driver iop3xx_i2c_driver = {
+ .probe = iop3xx_i2c_probe,
+- .remove = iop3xx_i2c_remove,
++ .remove_new = iop3xx_i2c_remove,
+ .driver = {
+ .name = "IOP3xx-I2C",
+ .of_match_table = i2c_iop3xx_match,
+diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c
+index 2dc7ada06ac50..1dc1ceaa44439 100644
+--- a/drivers/i2c/busses/i2c-isch.c
++++ b/drivers/i2c/busses/i2c-isch.c
+@@ -286,14 +286,12 @@ static int smbus_sch_probe(struct platform_device *dev)
+ return retval;
+ }
+
+-static int smbus_sch_remove(struct platform_device *pdev)
++static void smbus_sch_remove(struct platform_device *pdev)
+ {
+ if (sch_smba) {
+ i2c_del_adapter(&sch_adapter);
+ sch_smba = 0;
+ }
+-
+- return 0;
+ }
+
+ static struct platform_driver smbus_sch_driver = {
+@@ -301,7 +299,7 @@ static struct platform_driver smbus_sch_driver = {
+ .name = "isch_smbus",
+ },
+ .probe = smbus_sch_probe,
+- .remove = smbus_sch_remove,
++ .remove_new = smbus_sch_remove,
+ };
+
+ module_platform_driver(smbus_sch_driver);
+diff --git a/drivers/i2c/busses/i2c-jz4780.c b/drivers/i2c/busses/i2c-jz4780.c
+index baa7319eee539..0dfe603995214 100644
+--- a/drivers/i2c/busses/i2c-jz4780.c
++++ b/drivers/i2c/busses/i2c-jz4780.c
+@@ -845,18 +845,17 @@ static int jz4780_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int jz4780_i2c_remove(struct platform_device *pdev)
++static void jz4780_i2c_remove(struct platform_device *pdev)
+ {
+ struct jz4780_i2c *i2c = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(i2c->clk);
+ i2c_del_adapter(&i2c->adap);
+- return 0;
+ }
+
+ static struct platform_driver jz4780_i2c_driver = {
+ .probe = jz4780_i2c_probe,
+- .remove = jz4780_i2c_remove,
++ .remove_new = jz4780_i2c_remove,
+ .driver = {
+ .name = "jz4780-i2c",
+ .of_match_table = jz4780_i2c_of_matches,
+diff --git a/drivers/i2c/busses/i2c-kempld.c b/drivers/i2c/busses/i2c-kempld.c
+index cf857cf225070..281058e3ea463 100644
+--- a/drivers/i2c/busses/i2c-kempld.c
++++ b/drivers/i2c/busses/i2c-kempld.c
+@@ -329,7 +329,7 @@ static int kempld_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int kempld_i2c_remove(struct platform_device *pdev)
++static void kempld_i2c_remove(struct platform_device *pdev)
+ {
+ struct kempld_i2c_data *i2c = platform_get_drvdata(pdev);
+ struct kempld_device_data *pld = i2c->pld;
+@@ -348,8 +348,6 @@ static int kempld_i2c_remove(struct platform_device *pdev)
+ kempld_release_mutex(pld);
+
+ i2c_del_adapter(&i2c->adap);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_PM
+@@ -389,7 +387,7 @@ static struct platform_driver kempld_i2c_driver = {
+ .name = "kempld-i2c",
+ },
+ .probe = kempld_i2c_probe,
+- .remove = kempld_i2c_remove,
++ .remove_new = kempld_i2c_remove,
+ .suspend = kempld_i2c_suspend,
+ .resume = kempld_i2c_resume,
+ };
+diff --git a/drivers/i2c/busses/i2c-lpc2k.c b/drivers/i2c/busses/i2c-lpc2k.c
+index 8fff6fbb7065c..469fe907723e8 100644
+--- a/drivers/i2c/busses/i2c-lpc2k.c
++++ b/drivers/i2c/busses/i2c-lpc2k.c
+@@ -435,14 +435,12 @@ static int i2c_lpc2k_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int i2c_lpc2k_remove(struct platform_device *dev)
++static void i2c_lpc2k_remove(struct platform_device *dev)
+ {
+ struct lpc2k_i2c *i2c = platform_get_drvdata(dev);
+
+ i2c_del_adapter(&i2c->adap);
+ clk_disable_unprepare(i2c->clk);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_PM
+@@ -483,7 +481,7 @@ MODULE_DEVICE_TABLE(of, lpc2k_i2c_match);
+
+ static struct platform_driver i2c_lpc2k_driver = {
+ .probe = i2c_lpc2k_probe,
+- .remove = i2c_lpc2k_remove,
++ .remove_new = i2c_lpc2k_remove,
+ .driver = {
+ .name = "lpc2k-i2c",
+ .pm = I2C_LPC2K_DEV_PM_OPS,
+diff --git a/drivers/i2c/busses/i2c-meson.c b/drivers/i2c/busses/i2c-meson.c
+index 889eff06b78f4..16026c895bb65 100644
+--- a/drivers/i2c/busses/i2c-meson.c
++++ b/drivers/i2c/busses/i2c-meson.c
+@@ -535,14 +535,12 @@ static int meson_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int meson_i2c_remove(struct platform_device *pdev)
++static void meson_i2c_remove(struct platform_device *pdev)
+ {
+ struct meson_i2c *i2c = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c->adap);
+ clk_disable_unprepare(i2c->clk);
+-
+- return 0;
+ }
+
+ static const struct meson_i2c_data i2c_meson6_data = {
+@@ -568,7 +566,7 @@ MODULE_DEVICE_TABLE(of, meson_i2c_match);
+
+ static struct platform_driver meson_i2c_driver = {
+ .probe = meson_i2c_probe,
+- .remove = meson_i2c_remove,
++ .remove_new = meson_i2c_remove,
+ .driver = {
+ .name = "meson-i2c",
+ .of_match_table = meson_i2c_match,
+diff --git a/drivers/i2c/busses/i2c-microchip-corei2c.c b/drivers/i2c/busses/i2c-microchip-corei2c.c
+index 4d7e9b25f018b..7f58f7eaabb63 100644
+--- a/drivers/i2c/busses/i2c-microchip-corei2c.c
++++ b/drivers/i2c/busses/i2c-microchip-corei2c.c
+@@ -446,14 +446,12 @@ static int mchp_corei2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int mchp_corei2c_remove(struct platform_device *pdev)
++static void mchp_corei2c_remove(struct platform_device *pdev)
+ {
+ struct mchp_corei2c_dev *idev = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(idev->i2c_clk);
+ i2c_del_adapter(&idev->adapter);
+-
+- return 0;
+ }
+
+ static const struct of_device_id mchp_corei2c_of_match[] = {
+@@ -465,7 +463,7 @@ MODULE_DEVICE_TABLE(of, mchp_corei2c_of_match);
+
+ static struct platform_driver mchp_corei2c_driver = {
+ .probe = mchp_corei2c_probe,
+- .remove = mchp_corei2c_remove,
++ .remove_new = mchp_corei2c_remove,
+ .driver = {
+ .name = "microchip-corei2c",
+ .of_match_table = mchp_corei2c_of_match,
+diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c
+index 1810d5791b3d7..ae66bdd1b7379 100644
+--- a/drivers/i2c/busses/i2c-mlxbf.c
++++ b/drivers/i2c/busses/i2c-mlxbf.c
+@@ -2433,7 +2433,7 @@ static int mlxbf_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int mlxbf_i2c_remove(struct platform_device *pdev)
++static void mlxbf_i2c_remove(struct platform_device *pdev)
+ {
+ struct mlxbf_i2c_priv *priv = platform_get_drvdata(pdev);
+ struct device *dev = &pdev->dev;
+@@ -2474,13 +2474,11 @@ static int mlxbf_i2c_remove(struct platform_device *pdev)
+ devm_free_irq(dev, priv->irq, priv);
+
+ i2c_del_adapter(&priv->adap);
+-
+- return 0;
+ }
+
+ static struct platform_driver mlxbf_i2c_driver = {
+ .probe = mlxbf_i2c_probe,
+- .remove = mlxbf_i2c_remove,
++ .remove_new = mlxbf_i2c_remove,
+ .driver = {
+ .name = "i2c-mlxbf",
+ .acpi_match_table = ACPI_PTR(mlxbf_i2c_acpi_ids),
+diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c
+index 081f51ef0551b..c42fd4b329e4b 100644
+--- a/drivers/i2c/busses/i2c-mlxcpld.c
++++ b/drivers/i2c/busses/i2c-mlxcpld.c
+@@ -571,19 +571,17 @@ static int mlxcpld_i2c_probe(struct platform_device *pdev)
+ return err;
+ }
+
+-static int mlxcpld_i2c_remove(struct platform_device *pdev)
++static void mlxcpld_i2c_remove(struct platform_device *pdev)
+ {
+ struct mlxcpld_i2c_priv *priv = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&priv->adap);
+ mutex_destroy(&priv->lock);
+-
+- return 0;
+ }
+
+ static struct platform_driver mlxcpld_i2c_driver = {
+ .probe = mlxcpld_i2c_probe,
+- .remove = mlxcpld_i2c_remove,
++ .remove_new = mlxcpld_i2c_remove,
+ .driver = {
+ .name = MLXCPLD_I2C_DEVICE_NAME,
+ },
+diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
+index 81ac92bb4f6f1..c1afd618ec1cb 100644
+--- a/drivers/i2c/busses/i2c-mpc.c
++++ b/drivers/i2c/busses/i2c-mpc.c
+@@ -879,15 +879,13 @@ static int fsl_i2c_probe(struct platform_device *op)
+ return result;
+ };
+
+-static int fsl_i2c_remove(struct platform_device *op)
++static void fsl_i2c_remove(struct platform_device *op)
+ {
+ struct mpc_i2c *i2c = platform_get_drvdata(op);
+
+ i2c_del_adapter(&i2c->adap);
+
+ clk_disable_unprepare(i2c->clk_per);
+-
+- return 0;
+ };
+
+ static int __maybe_unused mpc_i2c_suspend(struct device *dev)
+@@ -948,7 +946,7 @@ MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
+ /* Structure for a device driver */
+ static struct platform_driver mpc_i2c_driver = {
+ .probe = fsl_i2c_probe,
+- .remove = fsl_i2c_remove,
++ .remove_new = fsl_i2c_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .of_match_table = mpc_i2c_of_match,
+diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
+index 43dd966d5ef58..263dd8d3484fb 100644
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -1492,15 +1492,13 @@ static int mtk_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int mtk_i2c_remove(struct platform_device *pdev)
++static void mtk_i2c_remove(struct platform_device *pdev)
+ {
+ struct mtk_i2c *i2c = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c->adap);
+
+ clk_bulk_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_PM_SLEEP
+@@ -1542,7 +1540,7 @@ static const struct dev_pm_ops mtk_i2c_pm = {
+
+ static struct platform_driver mtk_i2c_driver = {
+ .probe = mtk_i2c_probe,
+- .remove = mtk_i2c_remove,
++ .remove_new = mtk_i2c_remove,
+ .driver = {
+ .name = I2C_DRV_NAME,
+ .pm = &mtk_i2c_pm,
+diff --git a/drivers/i2c/busses/i2c-mt7621.c b/drivers/i2c/busses/i2c-mt7621.c
+index 20eda5738ac49..f9c294e2bd3c5 100644
+--- a/drivers/i2c/busses/i2c-mt7621.c
++++ b/drivers/i2c/busses/i2c-mt7621.c
+@@ -332,19 +332,17 @@ static int mtk_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int mtk_i2c_remove(struct platform_device *pdev)
++static void mtk_i2c_remove(struct platform_device *pdev)
+ {
+ struct mtk_i2c *i2c = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(i2c->clk);
+ i2c_del_adapter(&i2c->adap);
+-
+- return 0;
+ }
+
+ static struct platform_driver mtk_i2c_driver = {
+ .probe = mtk_i2c_probe,
+- .remove = mtk_i2c_remove,
++ .remove_new = mtk_i2c_remove,
+ .driver = {
+ .name = "i2c-mt7621",
+ .of_match_table = i2c_mtk_dt_ids,
+diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
+index 878c076ebdc6b..fd8403b07fa61 100644
+--- a/drivers/i2c/busses/i2c-mv64xxx.c
++++ b/drivers/i2c/busses/i2c-mv64xxx.c
+@@ -1084,7 +1084,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
+ return rc;
+ }
+
+-static int
++static void
+ mv64xxx_i2c_remove(struct platform_device *pd)
+ {
+ struct mv64xxx_i2c_data *drv_data = platform_get_drvdata(pd);
+@@ -1094,8 +1094,6 @@ mv64xxx_i2c_remove(struct platform_device *pd)
+ pm_runtime_disable(&pd->dev);
+ if (!pm_runtime_status_suspended(&pd->dev))
+ mv64xxx_i2c_runtime_suspend(&pd->dev);
+-
+- return 0;
+ }
+
+ static const struct dev_pm_ops mv64xxx_i2c_pm_ops = {
+@@ -1107,7 +1105,7 @@ static const struct dev_pm_ops mv64xxx_i2c_pm_ops = {
+
+ static struct platform_driver mv64xxx_i2c_driver = {
+ .probe = mv64xxx_i2c_probe,
+- .remove = mv64xxx_i2c_remove,
++ .remove_new = mv64xxx_i2c_remove,
+ .driver = {
+ .name = MV64XXX_I2C_CTLR_NAME,
+ .pm = &mv64xxx_i2c_pm_ops,
+diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
+index e0f3b3545cfe4..1d76f1c4dc06a 100644
+--- a/drivers/i2c/busses/i2c-mxs.c
++++ b/drivers/i2c/busses/i2c-mxs.c
+@@ -864,7 +864,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int mxs_i2c_remove(struct platform_device *pdev)
++static void mxs_i2c_remove(struct platform_device *pdev)
+ {
+ struct mxs_i2c_dev *i2c = platform_get_drvdata(pdev);
+
+@@ -874,8 +874,6 @@ static int mxs_i2c_remove(struct platform_device *pdev)
+ dma_release_channel(i2c->dmach);
+
+ writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
+-
+- return 0;
+ }
+
+ static struct platform_driver mxs_i2c_driver = {
+@@ -884,7 +882,7 @@ static struct platform_driver mxs_i2c_driver = {
+ .of_match_table = mxs_i2c_dt_ids,
+ },
+ .probe = mxs_i2c_probe,
+- .remove = mxs_i2c_remove,
++ .remove_new = mxs_i2c_remove,
+ };
+
+ static int __init mxs_i2c_init(void)
+diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c
+index 38d5864d0cb5b..53b65ffb6a647 100644
+--- a/drivers/i2c/busses/i2c-npcm7xx.c
++++ b/drivers/i2c/busses/i2c-npcm7xx.c
+@@ -2361,7 +2361,7 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int npcm_i2c_remove_bus(struct platform_device *pdev)
++static void npcm_i2c_remove_bus(struct platform_device *pdev)
+ {
+ unsigned long lock_flags;
+ struct npcm_i2c *bus = platform_get_drvdata(pdev);
+@@ -2371,7 +2371,6 @@ static int npcm_i2c_remove_bus(struct platform_device *pdev)
+ npcm_i2c_disable(bus);
+ spin_unlock_irqrestore(&bus->lock, lock_flags);
+ i2c_del_adapter(&bus->adap);
+- return 0;
+ }
+
+ static const struct of_device_id npcm_i2c_bus_of_table[] = {
+@@ -2383,7 +2382,7 @@ MODULE_DEVICE_TABLE(of, npcm_i2c_bus_of_table);
+
+ static struct platform_driver npcm_i2c_bus_driver = {
+ .probe = npcm_i2c_probe_bus,
+- .remove = npcm_i2c_remove_bus,
++ .remove_new = npcm_i2c_remove_bus,
+ .driver = {
+ .name = "nuvoton-i2c",
+ .of_match_table = npcm_i2c_bus_of_table,
+diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
+index 2e575856c5cd5..0742b84a11eb5 100644
+--- a/drivers/i2c/busses/i2c-ocores.c
++++ b/drivers/i2c/busses/i2c-ocores.c
+@@ -743,7 +743,7 @@ static int ocores_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int ocores_i2c_remove(struct platform_device *pdev)
++static void ocores_i2c_remove(struct platform_device *pdev)
+ {
+ struct ocores_i2c *i2c = platform_get_drvdata(pdev);
+ u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL);
+@@ -757,8 +757,6 @@ static int ocores_i2c_remove(struct platform_device *pdev)
+
+ if (!IS_ERR(i2c->clk))
+ clk_disable_unprepare(i2c->clk);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_PM_SLEEP
+@@ -804,7 +802,7 @@ static SIMPLE_DEV_PM_OPS(ocores_i2c_pm, ocores_i2c_suspend, ocores_i2c_resume);
+
+ static struct platform_driver ocores_i2c_driver = {
+ .probe = ocores_i2c_probe,
+- .remove = ocores_i2c_remove,
++ .remove_new = ocores_i2c_remove,
+ .driver = {
+ .name = "ocores-i2c",
+ .of_match_table = ocores_i2c_match,
+diff --git a/drivers/i2c/busses/i2c-octeon-platdrv.c b/drivers/i2c/busses/i2c-octeon-platdrv.c
+index 0c227963c8d69..7d54b3203f716 100644
+--- a/drivers/i2c/busses/i2c-octeon-platdrv.c
++++ b/drivers/i2c/busses/i2c-octeon-platdrv.c
+@@ -253,12 +253,11 @@ static int octeon_i2c_probe(struct platform_device *pdev)
+ return result;
+ };
+
+-static int octeon_i2c_remove(struct platform_device *pdev)
++static void octeon_i2c_remove(struct platform_device *pdev)
+ {
+ struct octeon_i2c *i2c = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c->adap);
+- return 0;
+ };
+
+ static const struct of_device_id octeon_i2c_match[] = {
+@@ -270,7 +269,7 @@ MODULE_DEVICE_TABLE(of, octeon_i2c_match);
+
+ static struct platform_driver octeon_i2c_driver = {
+ .probe = octeon_i2c_probe,
+- .remove = octeon_i2c_remove,
++ .remove_new = octeon_i2c_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .of_match_table = octeon_i2c_match,
+diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
+index 4199f57a6bf29..58fd6fa3edf14 100644
+--- a/drivers/i2c/busses/i2c-omap.c
++++ b/drivers/i2c/busses/i2c-omap.c
+@@ -1519,7 +1519,7 @@ omap_i2c_probe(struct platform_device *pdev)
+ return r;
+ }
+
+-static int omap_i2c_remove(struct platform_device *pdev)
++static void omap_i2c_remove(struct platform_device *pdev)
+ {
+ struct omap_i2c_dev *omap = platform_get_drvdata(pdev);
+ int ret;
+@@ -1535,8 +1535,6 @@ static int omap_i2c_remove(struct platform_device *pdev)
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+-
+- return 0;
+ }
+
+ static int __maybe_unused omap_i2c_runtime_suspend(struct device *dev)
+@@ -1588,7 +1586,7 @@ static const struct dev_pm_ops omap_i2c_pm_ops = {
+
+ static struct platform_driver omap_i2c_driver = {
+ .probe = omap_i2c_probe,
+- .remove = omap_i2c_remove,
++ .remove_new = omap_i2c_remove,
+ .driver = {
+ .name = "omap_i2c",
+ .pm = &omap_i2c_pm_ops,
+diff --git a/drivers/i2c/busses/i2c-opal.c b/drivers/i2c/busses/i2c-opal.c
+index 9f773b4f5ed8e..17ef87d50f7c7 100644
+--- a/drivers/i2c/busses/i2c-opal.c
++++ b/drivers/i2c/busses/i2c-opal.c
+@@ -232,13 +232,11 @@ static int i2c_opal_probe(struct platform_device *pdev)
+ return rc;
+ }
+
+-static int i2c_opal_remove(struct platform_device *pdev)
++static void i2c_opal_remove(struct platform_device *pdev)
+ {
+ struct i2c_adapter *adapter = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(adapter);
+-
+- return 0;
+ }
+
+ static const struct of_device_id i2c_opal_of_match[] = {
+@@ -251,7 +249,7 @@ MODULE_DEVICE_TABLE(of, i2c_opal_of_match);
+
+ static struct platform_driver i2c_opal_driver = {
+ .probe = i2c_opal_probe,
+- .remove = i2c_opal_remove,
++ .remove_new = i2c_opal_remove,
+ .driver = {
+ .name = "i2c-opal",
+ .of_match_table = i2c_opal_of_match,
+diff --git a/drivers/i2c/busses/i2c-pasemi-platform.c b/drivers/i2c/busses/i2c-pasemi-platform.c
+index e35945a91dbef..0a44f64897c7a 100644
+--- a/drivers/i2c/busses/i2c-pasemi-platform.c
++++ b/drivers/i2c/busses/i2c-pasemi-platform.c
+@@ -98,12 +98,11 @@ static int pasemi_platform_i2c_probe(struct platform_device *pdev)
+ return error;
+ }
+
+-static int pasemi_platform_i2c_remove(struct platform_device *pdev)
++static void pasemi_platform_i2c_remove(struct platform_device *pdev)
+ {
+ struct pasemi_platform_i2c_data *data = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(data->clk_ref);
+- return 0;
+ }
+
+ static const struct of_device_id pasemi_platform_i2c_of_match[] = {
+@@ -119,7 +118,7 @@ static struct platform_driver pasemi_platform_i2c_driver = {
+ .of_match_table = pasemi_platform_i2c_of_match,
+ },
+ .probe = pasemi_platform_i2c_probe,
+- .remove = pasemi_platform_i2c_remove,
++ .remove_new = pasemi_platform_i2c_remove,
+ };
+ module_platform_driver(pasemi_platform_i2c_driver);
+
+diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c
+index 86d4f75ef8d3f..d2a9e7b61c1ab 100644
+--- a/drivers/i2c/busses/i2c-pca-platform.c
++++ b/drivers/i2c/busses/i2c-pca-platform.c
+@@ -221,13 +221,11 @@ static int i2c_pca_pf_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int i2c_pca_pf_remove(struct platform_device *pdev)
++static void i2c_pca_pf_remove(struct platform_device *pdev)
+ {
+ struct i2c_pca_pf_data *i2c = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c->adap);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_OF
+@@ -241,7 +239,7 @@ MODULE_DEVICE_TABLE(of, i2c_pca_of_match_table);
+
+ static struct platform_driver i2c_pca_pf_driver = {
+ .probe = i2c_pca_pf_probe,
+- .remove = i2c_pca_pf_remove,
++ .remove_new = i2c_pca_pf_remove,
+ .driver = {
+ .name = "i2c-pca-platform",
+ .of_match_table = of_match_ptr(i2c_pca_of_match_table),
+diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
+index 50f21cdbe90d3..82400057f810a 100644
+--- a/drivers/i2c/busses/i2c-pnx.c
++++ b/drivers/i2c/busses/i2c-pnx.c
+@@ -743,14 +743,12 @@ static int i2c_pnx_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int i2c_pnx_remove(struct platform_device *pdev)
++static void i2c_pnx_remove(struct platform_device *pdev)
+ {
+ struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&alg_data->adapter);
+ clk_disable_unprepare(alg_data->clk);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_OF
+@@ -768,7 +766,7 @@ static struct platform_driver i2c_pnx_driver = {
+ .pm = PNX_I2C_PM,
+ },
+ .probe = i2c_pnx_probe,
+- .remove = i2c_pnx_remove,
++ .remove_new = i2c_pnx_remove,
+ };
+
+ static int __init i2c_adap_pnx_init(void)
+diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
+index 2e74747eec9ce..4d9705a0e8e2a 100644
+--- a/drivers/i2c/busses/i2c-powermac.c
++++ b/drivers/i2c/busses/i2c-powermac.c
+@@ -188,14 +188,12 @@ static const struct i2c_adapter_quirks i2c_powermac_quirks = {
+ .max_num_msgs = 1,
+ };
+
+-static int i2c_powermac_remove(struct platform_device *dev)
++static void i2c_powermac_remove(struct platform_device *dev)
+ {
+ struct i2c_adapter *adapter = platform_get_drvdata(dev);
+
+ i2c_del_adapter(adapter);
+ memset(adapter, 0, sizeof(*adapter));
+-
+- return 0;
+ }
+
+ static u32 i2c_powermac_get_addr(struct i2c_adapter *adap,
+@@ -439,7 +437,7 @@ static int i2c_powermac_probe(struct platform_device *dev)
+
+ static struct platform_driver i2c_powermac_driver = {
+ .probe = i2c_powermac_probe,
+- .remove = i2c_powermac_remove,
++ .remove_new = i2c_powermac_remove,
+ .driver = {
+ .name = "i2c-powermac",
+ .bus = &platform_bus_type,
+diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
+index b605b6e43cb90..0d6697e6602ec 100644
+--- a/drivers/i2c/busses/i2c-pxa.c
++++ b/drivers/i2c/busses/i2c-pxa.c
+@@ -1484,15 +1484,13 @@ static int i2c_pxa_probe(struct platform_device *dev)
+ return ret;
+ }
+
+-static int i2c_pxa_remove(struct platform_device *dev)
++static void i2c_pxa_remove(struct platform_device *dev)
+ {
+ struct pxa_i2c *i2c = platform_get_drvdata(dev);
+
+ i2c_del_adapter(&i2c->adap);
+
+ clk_disable_unprepare(i2c->clk);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_PM
+@@ -1527,7 +1525,7 @@ static const struct dev_pm_ops i2c_pxa_dev_pm_ops = {
+
+ static struct platform_driver i2c_pxa_driver = {
+ .probe = i2c_pxa_probe,
+- .remove = i2c_pxa_remove,
++ .remove_new = i2c_pxa_remove,
+ .driver = {
+ .name = "pxa2xx-i2c",
+ .pm = I2C_PXA_DEV_PM_OPS,
+diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c
+index 01358472680c4..58860014e0681 100644
+--- a/drivers/i2c/busses/i2c-qcom-cci.c
++++ b/drivers/i2c/busses/i2c-qcom-cci.c
+@@ -675,7 +675,7 @@ static int cci_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int cci_remove(struct platform_device *pdev)
++static void cci_remove(struct platform_device *pdev)
+ {
+ struct cci *cci = platform_get_drvdata(pdev);
+ int i;
+@@ -691,8 +691,6 @@ static int cci_remove(struct platform_device *pdev)
+ disable_irq(cci->irq);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+-
+- return 0;
+ }
+
+ static const struct cci_data cci_v1_data = {
+@@ -829,7 +827,7 @@ MODULE_DEVICE_TABLE(of, cci_dt_match);
+
+ static struct platform_driver qcom_cci_driver = {
+ .probe = cci_probe,
+- .remove = cci_remove,
++ .remove_new = cci_remove,
+ .driver = {
+ .name = "i2c-qcom-cci",
+ .of_match_table = cci_dt_match,
+diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
+index 83909b02a03ee..b670a67c4fdd0 100644
+--- a/drivers/i2c/busses/i2c-qcom-geni.c
++++ b/drivers/i2c/busses/i2c-qcom-geni.c
+@@ -936,14 +936,13 @@ static int geni_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int geni_i2c_remove(struct platform_device *pdev)
++static void geni_i2c_remove(struct platform_device *pdev)
+ {
+ struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&gi2c->adap);
+ release_gpi_dma(gi2c);
+ pm_runtime_disable(gi2c->se.dev);
+- return 0;
+ }
+
+ static void geni_i2c_shutdown(struct platform_device *pdev)
+@@ -1041,7 +1040,7 @@ MODULE_DEVICE_TABLE(of, geni_i2c_dt_match);
+
+ static struct platform_driver geni_i2c_driver = {
+ .probe = geni_i2c_probe,
+- .remove = geni_i2c_remove,
++ .remove_new = geni_i2c_remove,
+ .shutdown = geni_i2c_shutdown,
+ .driver = {
+ .name = "geni_i2c",
+diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
+index 2e153f2f71b6d..6eef1dbd00de7 100644
+--- a/drivers/i2c/busses/i2c-qup.c
++++ b/drivers/i2c/busses/i2c-qup.c
+@@ -1904,7 +1904,7 @@ static int qup_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int qup_i2c_remove(struct platform_device *pdev)
++static void qup_i2c_remove(struct platform_device *pdev)
+ {
+ struct qup_i2c_dev *qup = platform_get_drvdata(pdev);
+
+@@ -1918,7 +1918,6 @@ static int qup_i2c_remove(struct platform_device *pdev)
+ i2c_del_adapter(&qup->adap);
+ pm_runtime_disable(qup->dev);
+ pm_runtime_set_suspended(qup->dev);
+- return 0;
+ }
+
+ #ifdef CONFIG_PM
+@@ -1978,7 +1977,7 @@ MODULE_DEVICE_TABLE(of, qup_i2c_dt_match);
+
+ static struct platform_driver qup_i2c_driver = {
+ .probe = qup_i2c_probe,
+- .remove = qup_i2c_remove,
++ .remove_new = qup_i2c_remove,
+ .driver = {
+ .name = "i2c_qup",
+ .pm = &qup_i2c_qup_pm_ops,
+diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
+index cef82b205c261..2d9c37410ebd0 100644
+--- a/drivers/i2c/busses/i2c-rcar.c
++++ b/drivers/i2c/busses/i2c-rcar.c
+@@ -1155,7 +1155,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int rcar_i2c_remove(struct platform_device *pdev)
++static void rcar_i2c_remove(struct platform_device *pdev)
+ {
+ struct rcar_i2c_priv *priv = platform_get_drvdata(pdev);
+ struct device *dev = &pdev->dev;
+@@ -1167,8 +1167,6 @@ static int rcar_i2c_remove(struct platform_device *pdev)
+ if (priv->flags & ID_P_PM_BLOCKED)
+ pm_runtime_put(dev);
+ pm_runtime_disable(dev);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_PM_SLEEP
+@@ -1204,7 +1202,7 @@ static struct platform_driver rcar_i2c_driver = {
+ .pm = DEV_PM_OPS,
+ },
+ .probe = rcar_i2c_probe,
+- .remove = rcar_i2c_remove,
++ .remove_new = rcar_i2c_remove,
+ };
+
+ module_platform_driver(rcar_i2c_driver);
+diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c
+index 849848ccb0802..5f8c0bd508d2f 100644
+--- a/drivers/i2c/busses/i2c-riic.c
++++ b/drivers/i2c/busses/i2c-riic.c
+@@ -477,7 +477,7 @@ static int riic_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int riic_i2c_remove(struct platform_device *pdev)
++static void riic_i2c_remove(struct platform_device *pdev)
+ {
+ struct riic_dev *riic = platform_get_drvdata(pdev);
+
+@@ -486,8 +486,6 @@ static int riic_i2c_remove(struct platform_device *pdev)
+ pm_runtime_put(&pdev->dev);
+ i2c_del_adapter(&riic->adapter);
+ pm_runtime_disable(&pdev->dev);
+-
+- return 0;
+ }
+
+ static const struct of_device_id riic_i2c_dt_ids[] = {
+@@ -497,7 +495,7 @@ static const struct of_device_id riic_i2c_dt_ids[] = {
+
+ static struct platform_driver riic_i2c_driver = {
+ .probe = riic_i2c_probe,
+- .remove = riic_i2c_remove,
++ .remove_new = riic_i2c_remove,
+ .driver = {
+ .name = "i2c-riic",
+ .of_match_table = riic_i2c_dt_ids,
+diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
+index b31cf4f18f854..a044ca0c35a19 100644
+--- a/drivers/i2c/busses/i2c-rk3x.c
++++ b/drivers/i2c/busses/i2c-rk3x.c
+@@ -1372,7 +1372,7 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int rk3x_i2c_remove(struct platform_device *pdev)
++static void rk3x_i2c_remove(struct platform_device *pdev)
+ {
+ struct rk3x_i2c *i2c = platform_get_drvdata(pdev);
+
+@@ -1381,15 +1381,13 @@ static int rk3x_i2c_remove(struct platform_device *pdev)
+ clk_notifier_unregister(i2c->clk, &i2c->clk_rate_nb);
+ clk_unprepare(i2c->pclk);
+ clk_unprepare(i2c->clk);
+-
+- return 0;
+ }
+
+ static SIMPLE_DEV_PM_OPS(rk3x_i2c_pm_ops, NULL, rk3x_i2c_resume);
+
+ static struct platform_driver rk3x_i2c_driver = {
+ .probe = rk3x_i2c_probe,
+- .remove = rk3x_i2c_remove,
++ .remove_new = rk3x_i2c_remove,
+ .driver = {
+ .name = "rk3x-i2c",
+ .of_match_table = rk3x_i2c_match,
+diff --git a/drivers/i2c/busses/i2c-rzv2m.c b/drivers/i2c/busses/i2c-rzv2m.c
+index 56d0faee5c46e..dee9b6e655c56 100644
+--- a/drivers/i2c/busses/i2c-rzv2m.c
++++ b/drivers/i2c/busses/i2c-rzv2m.c
+@@ -460,7 +460,7 @@ static int rzv2m_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int rzv2m_i2c_remove(struct platform_device *pdev)
++static void rzv2m_i2c_remove(struct platform_device *pdev)
+ {
+ struct rzv2m_i2c_priv *priv = platform_get_drvdata(pdev);
+ struct device *dev = priv->adap.dev.parent;
+@@ -468,8 +468,6 @@ static int rzv2m_i2c_remove(struct platform_device *pdev)
+ i2c_del_adapter(&priv->adap);
+ bit_clrl(priv->base + IICB0CTL0, IICB0IICE);
+ pm_runtime_disable(dev);
+-
+- return 0;
+ }
+
+ static int rzv2m_i2c_suspend(struct device *dev)
+@@ -523,7 +521,7 @@ static struct platform_driver rzv2m_i2c_driver = {
+ .pm = pm_sleep_ptr(&rzv2m_i2c_pm_ops),
+ },
+ .probe = rzv2m_i2c_probe,
+- .remove = rzv2m_i2c_remove,
++ .remove_new = rzv2m_i2c_remove,
+ };
+ module_platform_driver(rzv2m_i2c_driver);
+
+diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
+index 45e9df81345a1..28f0e5c64f32e 100644
+--- a/drivers/i2c/busses/i2c-s3c2410.c
++++ b/drivers/i2c/busses/i2c-s3c2410.c
+@@ -1114,7 +1114,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int s3c24xx_i2c_remove(struct platform_device *pdev)
++static void s3c24xx_i2c_remove(struct platform_device *pdev)
+ {
+ struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
+
+@@ -1123,8 +1123,6 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
+ pm_runtime_disable(&pdev->dev);
+
+ i2c_del_adapter(&i2c->adap);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_PM_SLEEP
+@@ -1172,7 +1170,7 @@ static const struct dev_pm_ops s3c24xx_i2c_dev_pm_ops = {
+
+ static struct platform_driver s3c24xx_i2c_driver = {
+ .probe = s3c24xx_i2c_probe,
+- .remove = s3c24xx_i2c_remove,
++ .remove_new = s3c24xx_i2c_remove,
+ .id_table = s3c24xx_driver_ids,
+ .driver = {
+ .name = "s3c-i2c",
+diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c
+index 0239e134b90f4..1045702922413 100644
+--- a/drivers/i2c/busses/i2c-scmi.c
++++ b/drivers/i2c/busses/i2c-scmi.c
+@@ -404,19 +404,17 @@ static int smbus_cmi_probe(struct platform_device *device)
+ return ret;
+ }
+
+-static int smbus_cmi_remove(struct platform_device *device)
++static void smbus_cmi_remove(struct platform_device *device)
+ {
+ struct acpi_smbus_cmi *smbus_cmi = platform_get_drvdata(device);
+
+ i2c_del_adapter(&smbus_cmi->adapter);
+ kfree(smbus_cmi);
+-
+- return 0;
+ }
+
+ static struct platform_driver smbus_cmi_driver = {
+ .probe = smbus_cmi_probe,
+- .remove = smbus_cmi_remove,
++ .remove_new = smbus_cmi_remove,
+ .driver = {
+ .name = "smbus_cmi",
+ .acpi_match_table = acpi_smbus_cmi_ids,
+diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c
+index 319d1fa617c88..60efa3a5e6756 100644
+--- a/drivers/i2c/busses/i2c-sh7760.c
++++ b/drivers/i2c/busses/i2c-sh7760.c
+@@ -536,7 +536,7 @@ static int sh7760_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int sh7760_i2c_remove(struct platform_device *pdev)
++static void sh7760_i2c_remove(struct platform_device *pdev)
+ {
+ struct cami2c *id = platform_get_drvdata(pdev);
+
+@@ -546,8 +546,6 @@ static int sh7760_i2c_remove(struct platform_device *pdev)
+ release_resource(id->ioarea);
+ kfree(id->ioarea);
+ kfree(id);
+-
+- return 0;
+ }
+
+ static struct platform_driver sh7760_i2c_drv = {
+@@ -555,7 +553,7 @@ static struct platform_driver sh7760_i2c_drv = {
+ .name = SH7760_I2C_DEVNAME,
+ },
+ .probe = sh7760_i2c_probe,
+- .remove = sh7760_i2c_remove,
++ .remove_new = sh7760_i2c_remove,
+ };
+
+ module_platform_driver(sh7760_i2c_drv);
+diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
+index 29330ee64c9c0..21717b943a9e0 100644
+--- a/drivers/i2c/busses/i2c-sh_mobile.c
++++ b/drivers/i2c/busses/i2c-sh_mobile.c
+@@ -956,14 +956,13 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
+ return 0;
+ }
+
+-static int sh_mobile_i2c_remove(struct platform_device *dev)
++static void sh_mobile_i2c_remove(struct platform_device *dev)
+ {
+ struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
+
+ i2c_del_adapter(&pd->adap);
+ sh_mobile_i2c_release_dma(pd);
+ pm_runtime_disable(&dev->dev);
+- return 0;
+ }
+
+ #ifdef CONFIG_PM_SLEEP
+@@ -1000,7 +999,7 @@ static struct platform_driver sh_mobile_i2c_driver = {
+ .pm = DEV_PM_OPS,
+ },
+ .probe = sh_mobile_i2c_probe,
+- .remove = sh_mobile_i2c_remove,
++ .remove_new = sh_mobile_i2c_remove,
+ };
+
+ static int __init sh_mobile_i2c_adap_init(void)
+diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c
+index 87701744752fb..18516bc64e046 100644
+--- a/drivers/i2c/busses/i2c-simtec.c
++++ b/drivers/i2c/busses/i2c-simtec.c
+@@ -126,7 +126,7 @@ static int simtec_i2c_probe(struct platform_device *dev)
+ return ret;
+ }
+
+-static int simtec_i2c_remove(struct platform_device *dev)
++static void simtec_i2c_remove(struct platform_device *dev)
+ {
+ struct simtec_i2c_data *pd = platform_get_drvdata(dev);
+
+@@ -135,8 +135,6 @@ static int simtec_i2c_remove(struct platform_device *dev)
+ iounmap(pd->reg);
+ release_mem_region(pd->ioarea->start, resource_size(pd->ioarea));
+ kfree(pd);
+-
+- return 0;
+ }
+
+ /* device driver */
+@@ -146,7 +144,7 @@ static struct platform_driver simtec_i2c_driver = {
+ .name = "simtec-i2c",
+ },
+ .probe = simtec_i2c_probe,
+- .remove = simtec_i2c_remove,
++ .remove_new = simtec_i2c_remove,
+ };
+
+ module_platform_driver(simtec_i2c_driver);
+diff --git a/drivers/i2c/busses/i2c-st.c b/drivers/i2c/busses/i2c-st.c
+index f823913b75a6f..25c3521cae0e3 100644
+--- a/drivers/i2c/busses/i2c-st.c
++++ b/drivers/i2c/busses/i2c-st.c
+@@ -876,13 +876,11 @@ static int st_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int st_i2c_remove(struct platform_device *pdev)
++static void st_i2c_remove(struct platform_device *pdev)
+ {
+ struct st_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c_dev->adap);
+-
+- return 0;
+ }
+
+ static const struct of_device_id st_i2c_match[] = {
+@@ -899,7 +897,7 @@ static struct platform_driver st_i2c_driver = {
+ .pm = pm_sleep_ptr(&st_i2c_pm),
+ },
+ .probe = st_i2c_probe,
+- .remove = st_i2c_remove,
++ .remove_new = st_i2c_remove,
+ };
+
+ module_platform_driver(st_i2c_driver);
+diff --git a/drivers/i2c/busses/i2c-stm32f4.c b/drivers/i2c/busses/i2c-stm32f4.c
+index eebce7ecef25b..6ad06a5a22b43 100644
+--- a/drivers/i2c/busses/i2c-stm32f4.c
++++ b/drivers/i2c/busses/i2c-stm32f4.c
+@@ -861,15 +861,13 @@ static int stm32f4_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int stm32f4_i2c_remove(struct platform_device *pdev)
++static void stm32f4_i2c_remove(struct platform_device *pdev)
+ {
+ struct stm32f4_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c_dev->adap);
+
+ clk_unprepare(i2c_dev->clk);
+-
+- return 0;
+ }
+
+ static const struct of_device_id stm32f4_i2c_match[] = {
+@@ -884,7 +882,7 @@ static struct platform_driver stm32f4_i2c_driver = {
+ .of_match_table = stm32f4_i2c_match,
+ },
+ .probe = stm32f4_i2c_probe,
+- .remove = stm32f4_i2c_remove,
++ .remove_new = stm32f4_i2c_remove,
+ };
+
+ module_platform_driver(stm32f4_i2c_driver);
+diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
+index d1c59d83a65b9..e897d9101434d 100644
+--- a/drivers/i2c/busses/i2c-stm32f7.c
++++ b/drivers/i2c/busses/i2c-stm32f7.c
+@@ -2309,7 +2309,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int stm32f7_i2c_remove(struct platform_device *pdev)
++static void stm32f7_i2c_remove(struct platform_device *pdev)
+ {
+ struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+
+@@ -2341,8 +2341,6 @@ static int stm32f7_i2c_remove(struct platform_device *pdev)
+ stm32f7_i2c_write_fm_plus_bits(i2c_dev, false);
+
+ clk_disable_unprepare(i2c_dev->clk);
+-
+- return 0;
+ }
+
+ static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev)
+@@ -2486,7 +2484,7 @@ static struct platform_driver stm32f7_i2c_driver = {
+ .pm = &stm32f7_i2c_pm_ops,
+ },
+ .probe = stm32f7_i2c_probe,
+- .remove = stm32f7_i2c_remove,
++ .remove_new = stm32f7_i2c_remove,
+ };
+
+ module_platform_driver(stm32f7_i2c_driver);
+diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c
+index 9e3483f507ff5..3cff1afe0caa2 100644
+--- a/drivers/i2c/busses/i2c-sun6i-p2wi.c
++++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c
+@@ -313,20 +313,18 @@ static int p2wi_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int p2wi_remove(struct platform_device *dev)
++static void p2wi_remove(struct platform_device *dev)
+ {
+ struct p2wi *p2wi = platform_get_drvdata(dev);
+
+ reset_control_assert(p2wi->rstc);
+ clk_disable_unprepare(p2wi->clk);
+ i2c_del_adapter(&p2wi->adapter);
+-
+- return 0;
+ }
+
+ static struct platform_driver p2wi_driver = {
+ .probe = p2wi_probe,
+- .remove = p2wi_remove,
++ .remove_new = p2wi_remove,
+ .driver = {
+ .name = "i2c-sunxi-p2wi",
+ .of_match_table = p2wi_of_match_table,
+diff --git a/drivers/i2c/busses/i2c-synquacer.c b/drivers/i2c/busses/i2c-synquacer.c
+index e4026c5416b15..1b4ab3b6022b5 100644
+--- a/drivers/i2c/busses/i2c-synquacer.c
++++ b/drivers/i2c/busses/i2c-synquacer.c
+@@ -618,15 +618,13 @@ static int synquacer_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int synquacer_i2c_remove(struct platform_device *pdev)
++static void synquacer_i2c_remove(struct platform_device *pdev)
+ {
+ struct synquacer_i2c *i2c = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c->adapter);
+ if (!IS_ERR(i2c->pclk))
+ clk_disable_unprepare(i2c->pclk);
+-
+- return 0;
+ };
+
+ static const struct of_device_id synquacer_i2c_dt_ids[] = {
+@@ -645,7 +643,7 @@ MODULE_DEVICE_TABLE(acpi, synquacer_i2c_acpi_ids);
+
+ static struct platform_driver synquacer_i2c_driver = {
+ .probe = synquacer_i2c_probe,
+- .remove = synquacer_i2c_remove,
++ .remove_new = synquacer_i2c_remove,
+ .driver = {
+ .name = "synquacer_i2c",
+ .of_match_table = of_match_ptr(synquacer_i2c_dt_ids),
+diff --git a/drivers/i2c/busses/i2c-tegra-bpmp.c b/drivers/i2c/busses/i2c-tegra-bpmp.c
+index 95139985b2d5e..bc3f94561746e 100644
+--- a/drivers/i2c/busses/i2c-tegra-bpmp.c
++++ b/drivers/i2c/busses/i2c-tegra-bpmp.c
+@@ -316,13 +316,11 @@ static int tegra_bpmp_i2c_probe(struct platform_device *pdev)
+ return i2c_add_adapter(&i2c->adapter);
+ }
+
+-static int tegra_bpmp_i2c_remove(struct platform_device *pdev)
++static void tegra_bpmp_i2c_remove(struct platform_device *pdev)
+ {
+ struct tegra_bpmp_i2c *i2c = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c->adapter);
+-
+- return 0;
+ }
+
+ static const struct of_device_id tegra_bpmp_i2c_of_match[] = {
+@@ -337,7 +335,7 @@ static struct platform_driver tegra_bpmp_i2c_driver = {
+ .of_match_table = tegra_bpmp_i2c_of_match,
+ },
+ .probe = tegra_bpmp_i2c_probe,
+- .remove = tegra_bpmp_i2c_remove,
++ .remove_new = tegra_bpmp_i2c_remove,
+ };
+ module_platform_driver(tegra_bpmp_i2c_driver);
+
+diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
+index 157066f06a32d..a82d264bf73df 100644
+--- a/drivers/i2c/busses/i2c-tegra.c
++++ b/drivers/i2c/busses/i2c-tegra.c
+@@ -1868,7 +1868,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
+ return err;
+ }
+
+-static int tegra_i2c_remove(struct platform_device *pdev)
++static void tegra_i2c_remove(struct platform_device *pdev)
+ {
+ struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+
+@@ -1877,8 +1877,6 @@ static int tegra_i2c_remove(struct platform_device *pdev)
+
+ tegra_i2c_release_dma(i2c_dev);
+ tegra_i2c_release_clocks(i2c_dev);
+-
+- return 0;
+ }
+
+ static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
+@@ -1987,7 +1985,7 @@ MODULE_DEVICE_TABLE(acpi, tegra_i2c_acpi_match);
+
+ static struct platform_driver tegra_i2c_driver = {
+ .probe = tegra_i2c_probe,
+- .remove = tegra_i2c_remove,
++ .remove_new = tegra_i2c_remove,
+ .driver = {
+ .name = "tegra-i2c",
+ .of_match_table = tegra_i2c_of_match,
+diff --git a/drivers/i2c/busses/i2c-uniphier-f.c b/drivers/i2c/busses/i2c-uniphier-f.c
+index d7b622891e52d..54b1624ef87ea 100644
+--- a/drivers/i2c/busses/i2c-uniphier-f.c
++++ b/drivers/i2c/busses/i2c-uniphier-f.c
+@@ -586,14 +586,12 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int uniphier_fi2c_remove(struct platform_device *pdev)
++static void uniphier_fi2c_remove(struct platform_device *pdev)
+ {
+ struct uniphier_fi2c_priv *priv = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&priv->adap);
+ clk_disable_unprepare(priv->clk);
+-
+- return 0;
+ }
+
+ static int __maybe_unused uniphier_fi2c_suspend(struct device *dev)
+@@ -631,7 +629,7 @@ MODULE_DEVICE_TABLE(of, uniphier_fi2c_match);
+
+ static struct platform_driver uniphier_fi2c_drv = {
+ .probe = uniphier_fi2c_probe,
+- .remove = uniphier_fi2c_remove,
++ .remove_new = uniphier_fi2c_remove,
+ .driver = {
+ .name = "uniphier-fi2c",
+ .of_match_table = uniphier_fi2c_match,
+diff --git a/drivers/i2c/busses/i2c-uniphier.c b/drivers/i2c/busses/i2c-uniphier.c
+index e3ebae381f08a..96b1eb7489a3c 100644
+--- a/drivers/i2c/busses/i2c-uniphier.c
++++ b/drivers/i2c/busses/i2c-uniphier.c
+@@ -380,14 +380,12 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int uniphier_i2c_remove(struct platform_device *pdev)
++static void uniphier_i2c_remove(struct platform_device *pdev)
+ {
+ struct uniphier_i2c_priv *priv = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&priv->adap);
+ clk_disable_unprepare(priv->clk);
+-
+- return 0;
+ }
+
+ static int __maybe_unused uniphier_i2c_suspend(struct device *dev)
+@@ -425,7 +423,7 @@ MODULE_DEVICE_TABLE(of, uniphier_i2c_match);
+
+ static struct platform_driver uniphier_i2c_drv = {
+ .probe = uniphier_i2c_probe,
+- .remove = uniphier_i2c_remove,
++ .remove_new = uniphier_i2c_remove,
+ .driver = {
+ .name = "uniphier-i2c",
+ .of_match_table = uniphier_i2c_match,
+diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c
+index 1ab419f8fa527..0a866456db586 100644
+--- a/drivers/i2c/busses/i2c-versatile.c
++++ b/drivers/i2c/busses/i2c-versatile.c
+@@ -96,12 +96,11 @@ static int i2c_versatile_probe(struct platform_device *dev)
+ return 0;
+ }
+
+-static int i2c_versatile_remove(struct platform_device *dev)
++static void i2c_versatile_remove(struct platform_device *dev)
+ {
+ struct i2c_versatile *i2c = platform_get_drvdata(dev);
+
+ i2c_del_adapter(&i2c->adap);
+- return 0;
+ }
+
+ static const struct of_device_id i2c_versatile_match[] = {
+@@ -112,7 +111,7 @@ MODULE_DEVICE_TABLE(of, i2c_versatile_match);
+
+ static struct platform_driver i2c_versatile_driver = {
+ .probe = i2c_versatile_probe,
+- .remove = i2c_versatile_remove,
++ .remove_new = i2c_versatile_remove,
+ .driver = {
+ .name = "versatile-i2c",
+ .of_match_table = i2c_versatile_match,
+diff --git a/drivers/i2c/busses/i2c-viperboard.c b/drivers/i2c/busses/i2c-viperboard.c
+index 8b5322c3bce0e..9e153b5b0e8e4 100644
+--- a/drivers/i2c/busses/i2c-viperboard.c
++++ b/drivers/i2c/busses/i2c-viperboard.c
+@@ -407,20 +407,18 @@ static int vprbrd_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int vprbrd_i2c_remove(struct platform_device *pdev)
++static void vprbrd_i2c_remove(struct platform_device *pdev)
+ {
+ struct vprbrd_i2c *vb_i2c = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&vb_i2c->i2c);
+-
+- return 0;
+ }
+
+ static struct platform_driver vprbrd_i2c_driver = {
+ .driver.name = "viperboard-i2c",
+ .driver.owner = THIS_MODULE,
+ .probe = vprbrd_i2c_probe,
+- .remove = vprbrd_i2c_remove,
++ .remove_new = vprbrd_i2c_remove,
+ };
+
+ static int __init vprbrd_i2c_init(void)
+diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c
+index 7d4bc87360793..736acaa538d26 100644
+--- a/drivers/i2c/busses/i2c-wmt.c
++++ b/drivers/i2c/busses/i2c-wmt.c
+@@ -436,7 +436,7 @@ static int wmt_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int wmt_i2c_remove(struct platform_device *pdev)
++static void wmt_i2c_remove(struct platform_device *pdev)
+ {
+ struct wmt_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+
+@@ -444,8 +444,6 @@ static int wmt_i2c_remove(struct platform_device *pdev)
+ writew(0, i2c_dev->base + REG_IMR);
+ clk_disable_unprepare(i2c_dev->clk);
+ i2c_del_adapter(&i2c_dev->adapter);
+-
+- return 0;
+ }
+
+ static const struct of_device_id wmt_i2c_dt_ids[] = {
+@@ -455,7 +453,7 @@ static const struct of_device_id wmt_i2c_dt_ids[] = {
+
+ static struct platform_driver wmt_i2c_driver = {
+ .probe = wmt_i2c_probe,
+- .remove = wmt_i2c_remove,
++ .remove_new = wmt_i2c_remove,
+ .driver = {
+ .name = "wmt-i2c",
+ .of_match_table = wmt_i2c_dt_ids,
+diff --git a/drivers/i2c/busses/i2c-xgene-slimpro.c b/drivers/i2c/busses/i2c-xgene-slimpro.c
+index 3538d36368a90..fbc1ffbd2fa7d 100644
+--- a/drivers/i2c/busses/i2c-xgene-slimpro.c
++++ b/drivers/i2c/busses/i2c-xgene-slimpro.c
+@@ -560,7 +560,7 @@ static int xgene_slimpro_i2c_probe(struct platform_device *pdev)
+ return rc;
+ }
+
+-static int xgene_slimpro_i2c_remove(struct platform_device *pdev)
++static void xgene_slimpro_i2c_remove(struct platform_device *pdev)
+ {
+ struct slimpro_i2c_dev *ctx = platform_get_drvdata(pdev);
+
+@@ -570,8 +570,6 @@ static int xgene_slimpro_i2c_remove(struct platform_device *pdev)
+ mbox_free_channel(ctx->mbox_chan);
+ else
+ pcc_mbox_free_channel(ctx->pcc_chan);
+-
+- return 0;
+ }
+
+ static const struct of_device_id xgene_slimpro_i2c_dt_ids[] = {
+@@ -591,7 +589,7 @@ MODULE_DEVICE_TABLE(acpi, xgene_slimpro_i2c_acpi_ids);
+
+ static struct platform_driver xgene_slimpro_i2c_driver = {
+ .probe = xgene_slimpro_i2c_probe,
+- .remove = xgene_slimpro_i2c_remove,
++ .remove_new = xgene_slimpro_i2c_remove,
+ .driver = {
+ .name = "xgene-slimpro-i2c",
+ .of_match_table = of_match_ptr(xgene_slimpro_i2c_dt_ids),
+diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
+index 3b94b07cb37a6..38b988af4195a 100644
+--- a/drivers/i2c/busses/i2c-xiic.c
++++ b/drivers/i2c/busses/i2c-xiic.c
+@@ -1336,7 +1336,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int xiic_i2c_remove(struct platform_device *pdev)
++static void xiic_i2c_remove(struct platform_device *pdev)
+ {
+ struct xiic_i2c *i2c = platform_get_drvdata(pdev);
+ int ret;
+@@ -1357,8 +1357,6 @@ static int xiic_i2c_remove(struct platform_device *pdev)
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+-
+- return 0;
+ }
+
+ static int __maybe_unused xiic_i2c_runtime_suspend(struct device *dev)
+@@ -1391,7 +1389,7 @@ static const struct dev_pm_ops xiic_dev_pm_ops = {
+
+ static struct platform_driver xiic_i2c_driver = {
+ .probe = xiic_i2c_probe,
+- .remove = xiic_i2c_remove,
++ .remove_new = xiic_i2c_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = of_match_ptr(xiic_of_match),
+diff --git a/drivers/i2c/busses/i2c-xlp9xx.c b/drivers/i2c/busses/i2c-xlp9xx.c
+index 4e3b11c0f7325..f59e8c544f366 100644
+--- a/drivers/i2c/busses/i2c-xlp9xx.c
++++ b/drivers/i2c/busses/i2c-xlp9xx.c
+@@ -559,7 +559,7 @@ static int xlp9xx_i2c_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int xlp9xx_i2c_remove(struct platform_device *pdev)
++static void xlp9xx_i2c_remove(struct platform_device *pdev)
+ {
+ struct xlp9xx_i2c_dev *priv;
+
+@@ -568,8 +568,6 @@ static int xlp9xx_i2c_remove(struct platform_device *pdev)
+ synchronize_irq(priv->irq);
+ i2c_del_adapter(&priv->adapter);
+ xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, 0);
+-
+- return 0;
+ }
+
+ #ifdef CONFIG_ACPI
+@@ -583,7 +581,7 @@ MODULE_DEVICE_TABLE(acpi, xlp9xx_i2c_acpi_ids);
+
+ static struct platform_driver xlp9xx_i2c_driver = {
+ .probe = xlp9xx_i2c_probe,
+- .remove = xlp9xx_i2c_remove,
++ .remove_new = xlp9xx_i2c_remove,
+ .driver = {
+ .name = "xlp9xx-i2c",
+ .acpi_match_table = ACPI_PTR(xlp9xx_i2c_acpi_ids),
+diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
+index 7b42a18bd05c2..83c1db610f54b 100644
+--- a/drivers/i2c/busses/scx200_acb.c
++++ b/drivers/i2c/busses/scx200_acb.c
+@@ -523,14 +523,12 @@ static void scx200_cleanup_iface(struct scx200_acb_iface *iface)
+ kfree(iface);
+ }
+
+-static int scx200_remove(struct platform_device *pdev)
++static void scx200_remove(struct platform_device *pdev)
+ {
+ struct scx200_acb_iface *iface;
+
+ iface = platform_get_drvdata(pdev);
+ scx200_cleanup_iface(iface);
+-
+- return 0;
+ }
+
+ static struct platform_driver scx200_pci_driver = {
+@@ -538,7 +536,7 @@ static struct platform_driver scx200_pci_driver = {
+ .name = "cs5535-smb",
+ },
+ .probe = scx200_probe,
+- .remove = scx200_remove,
++ .remove_new = scx200_remove,
+ };
+
+ static const struct pci_device_id scx200_isa[] = {
+diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
+index 1c78657631f4f..24168e9f7df4c 100644
+--- a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
++++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
+@@ -174,13 +174,12 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int i2c_arbitrator_remove(struct platform_device *pdev)
++static void i2c_arbitrator_remove(struct platform_device *pdev)
+ {
+ struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
+
+ i2c_mux_del_adapters(muxc);
+ i2c_put_adapter(muxc->parent);
+- return 0;
+ }
+
+ static const struct of_device_id i2c_arbitrator_of_match[] = {
+@@ -191,7 +190,7 @@ MODULE_DEVICE_TABLE(of, i2c_arbitrator_of_match);
+
+ static struct platform_driver i2c_arbitrator_driver = {
+ .probe = i2c_arbitrator_probe,
+- .remove = i2c_arbitrator_remove,
++ .remove_new = i2c_arbitrator_remove,
+ .driver = {
+ .name = "i2c-arb-gpio-challenge",
+ .of_match_table = i2c_arbitrator_of_match,
+diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c
+index f7a7405d4350a..a3a122fae71e0 100644
+--- a/drivers/i2c/muxes/i2c-demux-pinctrl.c
++++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c
+@@ -282,7 +282,7 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
+ return err;
+ }
+
+-static int i2c_demux_pinctrl_remove(struct platform_device *pdev)
++static void i2c_demux_pinctrl_remove(struct platform_device *pdev)
+ {
+ struct i2c_demux_pinctrl_priv *priv = platform_get_drvdata(pdev);
+ int i;
+@@ -296,8 +296,6 @@ static int i2c_demux_pinctrl_remove(struct platform_device *pdev)
+ of_node_put(priv->chan[i].parent_np);
+ of_changeset_destroy(&priv->chan[i].chgset);
+ }
+-
+- return 0;
+ }
+
+ static const struct of_device_id i2c_demux_pinctrl_of_match[] = {
+@@ -312,7 +310,7 @@ static struct platform_driver i2c_demux_pinctrl_driver = {
+ .of_match_table = i2c_demux_pinctrl_of_match,
+ },
+ .probe = i2c_demux_pinctrl_probe,
+- .remove = i2c_demux_pinctrl_remove,
++ .remove_new = i2c_demux_pinctrl_remove,
+ };
+ module_platform_driver(i2c_demux_pinctrl_driver);
+
+diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
+index 73a23e117ebec..5d5cbe0130cdf 100644
+--- a/drivers/i2c/muxes/i2c-mux-gpio.c
++++ b/drivers/i2c/muxes/i2c-mux-gpio.c
+@@ -225,14 +225,12 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int i2c_mux_gpio_remove(struct platform_device *pdev)
++static void i2c_mux_gpio_remove(struct platform_device *pdev)
+ {
+ struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
+
+ i2c_mux_del_adapters(muxc);
+ i2c_put_adapter(muxc->parent);
+-
+- return 0;
+ }
+
+ static const struct of_device_id i2c_mux_gpio_of_match[] = {
+@@ -243,7 +241,7 @@ MODULE_DEVICE_TABLE(of, i2c_mux_gpio_of_match);
+
+ static struct platform_driver i2c_mux_gpio_driver = {
+ .probe = i2c_mux_gpio_probe,
+- .remove = i2c_mux_gpio_remove,
++ .remove_new = i2c_mux_gpio_remove,
+ .driver = {
+ .name = "i2c-mux-gpio",
+ .of_match_table = i2c_mux_gpio_of_match,
+diff --git a/drivers/i2c/muxes/i2c-mux-gpmux.c b/drivers/i2c/muxes/i2c-mux-gpmux.c
+index 33024acaac02b..0405af0e15104 100644
+--- a/drivers/i2c/muxes/i2c-mux-gpmux.c
++++ b/drivers/i2c/muxes/i2c-mux-gpmux.c
+@@ -142,19 +142,17 @@ static int i2c_mux_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int i2c_mux_remove(struct platform_device *pdev)
++static void i2c_mux_remove(struct platform_device *pdev)
+ {
+ struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
+
+ i2c_mux_del_adapters(muxc);
+ i2c_put_adapter(muxc->parent);
+-
+- return 0;
+ }
+
+ static struct platform_driver i2c_mux_driver = {
+ .probe = i2c_mux_probe,
+- .remove = i2c_mux_remove,
++ .remove_new = i2c_mux_remove,
+ .driver = {
+ .name = "i2c-mux-gpmux",
+ .of_match_table = i2c_mux_of_match,
+diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c
+index 1a879f6a31efd..3dda00f1df78d 100644
+--- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c
++++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c
+@@ -170,12 +170,11 @@ static int mlxcpld_mux_probe(struct platform_device *pdev)
+ return err;
+ }
+
+-static int mlxcpld_mux_remove(struct platform_device *pdev)
++static void mlxcpld_mux_remove(struct platform_device *pdev)
+ {
+ struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
+
+ i2c_mux_del_adapters(muxc);
+- return 0;
+ }
+
+ static struct platform_driver mlxcpld_mux_driver = {
+@@ -183,7 +182,7 @@ static struct platform_driver mlxcpld_mux_driver = {
+ .name = "i2c-mux-mlxcpld",
+ },
+ .probe = mlxcpld_mux_probe,
+- .remove = mlxcpld_mux_remove,
++ .remove_new = mlxcpld_mux_remove,
+ };
+
+ module_platform_driver(mlxcpld_mux_driver);
+diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c
+index d5ad904756fdf..18236b9fa14a9 100644
+--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
++++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
+@@ -166,14 +166,12 @@ static int i2c_mux_pinctrl_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int i2c_mux_pinctrl_remove(struct platform_device *pdev)
++static void i2c_mux_pinctrl_remove(struct platform_device *pdev)
+ {
+ struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
+
+ i2c_mux_del_adapters(muxc);
+ i2c_put_adapter(muxc->parent);
+-
+- return 0;
+ }
+
+ static const struct of_device_id i2c_mux_pinctrl_of_match[] = {
+@@ -188,7 +186,7 @@ static struct platform_driver i2c_mux_pinctrl_driver = {
+ .of_match_table = i2c_mux_pinctrl_of_match,
+ },
+ .probe = i2c_mux_pinctrl_probe,
+- .remove = i2c_mux_pinctrl_remove,
++ .remove_new = i2c_mux_pinctrl_remove,
+ };
+ module_platform_driver(i2c_mux_pinctrl_driver);
+
+diff --git a/drivers/i2c/muxes/i2c-mux-reg.c b/drivers/i2c/muxes/i2c-mux-reg.c
+index 30a6de1694e07..9efc1ed01577b 100644
+--- a/drivers/i2c/muxes/i2c-mux-reg.c
++++ b/drivers/i2c/muxes/i2c-mux-reg.c
+@@ -233,14 +233,12 @@ static int i2c_mux_reg_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+-static int i2c_mux_reg_remove(struct platform_device *pdev)
++static void i2c_mux_reg_remove(struct platform_device *pdev)
+ {
+ struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
+
+ i2c_mux_del_adapters(muxc);
+ i2c_put_adapter(muxc->parent);
+-
+- return 0;
+ }
+
+ static const struct of_device_id i2c_mux_reg_of_match[] = {
+@@ -251,7 +249,7 @@ MODULE_DEVICE_TABLE(of, i2c_mux_reg_of_match);
+
+ static struct platform_driver i2c_mux_reg_driver = {
+ .probe = i2c_mux_reg_probe,
+- .remove = i2c_mux_reg_remove,
++ .remove_new = i2c_mux_reg_remove,
+ .driver = {
+ .name = "i2c-mux-reg",
+ .of_match_table = of_match_ptr(i2c_mux_reg_of_match),
+--
+2.39.2
+
--- /dev/null
+From 2faeb111e6b39e0a477ee6537a8c8b8e8b3b68cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 May 2023 15:05:33 +0800
+Subject: i2c: ocores: use devm_ managed clks
+
+From: Wang Zhang <silver_code@hust.edu.cn>
+
+[ Upstream commit 9e1a1ee93f6b08aad5ee645073f7c7b115f71e15 ]
+
+Smatch complains that:
+drivers/i2c/busses/i2c-ocores.c:704 ocores_i2c_probe()
+warn: missing unwind goto?
+
+If any wrong occurs in ocores_i2c_of_probe, the i2c->clk needs to be
+released. But the function returns directly without freeing the clock.
+
+Fix this by updating the code to use devm_clk_get_optional_enabled()
+instead. Use dev_err_probe() where appropriate as well since we are
+changing those statements.
+
+Fixes: f5f35a92e44a ("i2c: ocores: Add irq support for sparc")
+Signed-off-by: Wang Zhang <silver_code@hust.edu.cn>
+Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-ocores.c | 64 +++++++++++----------------------
+ 1 file changed, 21 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
+index 0742b84a11eb5..4ac77e57bbbfe 100644
+--- a/drivers/i2c/busses/i2c-ocores.c
++++ b/drivers/i2c/busses/i2c-ocores.c
+@@ -552,28 +552,20 @@ static int ocores_i2c_of_probe(struct platform_device *pdev,
+ &clock_frequency);
+ i2c->bus_clock_khz = 100;
+
+- i2c->clk = devm_clk_get(&pdev->dev, NULL);
+-
+- if (!IS_ERR(i2c->clk)) {
+- int ret = clk_prepare_enable(i2c->clk);
+-
+- if (ret) {
+- dev_err(&pdev->dev,
+- "clk_prepare_enable failed: %d\n", ret);
+- return ret;
+- }
+- i2c->ip_clock_khz = clk_get_rate(i2c->clk) / 1000;
+- if (clock_frequency_present)
+- i2c->bus_clock_khz = clock_frequency / 1000;
+- }
+-
++ i2c->clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
++ if (IS_ERR(i2c->clk))
++ return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk),
++ "devm_clk_get_optional_enabled failed\n");
++
++ i2c->ip_clock_khz = clk_get_rate(i2c->clk) / 1000;
++ if (clock_frequency_present)
++ i2c->bus_clock_khz = clock_frequency / 1000;
+ if (i2c->ip_clock_khz == 0) {
+ if (of_property_read_u32(np, "opencores,ip-clock-frequency",
+ &val)) {
+ if (!clock_frequency_present) {
+ dev_err(&pdev->dev,
+ "Missing required parameter 'opencores,ip-clock-frequency'\n");
+- clk_disable_unprepare(i2c->clk);
+ return -ENODEV;
+ }
+ i2c->ip_clock_khz = clock_frequency / 1000;
+@@ -678,8 +670,7 @@ static int ocores_i2c_probe(struct platform_device *pdev)
+ default:
+ dev_err(&pdev->dev, "Unsupported I/O width (%d)\n",
+ i2c->reg_io_width);
+- ret = -EINVAL;
+- goto err_clk;
++ return -EINVAL;
+ }
+ }
+
+@@ -710,13 +701,13 @@ static int ocores_i2c_probe(struct platform_device *pdev)
+ pdev->name, i2c);
+ if (ret) {
+ dev_err(&pdev->dev, "Cannot claim IRQ\n");
+- goto err_clk;
++ return ret;
+ }
+ }
+
+ ret = ocores_init(&pdev->dev, i2c);
+ if (ret)
+- goto err_clk;
++ return ret;
+
+ /* hook up driver to tree */
+ platform_set_drvdata(pdev, i2c);
+@@ -728,7 +719,7 @@ static int ocores_i2c_probe(struct platform_device *pdev)
+ /* add i2c adapter to i2c tree */
+ ret = i2c_add_adapter(&i2c->adap);
+ if (ret)
+- goto err_clk;
++ return ret;
+
+ /* add in known devices to the bus */
+ if (pdata) {
+@@ -737,10 +728,6 @@ static int ocores_i2c_probe(struct platform_device *pdev)
+ }
+
+ return 0;
+-
+-err_clk:
+- clk_disable_unprepare(i2c->clk);
+- return ret;
+ }
+
+ static void ocores_i2c_remove(struct platform_device *pdev)
+@@ -754,9 +741,6 @@ static void ocores_i2c_remove(struct platform_device *pdev)
+
+ /* remove adapter & data */
+ i2c_del_adapter(&i2c->adap);
+-
+- if (!IS_ERR(i2c->clk))
+- clk_disable_unprepare(i2c->clk);
+ }
+
+ #ifdef CONFIG_PM_SLEEP
+@@ -769,28 +753,22 @@ static int ocores_i2c_suspend(struct device *dev)
+ ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN);
+ oc_setreg(i2c, OCI2C_CONTROL, ctrl);
+
+- if (!IS_ERR(i2c->clk))
+- clk_disable_unprepare(i2c->clk);
++ clk_disable_unprepare(i2c->clk);
+ return 0;
+ }
+
+ static int ocores_i2c_resume(struct device *dev)
+ {
+ struct ocores_i2c *i2c = dev_get_drvdata(dev);
++ unsigned long rate;
++ int ret;
+
+- if (!IS_ERR(i2c->clk)) {
+- unsigned long rate;
+- int ret = clk_prepare_enable(i2c->clk);
+-
+- if (ret) {
+- dev_err(dev,
+- "clk_prepare_enable failed: %d\n", ret);
+- return ret;
+- }
+- rate = clk_get_rate(i2c->clk) / 1000;
+- if (rate)
+- i2c->ip_clock_khz = rate;
+- }
++ ret = clk_prepare_enable(i2c->clk);
++ if (ret)
++ return dev_err_probe(dev, ret, "clk_prepare_enable failed\n");
++ rate = clk_get_rate(i2c->clk) / 1000;
++ if (rate)
++ i2c->ip_clock_khz = rate;
+ return ocores_init(dev, i2c);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 6155933f8f46712f12e9c630e6cc667961d14225 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 10:23:54 +0200
+Subject: i2c: omap: Improve error reporting for problems during .remove()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 9496fffcb28f39e0352779a0199b6e61861c9221 ]
+
+If pm_runtime_get() fails in .remove() the driver used to return the
+error to the driver core. The only effect of this (compared to returning
+zero) is a generic warning that the error value is ignored.
+
+So emit a better warning and return zero to suppress the generic (and
+little helpful) message. Also disable runtime PM in the error case.
+
+This prepares changing platform device remove callbacks to return void.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 9e1a1ee93f6b ("i2c: ocores: use devm_ managed clks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-omap.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
+index 7ec2521997061..4199f57a6bf29 100644
+--- a/drivers/i2c/busses/i2c-omap.c
++++ b/drivers/i2c/busses/i2c-omap.c
+@@ -1525,14 +1525,17 @@ static int omap_i2c_remove(struct platform_device *pdev)
+ int ret;
+
+ i2c_del_adapter(&omap->adapter);
+- ret = pm_runtime_resume_and_get(&pdev->dev);
++
++ ret = pm_runtime_get_sync(&pdev->dev);
+ if (ret < 0)
+- return ret;
++ dev_err(omap->dev, "Failed to resume hardware, skip disable\n");
++ else
++ omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, 0);
+
+- omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, 0);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
++
+ return 0;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From e27cce818b9cc004cab00aae9988e0883ae51006 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 May 2023 12:32:16 -0400
+Subject: IB/hfi1: Fix wrong mmu_node used for user SDMA packet after
+ invalidate
+
+From: Brendan Cunningham <bcunningham@cornelisnetworks.com>
+
+[ Upstream commit c9358de193ecfb360c3ce75f27ce839ca0b0bc8c ]
+
+The hfi1 user SDMA pinned-page cache will leave a stale cache entry when
+the cache-entry's virtual address range is invalidated but that cache
+entry is in-use by an outstanding SDMA request.
+
+Subsequent user SDMA requests with buffers in or spanning the virtual
+address range of the stale cache entry will result in packets constructed
+from the wrong memory, the physical pages pointed to by the stale cache
+entry.
+
+To fix this, remove mmu_rb_node cache entries from the mmu_rb_handler
+cache independent of the cache entry's refcount. Add 'struct kref
+refcount' to struct mmu_rb_node and manage mmu_rb_node lifetime with
+kref_get() and kref_put().
+
+mmu_rb_node.refcount makes sdma_mmu_node.refcount redundant. Remove
+'atomic_t refcount' from struct sdma_mmu_node and change sdma_mmu_node
+code to use mmu_rb_node.refcount.
+
+Move the mmu_rb_handler destructor call after a
+wait-for-SDMA-request-completion call so mmu_rb_nodes that need
+mmu_rb_handler's workqueue to queue themselves up for destruction from an
+interrupt context may do so.
+
+Fixes: f48ad614c100 ("IB/hfi1: Move driver out of staging")
+Fixes: 00cbce5cbf88 ("IB/hfi1: Fix bugs with non-PAGE_SIZE-end multi-iovec user SDMA requests")
+Link: https://lore.kernel.org/r/168451393605.3700681.13493776139032178861.stgit@awfm-02.cornelisnetworks.com
+Reviewed-by: Dean Luick <dean.luick@cornelisnetworks.com>
+Signed-off-by: Brendan Cunningham <bcunningham@cornelisnetworks.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/ipoib_tx.c | 4 +-
+ drivers/infiniband/hw/hfi1/mmu_rb.c | 101 ++++++++++-------
+ drivers/infiniband/hw/hfi1/mmu_rb.h | 3 +
+ drivers/infiniband/hw/hfi1/sdma.c | 23 +++-
+ drivers/infiniband/hw/hfi1/sdma.h | 47 +++++---
+ drivers/infiniband/hw/hfi1/sdma_txreq.h | 2 +
+ drivers/infiniband/hw/hfi1/user_sdma.c | 137 ++++++++++--------------
+ drivers/infiniband/hw/hfi1/user_sdma.h | 1 -
+ drivers/infiniband/hw/hfi1/vnic_sdma.c | 4 +-
+ 9 files changed, 177 insertions(+), 145 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hfi1/ipoib_tx.c b/drivers/infiniband/hw/hfi1/ipoib_tx.c
+index 8973a081d641e..e7d831330278d 100644
+--- a/drivers/infiniband/hw/hfi1/ipoib_tx.c
++++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c
+@@ -215,11 +215,11 @@ static int hfi1_ipoib_build_ulp_payload(struct ipoib_txreq *tx,
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ ret = sdma_txadd_page(dd,
+- NULL,
+ txreq,
+ skb_frag_page(frag),
+ frag->bv_offset,
+- skb_frag_size(frag));
++ skb_frag_size(frag),
++ NULL, NULL, NULL);
+ if (unlikely(ret))
+ break;
+ }
+diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c
+index 71b9ac0188875..94f1701667301 100644
+--- a/drivers/infiniband/hw/hfi1/mmu_rb.c
++++ b/drivers/infiniband/hw/hfi1/mmu_rb.c
+@@ -19,8 +19,7 @@ static int mmu_notifier_range_start(struct mmu_notifier *,
+ const struct mmu_notifier_range *);
+ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *,
+ unsigned long, unsigned long);
+-static void do_remove(struct mmu_rb_handler *handler,
+- struct list_head *del_list);
++static void release_immediate(struct kref *refcount);
+ static void handle_remove(struct work_struct *work);
+
+ static const struct mmu_notifier_ops mn_opts = {
+@@ -103,7 +102,11 @@ void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler)
+ }
+ spin_unlock_irqrestore(&handler->lock, flags);
+
+- do_remove(handler, &del_list);
++ while (!list_empty(&del_list)) {
++ rbnode = list_first_entry(&del_list, struct mmu_rb_node, list);
++ list_del(&rbnode->list);
++ kref_put(&rbnode->refcount, release_immediate);
++ }
+
+ /* Now the mm may be freed. */
+ mmdrop(handler->mn.mm);
+@@ -131,12 +134,6 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler,
+ }
+ __mmu_int_rb_insert(mnode, &handler->root);
+ list_add_tail(&mnode->list, &handler->lru_list);
+-
+- ret = handler->ops->insert(handler->ops_arg, mnode);
+- if (ret) {
+- __mmu_int_rb_remove(mnode, &handler->root);
+- list_del(&mnode->list); /* remove from LRU list */
+- }
+ mnode->handler = handler;
+ unlock:
+ spin_unlock_irqrestore(&handler->lock, flags);
+@@ -180,6 +177,48 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler,
+ return node;
+ }
+
++/*
++ * Must NOT call while holding mnode->handler->lock.
++ * mnode->handler->ops->remove() may sleep and mnode->handler->lock is a
++ * spinlock.
++ */
++static void release_immediate(struct kref *refcount)
++{
++ struct mmu_rb_node *mnode =
++ container_of(refcount, struct mmu_rb_node, refcount);
++ mnode->handler->ops->remove(mnode->handler->ops_arg, mnode);
++}
++
++/* Caller must hold mnode->handler->lock */
++static void release_nolock(struct kref *refcount)
++{
++ struct mmu_rb_node *mnode =
++ container_of(refcount, struct mmu_rb_node, refcount);
++ list_move(&mnode->list, &mnode->handler->del_list);
++ queue_work(mnode->handler->wq, &mnode->handler->del_work);
++}
++
++/*
++ * struct mmu_rb_node->refcount kref_put() callback.
++ * Adds mmu_rb_node to mmu_rb_node->handler->del_list and queues
++ * handler->del_work on handler->wq.
++ * Does not remove mmu_rb_node from handler->lru_list or handler->rb_root.
++ * Acquires mmu_rb_node->handler->lock; do not call while already holding
++ * handler->lock.
++ */
++void hfi1_mmu_rb_release(struct kref *refcount)
++{
++ struct mmu_rb_node *mnode =
++ container_of(refcount, struct mmu_rb_node, refcount);
++ struct mmu_rb_handler *handler = mnode->handler;
++ unsigned long flags;
++
++ spin_lock_irqsave(&handler->lock, flags);
++ list_move(&mnode->list, &mnode->handler->del_list);
++ spin_unlock_irqrestore(&handler->lock, flags);
++ queue_work(handler->wq, &handler->del_work);
++}
++
+ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg)
+ {
+ struct mmu_rb_node *rbnode, *ptr;
+@@ -194,6 +233,10 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg)
+
+ spin_lock_irqsave(&handler->lock, flags);
+ list_for_each_entry_safe(rbnode, ptr, &handler->lru_list, list) {
++ /* refcount == 1 implies mmu_rb_handler has only rbnode ref */
++ if (kref_read(&rbnode->refcount) > 1)
++ continue;
++
+ if (handler->ops->evict(handler->ops_arg, rbnode, evict_arg,
+ &stop)) {
+ __mmu_int_rb_remove(rbnode, &handler->root);
+@@ -206,7 +249,7 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg)
+ spin_unlock_irqrestore(&handler->lock, flags);
+
+ list_for_each_entry_safe(rbnode, ptr, &del_list, list) {
+- handler->ops->remove(handler->ops_arg, rbnode);
++ kref_put(&rbnode->refcount, release_immediate);
+ }
+ }
+
+@@ -218,7 +261,6 @@ static int mmu_notifier_range_start(struct mmu_notifier *mn,
+ struct rb_root_cached *root = &handler->root;
+ struct mmu_rb_node *node, *ptr = NULL;
+ unsigned long flags;
+- bool added = false;
+
+ spin_lock_irqsave(&handler->lock, flags);
+ for (node = __mmu_int_rb_iter_first(root, range->start, range->end-1);
+@@ -227,38 +269,16 @@ static int mmu_notifier_range_start(struct mmu_notifier *mn,
+ ptr = __mmu_int_rb_iter_next(node, range->start,
+ range->end - 1);
+ trace_hfi1_mmu_mem_invalidate(node->addr, node->len);
+- if (handler->ops->invalidate(handler->ops_arg, node)) {
+- __mmu_int_rb_remove(node, root);
+- /* move from LRU list to delete list */
+- list_move(&node->list, &handler->del_list);
+- added = true;
+- }
++ /* Remove from rb tree and lru_list. */
++ __mmu_int_rb_remove(node, root);
++ list_del_init(&node->list);
++ kref_put(&node->refcount, release_nolock);
+ }
+ spin_unlock_irqrestore(&handler->lock, flags);
+
+- if (added)
+- queue_work(handler->wq, &handler->del_work);
+-
+ return 0;
+ }
+
+-/*
+- * Call the remove function for the given handler and the list. This
+- * is expected to be called with a delete list extracted from handler.
+- * The caller should not be holding the handler lock.
+- */
+-static void do_remove(struct mmu_rb_handler *handler,
+- struct list_head *del_list)
+-{
+- struct mmu_rb_node *node;
+-
+- while (!list_empty(del_list)) {
+- node = list_first_entry(del_list, struct mmu_rb_node, list);
+- list_del(&node->list);
+- handler->ops->remove(handler->ops_arg, node);
+- }
+-}
+-
+ /*
+ * Work queue function to remove all nodes that have been queued up to
+ * be removed. The key feature is that mm->mmap_lock is not being held
+@@ -271,11 +291,16 @@ static void handle_remove(struct work_struct *work)
+ del_work);
+ struct list_head del_list;
+ unsigned long flags;
++ struct mmu_rb_node *node;
+
+ /* remove anything that is queued to get removed */
+ spin_lock_irqsave(&handler->lock, flags);
+ list_replace_init(&handler->del_list, &del_list);
+ spin_unlock_irqrestore(&handler->lock, flags);
+
+- do_remove(handler, &del_list);
++ while (!list_empty(&del_list)) {
++ node = list_first_entry(&del_list, struct mmu_rb_node, list);
++ list_del(&node->list);
++ handler->ops->remove(handler->ops_arg, node);
++ }
+ }
+diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.h b/drivers/infiniband/hw/hfi1/mmu_rb.h
+index ed75acdb7b839..dd2c4a0ae95b1 100644
+--- a/drivers/infiniband/hw/hfi1/mmu_rb.h
++++ b/drivers/infiniband/hw/hfi1/mmu_rb.h
+@@ -16,6 +16,7 @@ struct mmu_rb_node {
+ struct rb_node node;
+ struct mmu_rb_handler *handler;
+ struct list_head list;
++ struct kref refcount;
+ };
+
+ /*
+@@ -51,6 +52,8 @@ int hfi1_mmu_rb_register(void *ops_arg,
+ void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler);
+ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler,
+ struct mmu_rb_node *mnode);
++void hfi1_mmu_rb_release(struct kref *refcount);
++
+ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg);
+ struct mmu_rb_node *hfi1_mmu_rb_get_first(struct mmu_rb_handler *handler,
+ unsigned long addr,
+diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c
+index bb2552dd29c1e..26c62162759ba 100644
+--- a/drivers/infiniband/hw/hfi1/sdma.c
++++ b/drivers/infiniband/hw/hfi1/sdma.c
+@@ -1593,7 +1593,20 @@ static inline void sdma_unmap_desc(
+ struct hfi1_devdata *dd,
+ struct sdma_desc *descp)
+ {
+- system_descriptor_complete(dd, descp);
++ switch (sdma_mapping_type(descp)) {
++ case SDMA_MAP_SINGLE:
++ dma_unmap_single(&dd->pcidev->dev, sdma_mapping_addr(descp),
++ sdma_mapping_len(descp), DMA_TO_DEVICE);
++ break;
++ case SDMA_MAP_PAGE:
++ dma_unmap_page(&dd->pcidev->dev, sdma_mapping_addr(descp),
++ sdma_mapping_len(descp), DMA_TO_DEVICE);
++ break;
++ }
++
++ if (descp->pinning_ctx && descp->ctx_put)
++ descp->ctx_put(descp->pinning_ctx);
++ descp->pinning_ctx = NULL;
+ }
+
+ /*
+@@ -3113,8 +3126,8 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
+
+ /* Add descriptor for coalesce buffer */
+ tx->desc_limit = MAX_DESC;
+- return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, NULL, tx,
+- addr, tx->tlen);
++ return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx,
++ addr, tx->tlen, NULL, NULL, NULL);
+ }
+
+ return 1;
+@@ -3157,9 +3170,9 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx)
+ make_tx_sdma_desc(
+ tx,
+ SDMA_MAP_NONE,
+- NULL,
+ dd->sdma_pad_phys,
+- sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1)));
++ sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1)),
++ NULL, NULL, NULL);
+ tx->num_desc++;
+ _sdma_close_tx(dd, tx);
+ return rval;
+diff --git a/drivers/infiniband/hw/hfi1/sdma.h b/drivers/infiniband/hw/hfi1/sdma.h
+index 95aaec14c6c28..7fdebab202c4f 100644
+--- a/drivers/infiniband/hw/hfi1/sdma.h
++++ b/drivers/infiniband/hw/hfi1/sdma.h
+@@ -594,9 +594,11 @@ static inline dma_addr_t sdma_mapping_addr(struct sdma_desc *d)
+ static inline void make_tx_sdma_desc(
+ struct sdma_txreq *tx,
+ int type,
+- void *pinning_ctx,
+ dma_addr_t addr,
+- size_t len)
++ size_t len,
++ void *pinning_ctx,
++ void (*ctx_get)(void *),
++ void (*ctx_put)(void *))
+ {
+ struct sdma_desc *desc = &tx->descp[tx->num_desc];
+
+@@ -613,7 +615,11 @@ static inline void make_tx_sdma_desc(
+ << SDMA_DESC0_PHY_ADDR_SHIFT) |
+ (((u64)len & SDMA_DESC0_BYTE_COUNT_MASK)
+ << SDMA_DESC0_BYTE_COUNT_SHIFT);
++
+ desc->pinning_ctx = pinning_ctx;
++ desc->ctx_put = ctx_put;
++ if (pinning_ctx && ctx_get)
++ ctx_get(pinning_ctx);
+ }
+
+ /* helper to extend txreq */
+@@ -645,18 +651,20 @@ static inline void _sdma_close_tx(struct hfi1_devdata *dd,
+ static inline int _sdma_txadd_daddr(
+ struct hfi1_devdata *dd,
+ int type,
+- void *pinning_ctx,
+ struct sdma_txreq *tx,
+ dma_addr_t addr,
+- u16 len)
++ u16 len,
++ void *pinning_ctx,
++ void (*ctx_get)(void *),
++ void (*ctx_put)(void *))
+ {
+ int rval = 0;
+
+ make_tx_sdma_desc(
+ tx,
+ type,
+- pinning_ctx,
+- addr, len);
++ addr, len,
++ pinning_ctx, ctx_get, ctx_put);
+ WARN_ON(len > tx->tlen);
+ tx->num_desc++;
+ tx->tlen -= len;
+@@ -676,11 +684,18 @@ static inline int _sdma_txadd_daddr(
+ /**
+ * sdma_txadd_page() - add a page to the sdma_txreq
+ * @dd: the device to use for mapping
+- * @pinning_ctx: context to be released at descriptor retirement
+ * @tx: tx request to which the page is added
+ * @page: page to map
+ * @offset: offset within the page
+ * @len: length in bytes
++ * @pinning_ctx: context to be stored on struct sdma_desc .pinning_ctx. Not
++ * added if coalesce buffer is used. E.g. pointer to pinned-page
++ * cache entry for the sdma_desc.
++ * @ctx_get: optional function to take reference to @pinning_ctx. Not called if
++ * @pinning_ctx is NULL.
++ * @ctx_put: optional function to release reference to @pinning_ctx after
++ * sdma_desc completes. May be called in interrupt context so must
++ * not sleep. Not called if @pinning_ctx is NULL.
+ *
+ * This is used to add a page/offset/length descriptor.
+ *
+@@ -692,11 +707,13 @@ static inline int _sdma_txadd_daddr(
+ */
+ static inline int sdma_txadd_page(
+ struct hfi1_devdata *dd,
+- void *pinning_ctx,
+ struct sdma_txreq *tx,
+ struct page *page,
+ unsigned long offset,
+- u16 len)
++ u16 len,
++ void *pinning_ctx,
++ void (*ctx_get)(void *),
++ void (*ctx_put)(void *))
+ {
+ dma_addr_t addr;
+ int rval;
+@@ -720,7 +737,8 @@ static inline int sdma_txadd_page(
+ return -ENOSPC;
+ }
+
+- return _sdma_txadd_daddr(dd, SDMA_MAP_PAGE, pinning_ctx, tx, addr, len);
++ return _sdma_txadd_daddr(dd, SDMA_MAP_PAGE, tx, addr, len,
++ pinning_ctx, ctx_get, ctx_put);
+ }
+
+ /**
+@@ -754,8 +772,8 @@ static inline int sdma_txadd_daddr(
+ return rval;
+ }
+
+- return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, NULL, tx,
+- addr, len);
++ return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, tx, addr, len,
++ NULL, NULL, NULL);
+ }
+
+ /**
+@@ -801,7 +819,8 @@ static inline int sdma_txadd_kvaddr(
+ return -ENOSPC;
+ }
+
+- return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, NULL, tx, addr, len);
++ return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx, addr, len,
++ NULL, NULL, NULL);
+ }
+
+ struct iowait_work;
+@@ -1034,6 +1053,4 @@ u16 sdma_get_descq_cnt(void);
+ extern uint mod_num_sdma;
+
+ void sdma_update_lmc(struct hfi1_devdata *dd, u64 mask, u32 lid);
+-
+-void system_descriptor_complete(struct hfi1_devdata *dd, struct sdma_desc *descp);
+ #endif
+diff --git a/drivers/infiniband/hw/hfi1/sdma_txreq.h b/drivers/infiniband/hw/hfi1/sdma_txreq.h
+index fad946cb5e0d8..85ae7293c2741 100644
+--- a/drivers/infiniband/hw/hfi1/sdma_txreq.h
++++ b/drivers/infiniband/hw/hfi1/sdma_txreq.h
+@@ -20,6 +20,8 @@ struct sdma_desc {
+ /* private: don't use directly */
+ u64 qw[2];
+ void *pinning_ctx;
++ /* Release reference to @pinning_ctx. May be called in interrupt context. Must not sleep. */
++ void (*ctx_put)(void *ctx);
+ };
+
+ /**
+diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c
+index ae58b48afe074..02bd62b857b75 100644
+--- a/drivers/infiniband/hw/hfi1/user_sdma.c
++++ b/drivers/infiniband/hw/hfi1/user_sdma.c
+@@ -62,18 +62,14 @@ static int defer_packet_queue(
+ static void activate_packet_queue(struct iowait *wait, int reason);
+ static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr,
+ unsigned long len);
+-static int sdma_rb_insert(void *arg, struct mmu_rb_node *mnode);
+ static int sdma_rb_evict(void *arg, struct mmu_rb_node *mnode,
+ void *arg2, bool *stop);
+ static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode);
+-static int sdma_rb_invalidate(void *arg, struct mmu_rb_node *mnode);
+
+ static struct mmu_rb_ops sdma_rb_ops = {
+ .filter = sdma_rb_filter,
+- .insert = sdma_rb_insert,
+ .evict = sdma_rb_evict,
+ .remove = sdma_rb_remove,
+- .invalidate = sdma_rb_invalidate
+ };
+
+ static int add_system_pages_to_sdma_packet(struct user_sdma_request *req,
+@@ -247,14 +243,14 @@ int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd,
+ spin_unlock(&fd->pq_rcu_lock);
+ synchronize_srcu(&fd->pq_srcu);
+ /* at this point there can be no more new requests */
+- if (pq->handler)
+- hfi1_mmu_rb_unregister(pq->handler);
+ iowait_sdma_drain(&pq->busy);
+ /* Wait until all requests have been freed. */
+ wait_event_interruptible(
+ pq->wait,
+ !atomic_read(&pq->n_reqs));
+ kfree(pq->reqs);
++ if (pq->handler)
++ hfi1_mmu_rb_unregister(pq->handler);
+ bitmap_free(pq->req_in_use);
+ kmem_cache_destroy(pq->txreq_cache);
+ flush_pq_iowait(pq);
+@@ -1275,25 +1271,17 @@ static void free_system_node(struct sdma_mmu_node *node)
+ kfree(node);
+ }
+
+-static inline void acquire_node(struct sdma_mmu_node *node)
+-{
+- atomic_inc(&node->refcount);
+- WARN_ON(atomic_read(&node->refcount) < 0);
+-}
+-
+-static inline void release_node(struct mmu_rb_handler *handler,
+- struct sdma_mmu_node *node)
+-{
+- atomic_dec(&node->refcount);
+- WARN_ON(atomic_read(&node->refcount) < 0);
+-}
+-
++/*
++ * kref_get()'s an additional kref on the returned rb_node to prevent rb_node
++ * from being released until after rb_node is assigned to an SDMA descriptor
++ * (struct sdma_desc) under add_system_iovec_to_sdma_packet(), even if the
++ * virtual address range for rb_node is invalidated between now and then.
++ */
+ static struct sdma_mmu_node *find_system_node(struct mmu_rb_handler *handler,
+ unsigned long start,
+ unsigned long end)
+ {
+ struct mmu_rb_node *rb_node;
+- struct sdma_mmu_node *node;
+ unsigned long flags;
+
+ spin_lock_irqsave(&handler->lock, flags);
+@@ -1302,11 +1290,12 @@ static struct sdma_mmu_node *find_system_node(struct mmu_rb_handler *handler,
+ spin_unlock_irqrestore(&handler->lock, flags);
+ return NULL;
+ }
+- node = container_of(rb_node, struct sdma_mmu_node, rb);
+- acquire_node(node);
++
++ /* "safety" kref to prevent release before add_system_iovec_to_sdma_packet() */
++ kref_get(&rb_node->refcount);
+ spin_unlock_irqrestore(&handler->lock, flags);
+
+- return node;
++ return container_of(rb_node, struct sdma_mmu_node, rb);
+ }
+
+ static int pin_system_pages(struct user_sdma_request *req,
+@@ -1355,6 +1344,13 @@ static int pin_system_pages(struct user_sdma_request *req,
+ return 0;
+ }
+
++/*
++ * kref refcount on *node_p will be 2 on successful addition: one kref from
++ * kref_init() for mmu_rb_handler and one kref to prevent *node_p from being
++ * released until after *node_p is assigned to an SDMA descriptor (struct
++ * sdma_desc) under add_system_iovec_to_sdma_packet(), even if the virtual
++ * address range for *node_p is invalidated between now and then.
++ */
+ static int add_system_pinning(struct user_sdma_request *req,
+ struct sdma_mmu_node **node_p,
+ unsigned long start, unsigned long len)
+@@ -1368,6 +1364,12 @@ static int add_system_pinning(struct user_sdma_request *req,
+ if (!node)
+ return -ENOMEM;
+
++ /* First kref "moves" to mmu_rb_handler */
++ kref_init(&node->rb.refcount);
++
++ /* "safety" kref to prevent release before add_system_iovec_to_sdma_packet() */
++ kref_get(&node->rb.refcount);
++
+ node->pq = pq;
+ ret = pin_system_pages(req, start, len, node, PFN_DOWN(len));
+ if (ret == 0) {
+@@ -1431,15 +1433,15 @@ static int get_system_cache_entry(struct user_sdma_request *req,
+ return 0;
+ }
+
+- SDMA_DBG(req, "prepend: node->rb.addr %lx, node->refcount %d",
+- node->rb.addr, atomic_read(&node->refcount));
++ SDMA_DBG(req, "prepend: node->rb.addr %lx, node->rb.refcount %d",
++ node->rb.addr, kref_read(&node->rb.refcount));
+ prepend_len = node->rb.addr - start;
+
+ /*
+ * This node will not be returned, instead a new node
+ * will be. So release the reference.
+ */
+- release_node(handler, node);
++ kref_put(&node->rb.refcount, hfi1_mmu_rb_release);
+
+ /* Prepend a node to cover the beginning of the allocation */
+ ret = add_system_pinning(req, node_p, start, prepend_len);
+@@ -1451,6 +1453,20 @@ static int get_system_cache_entry(struct user_sdma_request *req,
+ }
+ }
+
++static void sdma_mmu_rb_node_get(void *ctx)
++{
++ struct mmu_rb_node *node = ctx;
++
++ kref_get(&node->refcount);
++}
++
++static void sdma_mmu_rb_node_put(void *ctx)
++{
++ struct sdma_mmu_node *node = ctx;
++
++ kref_put(&node->rb.refcount, hfi1_mmu_rb_release);
++}
++
+ static int add_mapping_to_sdma_packet(struct user_sdma_request *req,
+ struct user_sdma_txreq *tx,
+ struct sdma_mmu_node *cache_entry,
+@@ -1494,9 +1510,12 @@ static int add_mapping_to_sdma_packet(struct user_sdma_request *req,
+ ctx = cache_entry;
+ }
+
+- ret = sdma_txadd_page(pq->dd, ctx, &tx->txreq,
++ ret = sdma_txadd_page(pq->dd, &tx->txreq,
+ cache_entry->pages[page_index],
+- page_offset, from_this_page);
++ page_offset, from_this_page,
++ ctx,
++ sdma_mmu_rb_node_get,
++ sdma_mmu_rb_node_put);
+ if (ret) {
+ /*
+ * When there's a failure, the entire request is freed by
+@@ -1518,8 +1537,6 @@ static int add_system_iovec_to_sdma_packet(struct user_sdma_request *req,
+ struct user_sdma_iovec *iovec,
+ size_t from_this_iovec)
+ {
+- struct mmu_rb_handler *handler = req->pq->handler;
+-
+ while (from_this_iovec > 0) {
+ struct sdma_mmu_node *cache_entry;
+ size_t from_this_cache_entry;
+@@ -1540,15 +1557,15 @@ static int add_system_iovec_to_sdma_packet(struct user_sdma_request *req,
+
+ ret = add_mapping_to_sdma_packet(req, tx, cache_entry, start,
+ from_this_cache_entry);
++
++ /*
++ * Done adding cache_entry to zero or more sdma_desc. Can
++ * kref_put() the "safety" kref taken under
++ * get_system_cache_entry().
++ */
++ kref_put(&cache_entry->rb.refcount, hfi1_mmu_rb_release);
++
+ if (ret) {
+- /*
+- * We're guaranteed that there will be no descriptor
+- * completion callback that releases this node
+- * because only the last descriptor referencing it
+- * has a context attached, and a failure means the
+- * last descriptor was never added.
+- */
+- release_node(handler, cache_entry);
+ SDMA_DBG(req, "add system segment failed %d", ret);
+ return ret;
+ }
+@@ -1599,42 +1616,12 @@ static int add_system_pages_to_sdma_packet(struct user_sdma_request *req,
+ return 0;
+ }
+
+-void system_descriptor_complete(struct hfi1_devdata *dd,
+- struct sdma_desc *descp)
+-{
+- switch (sdma_mapping_type(descp)) {
+- case SDMA_MAP_SINGLE:
+- dma_unmap_single(&dd->pcidev->dev, sdma_mapping_addr(descp),
+- sdma_mapping_len(descp), DMA_TO_DEVICE);
+- break;
+- case SDMA_MAP_PAGE:
+- dma_unmap_page(&dd->pcidev->dev, sdma_mapping_addr(descp),
+- sdma_mapping_len(descp), DMA_TO_DEVICE);
+- break;
+- }
+-
+- if (descp->pinning_ctx) {
+- struct sdma_mmu_node *node = descp->pinning_ctx;
+-
+- release_node(node->rb.handler, node);
+- }
+-}
+-
+ static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr,
+ unsigned long len)
+ {
+ return (bool)(node->addr == addr);
+ }
+
+-static int sdma_rb_insert(void *arg, struct mmu_rb_node *mnode)
+-{
+- struct sdma_mmu_node *node =
+- container_of(mnode, struct sdma_mmu_node, rb);
+-
+- atomic_inc(&node->refcount);
+- return 0;
+-}
+-
+ /*
+ * Return 1 to remove the node from the rb tree and call the remove op.
+ *
+@@ -1647,10 +1634,6 @@ static int sdma_rb_evict(void *arg, struct mmu_rb_node *mnode,
+ container_of(mnode, struct sdma_mmu_node, rb);
+ struct evict_data *evict_data = evict_arg;
+
+- /* is this node still being used? */
+- if (atomic_read(&node->refcount))
+- return 0; /* keep this node */
+-
+ /* this node will be evicted, add its pages to our count */
+ evict_data->cleared += node->npages;
+
+@@ -1668,13 +1651,3 @@ static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode)
+
+ free_system_node(node);
+ }
+-
+-static int sdma_rb_invalidate(void *arg, struct mmu_rb_node *mnode)
+-{
+- struct sdma_mmu_node *node =
+- container_of(mnode, struct sdma_mmu_node, rb);
+-
+- if (!atomic_read(&node->refcount))
+- return 1;
+- return 0;
+-}
+diff --git a/drivers/infiniband/hw/hfi1/user_sdma.h b/drivers/infiniband/hw/hfi1/user_sdma.h
+index a241836371dc1..548347d4c5bc2 100644
+--- a/drivers/infiniband/hw/hfi1/user_sdma.h
++++ b/drivers/infiniband/hw/hfi1/user_sdma.h
+@@ -104,7 +104,6 @@ struct hfi1_user_sdma_comp_q {
+ struct sdma_mmu_node {
+ struct mmu_rb_node rb;
+ struct hfi1_user_sdma_pkt_q *pq;
+- atomic_t refcount;
+ struct page **pages;
+ unsigned int npages;
+ };
+diff --git a/drivers/infiniband/hw/hfi1/vnic_sdma.c b/drivers/infiniband/hw/hfi1/vnic_sdma.c
+index 727eedfba332a..cc6324d2d1ddc 100644
+--- a/drivers/infiniband/hw/hfi1/vnic_sdma.c
++++ b/drivers/infiniband/hw/hfi1/vnic_sdma.c
+@@ -64,11 +64,11 @@ static noinline int build_vnic_ulp_payload(struct sdma_engine *sde,
+
+ /* combine physically continuous fragments later? */
+ ret = sdma_txadd_page(sde->dd,
+- NULL,
+ &tx->txreq,
+ skb_frag_page(frag),
+ skb_frag_off(frag),
+- skb_frag_size(frag));
++ skb_frag_size(frag),
++ NULL, NULL, NULL);
+ if (unlikely(ret))
+ goto bail_txadd;
+ }
+--
+2.39.2
+
--- /dev/null
+From b7651a6f9e82a83a8aca247dec3768ab3ff77e88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 14:15:03 -0700
+Subject: ice: handle extts in the miscellaneous interrupt thread
+
+From: Karol Kolacinski <karol.kolacinski@intel.com>
+
+[ Upstream commit 6e8b2c88fc8cf95ed09de25946b20b7536c88cd5 ]
+
+The ice_ptp_extts_work() and ice_ptp_periodic_work() functions are both
+scheduled on the same kthread worker, pf.ptp.kworker. The
+ice_ptp_periodic_work() function sends to the firmware to interact with the
+PHY, and must block to wait for responses.
+
+This can cause delay in responding to the PFINT_OICR_TSYN_EVNT interrupt
+cause, ultimately resulting in disruption to processing an input signal of
+the frequency is high enough. In our testing, even 100 Hz signals get
+disrupted.
+
+Fix this by instead processing the signal inside the miscellaneous
+interrupt thread prior to handling Tx timestamps.
+
+Use atomic bits in a new pf->misc_thread bitmap in order to safely
+communicate which tasks require processing within the
+ice_misc_intr_thread_fn(). This ensures the communication of desired tasks
+from the ice_misc_intr() are correctly processed without racing even in the
+event that the interrupt triggers again before the thread function exits.
+
+Fixes: 172db5f91d5f ("ice: add support for auxiliary input/output pins")
+Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Arpana Arland <arpanax.arland@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice.h | 7 ++++++
+ drivers/net/ethernet/intel/ice/ice_main.c | 29 ++++++++++++++++-------
+ drivers/net/ethernet/intel/ice/ice_ptp.c | 12 +++-------
+ drivers/net/ethernet/intel/ice/ice_ptp.h | 4 ++--
+ 4 files changed, 33 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
+index e809249500e18..03c5aecd61402 100644
+--- a/drivers/net/ethernet/intel/ice/ice.h
++++ b/drivers/net/ethernet/intel/ice/ice.h
+@@ -515,6 +515,12 @@ enum ice_pf_flags {
+ ICE_PF_FLAGS_NBITS /* must be last */
+ };
+
++enum ice_misc_thread_tasks {
++ ICE_MISC_THREAD_EXTTS_EVENT,
++ ICE_MISC_THREAD_TX_TSTAMP,
++ ICE_MISC_THREAD_NBITS /* must be last */
++};
++
+ struct ice_switchdev_info {
+ struct ice_vsi *control_vsi;
+ struct ice_vsi *uplink_vsi;
+@@ -557,6 +563,7 @@ struct ice_pf {
+ DECLARE_BITMAP(features, ICE_F_MAX);
+ DECLARE_BITMAP(state, ICE_STATE_NBITS);
+ DECLARE_BITMAP(flags, ICE_PF_FLAGS_NBITS);
++ DECLARE_BITMAP(misc_thread, ICE_MISC_THREAD_NBITS);
+ unsigned long *avail_txqs; /* bitmap to track PF Tx queue usage */
+ unsigned long *avail_rxqs; /* bitmap to track PF Rx queue usage */
+ unsigned long serv_tmr_period;
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
+index 98e8ce743fb2e..65f77ab3fc806 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -3134,20 +3134,28 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
+
+ if (oicr & PFINT_OICR_TSYN_TX_M) {
+ ena_mask &= ~PFINT_OICR_TSYN_TX_M;
+- if (!hw->reset_ongoing)
++ if (!hw->reset_ongoing) {
++ set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
+ ret = IRQ_WAKE_THREAD;
++ }
+ }
+
+ if (oicr & PFINT_OICR_TSYN_EVNT_M) {
+ u8 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
+ u32 gltsyn_stat = rd32(hw, GLTSYN_STAT(tmr_idx));
+
+- /* Save EVENTs from GTSYN register */
+- pf->ptp.ext_ts_irq |= gltsyn_stat & (GLTSYN_STAT_EVENT0_M |
+- GLTSYN_STAT_EVENT1_M |
+- GLTSYN_STAT_EVENT2_M);
+ ena_mask &= ~PFINT_OICR_TSYN_EVNT_M;
+- kthread_queue_work(pf->ptp.kworker, &pf->ptp.extts_work);
++
++ if (hw->func_caps.ts_func_info.src_tmr_owned) {
++ /* Save EVENTs from GLTSYN register */
++ pf->ptp.ext_ts_irq |= gltsyn_stat &
++ (GLTSYN_STAT_EVENT0_M |
++ GLTSYN_STAT_EVENT1_M |
++ GLTSYN_STAT_EVENT2_M);
++
++ set_bit(ICE_MISC_THREAD_EXTTS_EVENT, pf->misc_thread);
++ ret = IRQ_WAKE_THREAD;
++ }
+ }
+
+ #define ICE_AUX_CRIT_ERR (PFINT_OICR_PE_CRITERR_M | PFINT_OICR_HMC_ERR_M | PFINT_OICR_PE_PUSH_M)
+@@ -3191,8 +3199,13 @@ static irqreturn_t ice_misc_intr_thread_fn(int __always_unused irq, void *data)
+ if (ice_is_reset_in_progress(pf->state))
+ return IRQ_HANDLED;
+
+- while (!ice_ptp_process_ts(pf))
+- usleep_range(50, 100);
++ if (test_and_clear_bit(ICE_MISC_THREAD_EXTTS_EVENT, pf->misc_thread))
++ ice_ptp_extts_event(pf);
++
++ if (test_and_clear_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread)) {
++ while (!ice_ptp_process_ts(pf))
++ usleep_range(50, 100);
++ }
+
+ return IRQ_HANDLED;
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
+index ac6f06f9a2ed0..e8507d09b8488 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
+@@ -1458,15 +1458,11 @@ static int ice_ptp_adjfine(struct ptp_clock_info *info, long scaled_ppm)
+ }
+
+ /**
+- * ice_ptp_extts_work - Workqueue task function
+- * @work: external timestamp work structure
+- *
+- * Service for PTP external clock event
++ * ice_ptp_extts_event - Process PTP external clock event
++ * @pf: Board private structure
+ */
+-static void ice_ptp_extts_work(struct kthread_work *work)
++void ice_ptp_extts_event(struct ice_pf *pf)
+ {
+- struct ice_ptp *ptp = container_of(work, struct ice_ptp, extts_work);
+- struct ice_pf *pf = container_of(ptp, struct ice_pf, ptp);
+ struct ptp_clock_event event;
+ struct ice_hw *hw = &pf->hw;
+ u8 chan, tmr_idx;
+@@ -2558,7 +2554,6 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
+ ice_ptp_cfg_timestamp(pf, false);
+
+ kthread_cancel_delayed_work_sync(&ptp->work);
+- kthread_cancel_work_sync(&ptp->extts_work);
+
+ if (test_bit(ICE_PFR_REQ, pf->state))
+ return;
+@@ -2656,7 +2651,6 @@ static int ice_ptp_init_work(struct ice_pf *pf, struct ice_ptp *ptp)
+
+ /* Initialize work functions */
+ kthread_init_delayed_work(&ptp->work, ice_ptp_periodic_work);
+- kthread_init_work(&ptp->extts_work, ice_ptp_extts_work);
+
+ /* Allocate a kworker for handling work required for the ports
+ * connected to the PTP hardware clock.
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
+index 9cda2f43e0e56..9f8902c1e743d 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
++++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
+@@ -169,7 +169,6 @@ struct ice_ptp_port {
+ * struct ice_ptp - data used for integrating with CONFIG_PTP_1588_CLOCK
+ * @port: data for the PHY port initialization procedure
+ * @work: delayed work function for periodic tasks
+- * @extts_work: work function for handling external Tx timestamps
+ * @cached_phc_time: a cached copy of the PHC time for timestamp extension
+ * @cached_phc_jiffies: jiffies when cached_phc_time was last updated
+ * @ext_ts_chan: the external timestamp channel in use
+@@ -190,7 +189,6 @@ struct ice_ptp_port {
+ struct ice_ptp {
+ struct ice_ptp_port port;
+ struct kthread_delayed_work work;
+- struct kthread_work extts_work;
+ u64 cached_phc_time;
+ unsigned long cached_phc_jiffies;
+ u8 ext_ts_chan;
+@@ -256,6 +254,7 @@ int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr);
+ void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena);
+ int ice_get_ptp_clock_index(struct ice_pf *pf);
+
++void ice_ptp_extts_event(struct ice_pf *pf);
+ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb);
+ bool ice_ptp_process_ts(struct ice_pf *pf);
+
+@@ -284,6 +283,7 @@ static inline int ice_get_ptp_clock_index(struct ice_pf *pf)
+ return -1;
+ }
+
++static inline void ice_ptp_extts_event(struct ice_pf *pf) { }
+ static inline s8
+ ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
+ {
+--
+2.39.2
+
--- /dev/null
+From 0ebdc5b0dec488d640bf8072e6e69f14646aedd3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Apr 2023 15:30:42 +0200
+Subject: igc: Enable and fix RX hash usage by netstack
+
+From: Jesper Dangaard Brouer <brouer@redhat.com>
+
+[ Upstream commit 84214ab4689f962b4bfc47fc9a5838d25ac4274d ]
+
+When function igc_rx_hash() was introduced in v4.20 via commit 0507ef8a0372
+("igc: Add transmit and receive fastpath and interrupt handlers"), the
+hardware wasn't configured to provide RSS hash, thus it made sense to not
+enable net_device NETIF_F_RXHASH feature bit.
+
+The NIC hardware was configured to enable RSS hash info in v5.2 via commit
+2121c2712f82 ("igc: Add multiple receive queues control supporting"), but
+forgot to set the NETIF_F_RXHASH feature bit.
+
+The original implementation of igc_rx_hash() didn't extract the associated
+pkt_hash_type, but statically set PKT_HASH_TYPE_L3. The largest portions of
+this patch are about extracting the RSS Type from the hardware and mapping
+this to enum pkt_hash_types. This was based on Foxville i225 software user
+manual rev-1.3.1 and tested on Intel Ethernet Controller I225-LM (rev 03).
+
+For UDP it's worth noting that RSS (type) hashing have been disabled both for
+IPv4 and IPv6 (see IGC_MRQC_RSS_FIELD_IPV4_UDP + IGC_MRQC_RSS_FIELD_IPV6_UDP)
+because hardware RSS doesn't handle fragmented pkts well when enabled (can
+cause out-of-order). This results in PKT_HASH_TYPE_L3 for UDP packets, and
+hash value doesn't include UDP port numbers. Not being PKT_HASH_TYPE_L4, have
+the effect that netstack will do a software based hash calc calling into
+flow_dissect, but only when code calls skb_get_hash(), which doesn't
+necessary happen for local delivery.
+
+For QA verification testing I wrote a small bpftrace prog:
+ [0] https://github.com/xdp-project/xdp-project/blob/master/areas/hints/monitor_skb_hash_on_dev.bt
+
+Fixes: 2121c2712f82 ("igc: Add multiple receive queues control supporting")
+Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Song Yoong Siang <yoong.siang.song@intel.com>
+Link: https://lore.kernel.org/bpf/168182464270.616355.11391652654430626584.stgit@firesoul
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc.h | 28 ++++++++++++++++++++
+ drivers/net/ethernet/intel/igc/igc_main.c | 31 ++++++++++++++++++++---
+ 2 files changed, 55 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
+index df3e26c0cf01a..f83cbc4a1afa8 100644
+--- a/drivers/net/ethernet/intel/igc/igc.h
++++ b/drivers/net/ethernet/intel/igc/igc.h
+@@ -13,6 +13,7 @@
+ #include <linux/ptp_clock_kernel.h>
+ #include <linux/timecounter.h>
+ #include <linux/net_tstamp.h>
++#include <linux/bitfield.h>
+
+ #include "igc_hw.h"
+
+@@ -311,6 +312,33 @@ extern char igc_driver_name[];
+ #define IGC_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
+ #define IGC_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
+
++/* RX-desc Write-Back format RSS Type's */
++enum igc_rss_type_num {
++ IGC_RSS_TYPE_NO_HASH = 0,
++ IGC_RSS_TYPE_HASH_TCP_IPV4 = 1,
++ IGC_RSS_TYPE_HASH_IPV4 = 2,
++ IGC_RSS_TYPE_HASH_TCP_IPV6 = 3,
++ IGC_RSS_TYPE_HASH_IPV6_EX = 4,
++ IGC_RSS_TYPE_HASH_IPV6 = 5,
++ IGC_RSS_TYPE_HASH_TCP_IPV6_EX = 6,
++ IGC_RSS_TYPE_HASH_UDP_IPV4 = 7,
++ IGC_RSS_TYPE_HASH_UDP_IPV6 = 8,
++ IGC_RSS_TYPE_HASH_UDP_IPV6_EX = 9,
++ IGC_RSS_TYPE_MAX = 10,
++};
++#define IGC_RSS_TYPE_MAX_TABLE 16
++#define IGC_RSS_TYPE_MASK GENMASK(3,0) /* 4-bits (3:0) = mask 0x0F */
++
++/* igc_rss_type - Rx descriptor RSS type field */
++static inline u32 igc_rss_type(const union igc_adv_rx_desc *rx_desc)
++{
++ /* RSS Type 4-bits (3:0) number: 0-9 (above 9 is reserved)
++ * Accessing the same bits via u16 (wb.lower.lo_dword.hs_rss.pkt_info)
++ * is slightly slower than via u32 (wb.lower.lo_dword.data)
++ */
++ return le32_get_bits(rx_desc->wb.lower.lo_dword.data, IGC_RSS_TYPE_MASK);
++}
++
+ /* Interrupt defines */
+ #define IGC_START_ITR 648 /* ~6000 ints/sec */
+ #define IGC_4K_ITR 980
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index b35f5ff3536e5..c85ceed443223 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -1687,14 +1687,36 @@ static void igc_rx_checksum(struct igc_ring *ring,
+ le32_to_cpu(rx_desc->wb.upper.status_error));
+ }
+
++/* Mapping HW RSS Type to enum pkt_hash_types */
++static const enum pkt_hash_types igc_rss_type_table[IGC_RSS_TYPE_MAX_TABLE] = {
++ [IGC_RSS_TYPE_NO_HASH] = PKT_HASH_TYPE_L2,
++ [IGC_RSS_TYPE_HASH_TCP_IPV4] = PKT_HASH_TYPE_L4,
++ [IGC_RSS_TYPE_HASH_IPV4] = PKT_HASH_TYPE_L3,
++ [IGC_RSS_TYPE_HASH_TCP_IPV6] = PKT_HASH_TYPE_L4,
++ [IGC_RSS_TYPE_HASH_IPV6_EX] = PKT_HASH_TYPE_L3,
++ [IGC_RSS_TYPE_HASH_IPV6] = PKT_HASH_TYPE_L3,
++ [IGC_RSS_TYPE_HASH_TCP_IPV6_EX] = PKT_HASH_TYPE_L4,
++ [IGC_RSS_TYPE_HASH_UDP_IPV4] = PKT_HASH_TYPE_L4,
++ [IGC_RSS_TYPE_HASH_UDP_IPV6] = PKT_HASH_TYPE_L4,
++ [IGC_RSS_TYPE_HASH_UDP_IPV6_EX] = PKT_HASH_TYPE_L4,
++ [10] = PKT_HASH_TYPE_NONE, /* RSS Type above 9 "Reserved" by HW */
++ [11] = PKT_HASH_TYPE_NONE, /* keep array sized for SW bit-mask */
++ [12] = PKT_HASH_TYPE_NONE, /* to handle future HW revisons */
++ [13] = PKT_HASH_TYPE_NONE,
++ [14] = PKT_HASH_TYPE_NONE,
++ [15] = PKT_HASH_TYPE_NONE,
++};
++
+ static inline void igc_rx_hash(struct igc_ring *ring,
+ union igc_adv_rx_desc *rx_desc,
+ struct sk_buff *skb)
+ {
+- if (ring->netdev->features & NETIF_F_RXHASH)
+- skb_set_hash(skb,
+- le32_to_cpu(rx_desc->wb.lower.hi_dword.rss),
+- PKT_HASH_TYPE_L3);
++ if (ring->netdev->features & NETIF_F_RXHASH) {
++ u32 rss_hash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
++ u32 rss_type = igc_rss_type(rx_desc);
++
++ skb_set_hash(skb, rss_hash, igc_rss_type_table[rss_type]);
++ }
+ }
+
+ static void igc_rx_vlan(struct igc_ring *rx_ring,
+@@ -6553,6 +6575,7 @@ static int igc_probe(struct pci_dev *pdev,
+ netdev->features |= NETIF_F_TSO;
+ netdev->features |= NETIF_F_TSO6;
+ netdev->features |= NETIF_F_TSO_ECN;
++ netdev->features |= NETIF_F_RXHASH;
+ netdev->features |= NETIF_F_RXCSUM;
+ netdev->features |= NETIF_F_HW_CSUM;
+ netdev->features |= NETIF_F_SCTP_CRC;
+--
+2.39.2
+
--- /dev/null
+From 379c72b3cdf4ab293f211bf1d1eae4de64632cd3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 09:41:13 +0200
+Subject: ima: Fix build warnings
+
+From: Roberto Sassu <roberto.sassu@huawei.com>
+
+[ Upstream commit 95526d13038c2bbddd567a4d8e39fac42484e182 ]
+
+Fix build warnings (function parameters description) for
+ima_collect_modsig(), ima_match_policy() and ima_parse_add_rule().
+
+Fixes: 15588227e086 ("ima: Collect modsig") # v5.4+
+Fixes: 2fe5d6def167 ("ima: integrity appraisal extension") # v5.14+
+Fixes: 4af4662fa4a9 ("integrity: IMA policy") # v3.2+
+Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/ima_modsig.c | 3 +++
+ security/integrity/ima/ima_policy.c | 3 ++-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/security/integrity/ima/ima_modsig.c b/security/integrity/ima/ima_modsig.c
+index fb25723c65bc4..3e7bee30080f2 100644
+--- a/security/integrity/ima/ima_modsig.c
++++ b/security/integrity/ima/ima_modsig.c
+@@ -89,6 +89,9 @@ int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,
+
+ /**
+ * ima_collect_modsig - Calculate the file hash without the appended signature.
++ * @modsig: parsed module signature
++ * @buf: data to verify the signature on
++ * @size: data size
+ *
+ * Since the modsig is part of the file contents, the hash used in its signature
+ * isn't the same one ordinarily calculated by IMA. Therefore PKCS7 code
+diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
+index 3ca8b7348c2e4..c9b3bd8f1bb9c 100644
+--- a/security/integrity/ima/ima_policy.c
++++ b/security/integrity/ima/ima_policy.c
+@@ -721,6 +721,7 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
+ * @secid: LSM secid of the task to be validated
+ * @func: IMA hook identifier
+ * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
++ * @flags: IMA actions to consider (e.g. IMA_MEASURE | IMA_APPRAISE)
+ * @pcr: set the pcr to extend
+ * @template_desc: the template that should be used for this rule
+ * @func_data: func specific data, may be NULL
+@@ -1915,7 +1916,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
+
+ /**
+ * ima_parse_add_rule - add a rule to ima_policy_rules
+- * @rule - ima measurement policy rule
++ * @rule: ima measurement policy rule
+ *
+ * Avoid locking by allowing just one writer at a time in ima_write_policy()
+ * Returns the length of the rule parsed, an error code on failure
+--
+2.39.2
+
--- /dev/null
+From fc36a7621dda1a2d1d14b29f237e99c5be36fe8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 May 2023 17:27:55 -0700
+Subject: Input: adxl34x - do not hardcode interrupt trigger type
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit e96220bce5176ed2309f77f061dcc0430b82b25e ]
+
+Instead of hardcoding IRQ trigger type to IRQF_TRIGGER_HIGH, let's
+respect the settings specified in the firmware description.
+
+Fixes: e27c729219ad ("Input: add driver for ADXL345/346 Digital Accelerometers")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Acked-by: Michael Hennerich <michael.hennerich@analog.com>
+Link: https://lore.kernel.org/r/20230509203555.549158-1-marex@denx.de
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/misc/adxl34x.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c
+index eecca671b5884..a3f45e0ee0c75 100644
+--- a/drivers/input/misc/adxl34x.c
++++ b/drivers/input/misc/adxl34x.c
+@@ -817,8 +817,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
+ AC_WRITE(ac, POWER_CTL, 0);
+
+ err = request_threaded_irq(ac->irq, NULL, adxl34x_irq,
+- IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+- dev_name(dev), ac);
++ IRQF_ONESHOT, dev_name(dev), ac);
+ if (err) {
+ dev_err(dev, "irq %d busy?\n", ac->irq);
+ goto err_free_mem;
+--
+2.39.2
+
--- /dev/null
+From 2337ab4605d97b2ee1d493c50b170554c4a67e73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 May 2023 17:37:02 -0700
+Subject: Input: cyttsp4_core - change del_timer_sync() to
+ timer_shutdown_sync()
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit dbe836576f12743a7d2d170ad4ad4fd324c4d47a ]
+
+The watchdog_timer can schedule tx_timeout_task and watchdog_work
+can also arm watchdog_timer. The process is shown below:
+
+----------- timer schedules work ------------
+cyttsp4_watchdog_timer() //timer handler
+ schedule_work(&cd->watchdog_work)
+
+----------- work arms timer ------------
+cyttsp4_watchdog_work() //workqueue callback function
+ cyttsp4_start_wd_timer()
+ mod_timer(&cd->watchdog_timer, ...)
+
+Although del_timer_sync() and cancel_work_sync() are called in
+cyttsp4_remove(), the timer and workqueue could still be rearmed.
+As a result, the possible use after free bugs could happen. The
+process is shown below:
+
+ (cleanup routine) | (timer and workqueue routine)
+cyttsp4_remove() | cyttsp4_watchdog_timer() //timer
+ cyttsp4_stop_wd_timer() | schedule_work()
+ del_timer_sync() |
+ | cyttsp4_watchdog_work() //worker
+ | cyttsp4_start_wd_timer()
+ | mod_timer()
+ cancel_work_sync() |
+ | cyttsp4_watchdog_timer() //timer
+ | schedule_work()
+ del_timer_sync() |
+ kfree(cd) //FREE |
+ | cyttsp4_watchdog_work() // reschedule!
+ | cd-> //USE
+
+This patch changes del_timer_sync() to timer_shutdown_sync(),
+which could prevent rearming of the timer from the workqueue.
+
+Fixes: 17fb1563d69b ("Input: cyttsp4 - add core driver for Cypress TMA4XX touchscreen devices")
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Link: https://lore.kernel.org/r/20230421082919.8471-1-duoming@zju.edu.cn
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/touchscreen/cyttsp4_core.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c
+index 0cd6f626adec5..7cb26929dc732 100644
+--- a/drivers/input/touchscreen/cyttsp4_core.c
++++ b/drivers/input/touchscreen/cyttsp4_core.c
+@@ -1263,9 +1263,8 @@ static void cyttsp4_stop_wd_timer(struct cyttsp4 *cd)
+ * Ensure we wait until the watchdog timer
+ * running on a different CPU finishes
+ */
+- del_timer_sync(&cd->watchdog_timer);
++ timer_shutdown_sync(&cd->watchdog_timer);
+ cancel_work_sync(&cd->watchdog_work);
+- del_timer_sync(&cd->watchdog_timer);
+ }
+
+ static void cyttsp4_watchdog_timer(struct timer_list *t)
+--
+2.39.2
+
--- /dev/null
+From 58f8d58576c3fc8eb088c7cfa4646fcc8fcd771c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 May 2023 17:01:45 -0700
+Subject: Input: drv260x - sleep between polling GO bit
+
+From: Luca Weiss <luca@z3ntu.xyz>
+
+[ Upstream commit efef661dfa6bf8cbafe4cd6a97433fcef0118967 ]
+
+When doing the initial startup there's no need to poll without any
+delay and spam the I2C bus.
+
+Let's sleep 15ms between each attempt, which is the same time as used
+in the vendor driver.
+
+Fixes: 7132fe4f5687 ("Input: drv260x - add TI drv260x haptics driver")
+Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
+Link: https://lore.kernel.org/r/20230430-drv260x-improvements-v1-2-1fb28b4cc698@z3ntu.xyz
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/misc/drv260x.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c
+index 8a9ebfc04a2d9..85371fa1a03ed 100644
+--- a/drivers/input/misc/drv260x.c
++++ b/drivers/input/misc/drv260x.c
+@@ -435,6 +435,7 @@ static int drv260x_init(struct drv260x_data *haptics)
+ }
+
+ do {
++ usleep_range(15000, 15500);
+ error = regmap_read(haptics->regmap, DRV260X_GO, &cal_buf);
+ if (error) {
+ dev_err(&haptics->client->dev,
+--
+2.39.2
+
--- /dev/null
+From 2be418139c04c9d1df81ee2b29381f62f0a4a0ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 12:05:32 -0700
+Subject: Input: pm8941-powerkey - fix debounce on gen2+ PMICs
+
+From: Caleb Connolly <caleb.connolly@linaro.org>
+
+[ Upstream commit 8c9cce9cb81b5fdc6e66bf3f129727b89e8daab7 ]
+
+Since PM8998/PM660, the power key debounce register was redefined to
+support shorter debounce times. On PM8941 the shortest debounce time
+(represented by register value 0) was 15625us, on PM8998 the shortest
+debounce time is 62us, with the default being 2ms.
+
+Adjust the bit shift to correctly program debounce on PM8998 and newer.
+
+Fixes: 68c581d5e7d8 ("Input: add Qualcomm PM8941 power key driver")
+Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
+Link: https://lore.kernel.org/r/20230529-pm8941-pwrkey-debounce-v1-2-c043a6d5c814@linaro.org
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/misc/pm8941-pwrkey.c | 19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/input/misc/pm8941-pwrkey.c b/drivers/input/misc/pm8941-pwrkey.c
+index b6a27ebae977b..74d77d8aaeff2 100644
+--- a/drivers/input/misc/pm8941-pwrkey.c
++++ b/drivers/input/misc/pm8941-pwrkey.c
+@@ -50,7 +50,10 @@
+ #define PON_RESIN_PULL_UP BIT(0)
+
+ #define PON_DBC_CTL 0x71
+-#define PON_DBC_DELAY_MASK 0x7
++#define PON_DBC_DELAY_MASK_GEN1 0x7
++#define PON_DBC_DELAY_MASK_GEN2 0xf
++#define PON_DBC_SHIFT_GEN1 6
++#define PON_DBC_SHIFT_GEN2 14
+
+ struct pm8941_data {
+ unsigned int pull_up_bit;
+@@ -247,7 +250,7 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
+ struct device *parent;
+ struct device_node *regmap_node;
+ const __be32 *addr;
+- u32 req_delay;
++ u32 req_delay, mask, delay_shift;
+ int error;
+
+ if (of_property_read_u32(pdev->dev.of_node, "debounce", &req_delay))
+@@ -336,12 +339,20 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
+ pwrkey->input->phys = pwrkey->data->phys;
+
+ if (pwrkey->data->supports_debounce_config) {
+- req_delay = (req_delay << 6) / USEC_PER_SEC;
++ if (pwrkey->subtype >= PON_SUBTYPE_GEN2_PRIMARY) {
++ mask = PON_DBC_DELAY_MASK_GEN2;
++ delay_shift = PON_DBC_SHIFT_GEN2;
++ } else {
++ mask = PON_DBC_DELAY_MASK_GEN1;
++ delay_shift = PON_DBC_SHIFT_GEN1;
++ }
++
++ req_delay = (req_delay << delay_shift) / USEC_PER_SEC;
+ req_delay = ilog2(req_delay);
+
+ error = regmap_update_bits(pwrkey->regmap,
+ pwrkey->baseaddr + PON_DBC_CTL,
+- PON_DBC_DELAY_MASK,
++ mask,
+ req_delay);
+ if (error) {
+ dev_err(&pdev->dev, "failed to set debounce: %d\n",
+--
+2.39.2
+
--- /dev/null
+From 6922dd5f03acbdc5333304df2108b5c93895f6eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 12:39:48 +0100
+Subject: iommu/virtio: Detach domain on endpoint release
+
+From: Jean-Philippe Brucker <jean-philippe@linaro.org>
+
+[ Upstream commit 809d0810e3520da669d231303608cdf5fe5c1a70 ]
+
+When an endpoint is released, for example a PCIe VF being destroyed or a
+function hot-unplugged, it should be detached from its domain. Send a
+DETACH request.
+
+Fixes: edcd69ab9a32 ("iommu: Add virtio-iommu driver")
+Reported-by: Akihiko Odaki <akihiko.odaki@daynix.com>
+Link: https://lore.kernel.org/all/15bf1b00-3aa0-973a-3a86-3fa5c4d41d2c@daynix.com/
+Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
+Link: https://lore.kernel.org/r/20230515113946.1017624-2-jean-philippe@linaro.org
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/virtio-iommu.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
+index 5b8fe9bfa9a5b..fd316a37d7562 100644
+--- a/drivers/iommu/virtio-iommu.c
++++ b/drivers/iommu/virtio-iommu.c
+@@ -788,6 +788,29 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
+ return 0;
+ }
+
++static void viommu_detach_dev(struct viommu_endpoint *vdev)
++{
++ int i;
++ struct virtio_iommu_req_detach req;
++ struct viommu_domain *vdomain = vdev->vdomain;
++ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(vdev->dev);
++
++ if (!vdomain)
++ return;
++
++ req = (struct virtio_iommu_req_detach) {
++ .head.type = VIRTIO_IOMMU_T_DETACH,
++ .domain = cpu_to_le32(vdomain->id),
++ };
++
++ for (i = 0; i < fwspec->num_ids; i++) {
++ req.endpoint = cpu_to_le32(fwspec->ids[i]);
++ WARN_ON(viommu_send_req_sync(vdev->viommu, &req, sizeof(req)));
++ }
++ vdomain->nr_endpoints--;
++ vdev->vdomain = NULL;
++}
++
+ static int viommu_map_pages(struct iommu_domain *domain, unsigned long iova,
+ phys_addr_t paddr, size_t pgsize, size_t pgcount,
+ int prot, gfp_t gfp, size_t *mapped)
+@@ -990,6 +1013,7 @@ static void viommu_release_device(struct device *dev)
+ {
+ struct viommu_endpoint *vdev = dev_iommu_priv_get(dev);
+
++ viommu_detach_dev(vdev);
+ iommu_put_resv_regions(dev, &vdev->resv_regions);
+ kfree(vdev);
+ }
+--
+2.39.2
+
--- /dev/null
+From 8b6f0e36dbdf3cfefccdb8d6f7a9c70f8962aa2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 12:39:50 +0100
+Subject: iommu/virtio: Return size mapped for a detached domain
+
+From: Jean-Philippe Brucker <jean-philippe@linaro.org>
+
+[ Upstream commit 7061b6af34686e7e2364b7240cfb061293218f2d ]
+
+When map() is called on a detached domain, the domain does not exist in
+the device so we do not send a MAP request, but we do update the
+internal mapping tree, to be replayed on the next attach. Since this
+constitutes a successful iommu_map() call, return *mapped in this case
+too.
+
+Fixes: 7e62edd7a33a ("iommu/virtio: Add map/unmap_pages() callbacks implementation")
+Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/20230515113946.1017624-3-jean-philippe@linaro.org
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/virtio-iommu.c | 33 +++++++++++++++++----------------
+ 1 file changed, 17 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
+index fd316a37d7562..3551ed057774e 100644
+--- a/drivers/iommu/virtio-iommu.c
++++ b/drivers/iommu/virtio-iommu.c
+@@ -833,25 +833,26 @@ static int viommu_map_pages(struct iommu_domain *domain, unsigned long iova,
+ if (ret)
+ return ret;
+
+- map = (struct virtio_iommu_req_map) {
+- .head.type = VIRTIO_IOMMU_T_MAP,
+- .domain = cpu_to_le32(vdomain->id),
+- .virt_start = cpu_to_le64(iova),
+- .phys_start = cpu_to_le64(paddr),
+- .virt_end = cpu_to_le64(end),
+- .flags = cpu_to_le32(flags),
+- };
+-
+- if (!vdomain->nr_endpoints)
+- return 0;
++ if (vdomain->nr_endpoints) {
++ map = (struct virtio_iommu_req_map) {
++ .head.type = VIRTIO_IOMMU_T_MAP,
++ .domain = cpu_to_le32(vdomain->id),
++ .virt_start = cpu_to_le64(iova),
++ .phys_start = cpu_to_le64(paddr),
++ .virt_end = cpu_to_le64(end),
++ .flags = cpu_to_le32(flags),
++ };
+
+- ret = viommu_send_req_sync(vdomain->viommu, &map, sizeof(map));
+- if (ret)
+- viommu_del_mappings(vdomain, iova, end);
+- else if (mapped)
++ ret = viommu_send_req_sync(vdomain->viommu, &map, sizeof(map));
++ if (ret) {
++ viommu_del_mappings(vdomain, iova, end);
++ return ret;
++ }
++ }
++ if (mapped)
+ *mapped = size;
+
+- return ret;
++ return 0;
+ }
+
+ static size_t viommu_unmap_pages(struct iommu_domain *domain, unsigned long iova,
+--
+2.39.2
+
--- /dev/null
+From 1917a035237ee2a5fdbaf006ca96a2541678fdbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 11:11:24 -0300
+Subject: iommufd: Call iopt_area_contig_done() under the lock
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit dbe245cdf5189e88d680379ed13901356628b650 ]
+
+The iter internally holds a pointer to the area and
+iopt_area_contig_done() will dereference it. The pointer is not valid
+outside the iova_rwsem.
+
+syzkaller reports:
+
+ BUG: KASAN: slab-use-after-free in iommufd_access_unpin_pages+0x363/0x370
+ Read of size 8 at addr ffff888022286e20 by task syz-executor669/5771
+
+ CPU: 0 PID: 5771 Comm: syz-executor669 Not tainted 6.4.0-rc5-syzkaller-00313-g4c605260bc60 #0
+ Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/25/2023
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0xd9/0x150
+ print_address_description.constprop.0+0x2c/0x3c0
+ kasan_report+0x11c/0x130
+ iommufd_access_unpin_pages+0x363/0x370
+ iommufd_test_access_unmap+0x24b/0x390
+ iommufd_access_notify_unmap+0x24c/0x3a0
+ iopt_unmap_iova_range+0x4c4/0x5f0
+ iopt_unmap_all+0x27/0x50
+ iommufd_ioas_unmap+0x3d0/0x490
+ iommufd_fops_ioctl+0x317/0x4b0
+ __x64_sys_ioctl+0x197/0x210
+ do_syscall_64+0x39/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+ RIP: 0033:0x7fec1dae3b19
+ Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 11 15 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
+ RSP: 002b:00007fec1da74308 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
+ RAX: ffffffffffffffda RBX: 00007fec1db6b438 RCX: 00007fec1dae3b19
+ RDX: 0000000020000100 RSI: 0000000000003b86 RDI: 0000000000000003
+ RBP: 00007fec1db6b430 R08: 00007fec1da74700 R09: 0000000000000000
+ R10: 00007fec1da74700 R11: 0000000000000246 R12: 00007fec1db6b43c
+ R13: 00007fec1db39074 R14: 6d6f692f7665642f R15: 0000000000022000
+ </TASK>
+
+ Allocated by task 5770:
+ kasan_save_stack+0x22/0x40
+ kasan_set_track+0x25/0x30
+ __kasan_kmalloc+0xa2/0xb0
+ iopt_alloc_area_pages+0x94/0x560
+ iopt_map_user_pages+0x205/0x4e0
+ iommufd_ioas_map+0x329/0x5f0
+ iommufd_fops_ioctl+0x317/0x4b0
+ __x64_sys_ioctl+0x197/0x210
+ do_syscall_64+0x39/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+ Freed by task 5770:
+ kasan_save_stack+0x22/0x40
+ kasan_set_track+0x25/0x30
+ kasan_save_free_info+0x2e/0x40
+ ____kasan_slab_free+0x160/0x1c0
+ slab_free_freelist_hook+0x8b/0x1c0
+ __kmem_cache_free+0xaf/0x2d0
+ iopt_unmap_iova_range+0x288/0x5f0
+ iopt_unmap_all+0x27/0x50
+ iommufd_ioas_unmap+0x3d0/0x490
+ iommufd_fops_ioctl+0x317/0x4b0
+ __x64_sys_ioctl+0x197/0x210
+ do_syscall_64+0x39/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+The parallel unmap free'd iter->area the instant the lock was released.
+
+Fixes: 51fe6141f0f6 ("iommufd: Data structure to provide IOVA to PFN mapping")
+Link: https://lore.kernel.org/r/2-v2-9a03761d445d+54-iommufd_syz2_jgg@nvidia.com
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reported-by: syzbot+6c8d756f238a75fc3eb8@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/r/000000000000905eba05fe38e9f2@google.com
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/iommufd/device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c
+index a0c66f47a65ad..532e12ea23efe 100644
+--- a/drivers/iommu/iommufd/device.c
++++ b/drivers/iommu/iommufd/device.c
+@@ -560,8 +560,8 @@ void iommufd_access_unpin_pages(struct iommufd_access *access,
+ iopt_area_iova_to_index(
+ area,
+ min(last_iova, iopt_area_last_iova(area))));
+- up_read(&iopt->iova_rwsem);
+ WARN_ON(!iopt_area_contig_done(&iter));
++ up_read(&iopt->iova_rwsem);
+ }
+ EXPORT_SYMBOL_NS_GPL(iommufd_access_unpin_pages, IOMMUFD);
+
+--
+2.39.2
+
--- /dev/null
+From 4508a5cceac39d0c6692accfb6455c8f28a1f5e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 11:11:23 -0300
+Subject: iommufd: Do not access the area pointer after unlocking
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit 804ca14d04df09bf7924bacc5ad22a4bed80c94f ]
+
+A concurrent unmap can trigger freeing of the area pointers while we are
+generating an unmapping notification for accesses.
+
+syzkaller reports:
+
+ BUG: KASAN: slab-use-after-free in iopt_unmap_iova_range+0x5ba/0x5f0
+ Read of size 4 at addr ffff888075996184 by task syz-executor.2/31160
+
+ CPU: 1 PID: 31160 Comm: syz-executor.2 Not tainted 6.4.0-rc5-syzkaller-00313-g4c605260bc60 #0
+ Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/25/2023
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0xd9/0x150
+ print_address_description.constprop.0+0x2c/0x3c0
+ kasan_report+0x11c/0x130
+ iopt_unmap_iova_range+0x5ba/0x5f0
+ iopt_unmap_all+0x27/0x50
+ iommufd_ioas_unmap+0x3d0/0x490
+ iommufd_fops_ioctl+0x317/0x4b0
+ __x64_sys_ioctl+0x197/0x210
+ do_syscall_64+0x39/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+ RIP: 0033:0x7f0812c8c169
+ Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 19 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
+ RSP: 002b:00007f0813914168 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
+ RAX: ffffffffffffffda RBX: 00007f0812dabf80 RCX: 00007f0812c8c169
+ RDX: 0000000020000100 RSI: 0000000000003b86 RDI: 0000000000000005
+ RBP: 00007f0812ce7ca1 R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+ R13: 00007f0812ecfb1f R14: 00007f0813914300 R15: 0000000000022000
+ </TASK>
+
+ Allocated by task 31160:
+ kasan_save_stack+0x22/0x40
+ kasan_set_track+0x25/0x30
+ __kasan_kmalloc+0xa2/0xb0
+ iopt_alloc_area_pages+0x94/0x560
+ iopt_map_user_pages+0x205/0x4e0
+ iommufd_ioas_map+0x329/0x5f0
+ iommufd_fops_ioctl+0x317/0x4b0
+ __x64_sys_ioctl+0x197/0x210
+ do_syscall_64+0x39/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+ Freed by task 31161:
+ kasan_save_stack+0x22/0x40
+ kasan_set_track+0x25/0x30
+ kasan_save_free_info+0x2e/0x40
+ ____kasan_slab_free+0x160/0x1c0
+ slab_free_freelist_hook+0x8b/0x1c0
+ __kmem_cache_free+0xaf/0x2d0
+ iopt_unmap_iova_range+0x288/0x5f0
+ iopt_unmap_all+0x27/0x50
+ iommufd_ioas_unmap+0x3d0/0x490
+ iommufd_fops_ioctl+0x317/0x4b0
+ __x64_sys_ioctl+0x197/0x210
+ do_syscall_64+0x39/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+ The buggy address belongs to the object at ffff888075996100
+ which belongs to the cache kmalloc-cg-192 of size 192
+ The buggy address is located 132 bytes inside of
+ freed 192-byte region [ffff888075996100, ffff8880759961c0)
+
+ The buggy address belongs to the physical page:
+ page:ffffea0001d66580 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x75996
+ memcg:ffff88801f1c2701
+ flags: 0xfff00000000200(slab|node=0|zone=1|lastcpupid=0x7ff)
+ page_type: 0xffffffff()
+ raw: 00fff00000000200 ffff88801244ddc0 dead000000000122 0000000000000000
+ raw: 0000000000000000 0000000080100010 00000001ffffffff ffff88801f1c2701
+ page dumped because: kasan: bad access detected
+ page_owner tracks the page as allocated
+ page last allocated via order 0, migratetype Unmovable, gfp_mask 0x112cc0(GFP_USER|__GFP_NOWARN|__GFP_NORETRY), pid 31157, tgid 31154 (syz-executor.0), ts 1984547323469, free_ts 1983933451331
+ post_alloc_hook+0x2db/0x350
+ get_page_from_freelist+0xf41/0x2c00
+ __alloc_pages+0x1cb/0x4a0
+ alloc_pages+0x1aa/0x270
+ allocate_slab+0x25f/0x390
+ ___slab_alloc+0xa91/0x1400
+ __slab_alloc.constprop.0+0x56/0xa0
+ __kmem_cache_alloc_node+0x136/0x320
+ kmalloc_trace+0x26/0xe0
+ iommufd_test+0x1328/0x2c20
+ iommufd_fops_ioctl+0x317/0x4b0
+ __x64_sys_ioctl+0x197/0x210
+ do_syscall_64+0x39/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+ page last free stack trace:
+ free_unref_page_prepare+0x62e/0xcb0
+ free_unref_page_list+0xe3/0xa70
+ release_pages+0xcd8/0x1380
+ tlb_batch_pages_flush+0xa8/0x1a0
+ tlb_finish_mmu+0x14b/0x7e0
+ exit_mmap+0x2b2/0x930
+ __mmput+0x128/0x4c0
+ mmput+0x60/0x70
+ do_exit+0x9b0/0x29b0
+ do_group_exit+0xd4/0x2a0
+ get_signal+0x2318/0x25b0
+ arch_do_signal_or_restart+0x79/0x5c0
+ exit_to_user_mode_prepare+0x11f/0x240
+ syscall_exit_to_user_mode+0x1d/0x50
+ do_syscall_64+0x46/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Precompute what is needed to call the access function and do not check the
+area's num_accesses again as the pointer may not be valid anymore. Use a
+counter instead.
+
+Fixes: 51fe6141f0f6 ("iommufd: Data structure to provide IOVA to PFN mapping")
+Link: https://lore.kernel.org/r/1-v2-9a03761d445d+54-iommufd_syz2_jgg@nvidia.com
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reported-by: syzbot+1ad12d16afca0e7d2dde@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/r/0000000000001d40fc05fe385332@google.com
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/iommufd/io_pagetable.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iommu/iommufd/io_pagetable.c b/drivers/iommu/iommufd/io_pagetable.c
+index e0ae72b9e67f8..724c4c5742417 100644
+--- a/drivers/iommu/iommufd/io_pagetable.c
++++ b/drivers/iommu/iommufd/io_pagetable.c
+@@ -458,6 +458,7 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start,
+ {
+ struct iopt_area *area;
+ unsigned long unmapped_bytes = 0;
++ unsigned int tries = 0;
+ int rc = -ENOENT;
+
+ /*
+@@ -484,19 +485,26 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start,
+ goto out_unlock_iova;
+ }
+
++ if (area_first != start)
++ tries = 0;
++
+ /*
+ * num_accesses writers must hold the iova_rwsem too, so we can
+ * safely read it under the write side of the iovam_rwsem
+ * without the pages->mutex.
+ */
+ if (area->num_accesses) {
++ size_t length = iopt_area_length(area);
++
+ start = area_first;
+ area->prevent_access = true;
+ up_write(&iopt->iova_rwsem);
+ up_read(&iopt->domains_rwsem);
+- iommufd_access_notify_unmap(iopt, area_first,
+- iopt_area_length(area));
+- if (WARN_ON(READ_ONCE(area->num_accesses)))
++
++ iommufd_access_notify_unmap(iopt, area_first, length);
++ /* Something is not responding to unmap requests. */
++ tries++;
++ if (WARN_ON(tries > 100))
+ return -EDEADLOCK;
+ goto again;
+ }
+--
+2.39.2
+
--- /dev/null
+From b4adf465bb5ccdb2c3cc7ab86324664b6bdbe941 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 17:33:47 +0800
+Subject: ipvlan: Fix return value of ipvlan_queue_xmit()
+
+From: Cambda Zhu <cambda@linux.alibaba.com>
+
+[ Upstream commit 8a9922e7be6d042fa00f894c376473b17a162b66 ]
+
+ipvlan_queue_xmit() should return NET_XMIT_XXX, but
+ipvlan_xmit_mode_l2/l3() returns rx_handler_result_t or NET_RX_XXX
+in some cases. ipvlan_rcv_frame() will only return RX_HANDLER_CONSUMED
+in ipvlan_xmit_mode_l2/l3() because 'local' is true. It's equal to
+NET_XMIT_SUCCESS. But dev_forward_skb() can return NET_RX_SUCCESS or
+NET_RX_DROP, and returning NET_RX_DROP(NET_XMIT_DROP) will increase
+both ipvlan and ipvlan->phy_dev drops counter.
+
+The skb to forward can be treated as xmitted successfully. This patch
+makes ipvlan_queue_xmit() return NET_XMIT_SUCCESS for forward skb.
+
+Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
+Signed-off-by: Cambda Zhu <cambda@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20230626093347.7492-1-cambda@linux.alibaba.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ipvlan/ipvlan_core.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
+index ab5133eb1d517..e45817caaee8d 100644
+--- a/drivers/net/ipvlan/ipvlan_core.c
++++ b/drivers/net/ipvlan/ipvlan_core.c
+@@ -585,7 +585,8 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
+ consume_skb(skb);
+ return NET_XMIT_DROP;
+ }
+- return ipvlan_rcv_frame(addr, &skb, true);
++ ipvlan_rcv_frame(addr, &skb, true);
++ return NET_XMIT_SUCCESS;
+ }
+ }
+ out:
+@@ -611,7 +612,8 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
+ consume_skb(skb);
+ return NET_XMIT_DROP;
+ }
+- return ipvlan_rcv_frame(addr, &skb, true);
++ ipvlan_rcv_frame(addr, &skb, true);
++ return NET_XMIT_SUCCESS;
+ }
+ }
+ skb = skb_share_check(skb, GFP_ATOMIC);
+@@ -623,7 +625,8 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
+ * the skb for the main-dev. At the RX side we just return
+ * RX_PASS for it to be processed further on the stack.
+ */
+- return dev_forward_skb(ipvlan->phy_dev, skb);
++ dev_forward_skb(ipvlan->phy_dev, skb);
++ return NET_XMIT_SUCCESS;
+
+ } else if (is_multicast_ether_addr(eth->h_dest)) {
+ skb_reset_mac_header(skb);
+--
+2.39.2
+
--- /dev/null
+From f9bba0ec0c8343d38d9efd650a0c6d56a260e6ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 May 2023 18:33:42 +0200
+Subject: irqchip/jcore-aic: Fix missing allocation of IRQ descriptors
+
+From: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+
+[ Upstream commit 4848229494a323eeaab62eee5574ef9f7de80374 ]
+
+The initialization function for the J-Core AIC aic_irq_of_init() is
+currently missing the call to irq_alloc_descs() which allocates and
+initializes all the IRQ descriptors. Add missing function call and
+return the error code from irq_alloc_descs() in case the allocation
+fails.
+
+Fixes: 981b58f66cfc ("irqchip/jcore-aic: Add J-Core AIC driver")
+Signed-off-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+Tested-by: Rob Landley <rob@landley.net>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230510163343.43090-1-glaubitz@physik.fu-berlin.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-jcore-aic.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/irqchip/irq-jcore-aic.c b/drivers/irqchip/irq-jcore-aic.c
+index 5f47d8ee4ae39..b9dcc8e78c750 100644
+--- a/drivers/irqchip/irq-jcore-aic.c
++++ b/drivers/irqchip/irq-jcore-aic.c
+@@ -68,6 +68,7 @@ static int __init aic_irq_of_init(struct device_node *node,
+ unsigned min_irq = JCORE_AIC2_MIN_HWIRQ;
+ unsigned dom_sz = JCORE_AIC_MAX_HWIRQ+1;
+ struct irq_domain *domain;
++ int ret;
+
+ pr_info("Initializing J-Core AIC\n");
+
+@@ -100,6 +101,12 @@ static int __init aic_irq_of_init(struct device_node *node,
+ jcore_aic.irq_unmask = noop;
+ jcore_aic.name = "AIC";
+
++ ret = irq_alloc_descs(-1, min_irq, dom_sz - min_irq,
++ of_node_to_nid(node));
++
++ if (ret < 0)
++ return ret;
++
+ domain = irq_domain_add_legacy(node, dom_sz - min_irq, min_irq, min_irq,
+ &jcore_aic_irqdomain_ops,
+ &jcore_aic);
+--
+2.39.2
+
--- /dev/null
+From cc4812ea2cd98750479feae40f8687b24eb378af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 19:59:36 +0800
+Subject: irqchip/loongson-eiointc: Fix irq affinity setting during resume
+
+From: Jianmin Lv <lvjianmin@loongson.cn>
+
+[ Upstream commit fb07b8f83441febeb0daf199b5f18c6de9bbab03 ]
+
+The hierarchy of PCH PIC, PCH PCI MSI and EIONTC is as following:
+
+ PCH PIC ------->|
+ |---->EIOINTC
+ PCH PCI MSI --->|
+
+so the irq_data list of irq_desc for IRQs on PCH PIC and PCH PCI MSI
+is like this:
+
+irq_desc->irq_data(domain: PCH PIC)->parent_data(domain: EIOINTC)
+irq_desc->irq_data(domain: PCH PCI MSI)->parent_data(domain: EIOINTC)
+
+In eiointc_resume(), the irq_data passed into eiointc_set_irq_affinity()
+should be matched to EIOINTC domain instead of PCH PIC or PCH PCI MSI
+domain, so fix it.
+
+Fixes: a90335c2dfb4 ("irqchip/loongson-eiointc: Add suspend/resume support")
+
+Reported-by: yangqiming <yangqiming@loongson.cn>
+Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230614115936.5950-6-lvjianmin@loongson.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-loongson-eiointc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c
+index 90181c42840b4..873a326ed6cbc 100644
+--- a/drivers/irqchip/irq-loongson-eiointc.c
++++ b/drivers/irqchip/irq-loongson-eiointc.c
+@@ -317,7 +317,7 @@ static void eiointc_resume(void)
+ desc = irq_resolve_mapping(eiointc_priv[i]->eiointc_domain, j);
+ if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) {
+ raw_spin_lock(&desc->lock);
+- irq_data = &desc->irq_data;
++ irq_data = irq_domain_get_irq_data(eiointc_priv[i]->eiointc_domain, irq_desc_get_irq(desc));
+ eiointc_set_irq_affinity(irq_data, irq_data->common->affinity, 0);
+ raw_spin_unlock(&desc->lock);
+ }
+--
+2.39.2
+
--- /dev/null
+From c57b790bfbc452b0535601b2f3da8bbd5098d5d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 17:56:14 +0200
+Subject: irqchip/stm32-exti: Fix warning on initialized field overwritten
+
+From: Antonio Borneo <antonio.borneo@foss.st.com>
+
+[ Upstream commit 48f31e496488a25f443c0df52464da446fb1d10c ]
+
+While compiling with W=1, both gcc and clang complain about a
+tricky way to initialize an array by filling it with a non-zero
+value and then overrride some of the array elements.
+In this case the override is intentional, so just disable the
+specific warning for only this part of the code.
+
+Note: the flag "-Woverride-init" is recognized by both compilers,
+but the warning msg from clang reports "-Winitializer-overrides".
+The doc of clang clarifies that the two flags are synonyms, so use
+here only the flag name common on both compilers.
+
+Signed-off-by: Antonio Borneo <antonio.borneo@foss.st.com>
+Fixes: c297493336b7 ("irqchip/stm32-exti: Simplify irq description table")
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230601155614.34490-1-antonio.borneo@foss.st.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-stm32-exti.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
+index 6a3f7498ea8ea..8bbb2b114636c 100644
+--- a/drivers/irqchip/irq-stm32-exti.c
++++ b/drivers/irqchip/irq-stm32-exti.c
+@@ -173,6 +173,16 @@ static struct irq_chip stm32_exti_h_chip_direct;
+ #define EXTI_INVALID_IRQ U8_MAX
+ #define STM32MP1_DESC_IRQ_SIZE (ARRAY_SIZE(stm32mp1_exti_banks) * IRQS_PER_BANK)
+
++/*
++ * Use some intentionally tricky logic here to initialize the whole array to
++ * EXTI_INVALID_IRQ, but then override certain fields, requiring us to indicate
++ * that we "know" that there are overrides in this structure, and we'll need to
++ * disable that warning from W=1 builds.
++ */
++__diag_push();
++__diag_ignore_all("-Woverride-init",
++ "logic to initialize all and then override some is OK");
++
+ static const u8 stm32mp1_desc_irq[] = {
+ /* default value */
+ [0 ... (STM32MP1_DESC_IRQ_SIZE - 1)] = EXTI_INVALID_IRQ,
+@@ -266,6 +276,8 @@ static const u8 stm32mp13_desc_irq[] = {
+ [70] = 98,
+ };
+
++__diag_pop();
++
+ static const struct stm32_exti_drv_data stm32mp1_drv_data = {
+ .exti_banks = stm32mp1_exti_banks,
+ .bank_nr = ARRAY_SIZE(stm32mp1_exti_banks),
+--
+2.39.2
+
--- /dev/null
+From e4a5f4a2602529a790ee6bf1cbbc0f559c3e0d2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 12:19:53 -0700
+Subject: kbuild: builddeb: always make modules_install, to install
+ modules.builtin*
+
+From: Josh Triplett <josh@joshtriplett.org>
+
+[ Upstream commit 4243afdb932677a03770753be8c54b3190a512e8 ]
+
+Even for a non-modular kernel, the kernel builds modules.builtin and
+modules.builtin.modinfo, with information about the built-in modules.
+Tools such as initramfs-tools need these files to build a working
+initramfs on some systems, such as those requiring firmware.
+
+Now that `make modules_install` works even in non-modular kernels and
+installs these files, unconditionally invoke it when building a Debian
+package.
+
+Signed-off-by: Josh Triplett <josh@joshtriplett.org>
+Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Stable-dep-of: 1240dabe8d58 ("kbuild: deb-pkg: remove the CONFIG_MODULES check in buildeb")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/package/builddeb | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/package/builddeb b/scripts/package/builddeb
+index 7b23f52c70c5f..07087ca68fe4b 100755
+--- a/scripts/package/builddeb
++++ b/scripts/package/builddeb
+@@ -62,8 +62,8 @@ install_linux_image () {
+ ${MAKE} -f ${srctree}/Makefile INSTALL_DTBS_PATH="${pdir}/usr/lib/linux-image-${KERNELRELEASE}" dtbs_install
+ fi
+
++ ${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" modules_install
+ if is_enabled CONFIG_MODULES; then
+- ${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" modules_install
+ rm -f "${pdir}/lib/modules/${KERNELRELEASE}/build"
+ rm -f "${pdir}/lib/modules/${KERNELRELEASE}/source"
+ if [ "${SRCARCH}" = um ] ; then
+--
+2.39.2
+
--- /dev/null
+From 0c62a478449cd80db7818b4820ac3020cd3d269b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 03:16:23 +0900
+Subject: kbuild: deb-pkg: remove the CONFIG_MODULES check in buildeb
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 1240dabe8d58b4eff09e7edf1560da0360f997aa ]
+
+When CONFIG_MODULES is disabled for ARCH=um, 'make (bin)deb-pkg' fails
+with an error like follows:
+
+ cp: cannot create regular file 'debian/linux-image/usr/lib/uml/modules/6.4.0-rc2+/System.map': No such file or directory
+
+Remove the CONFIG_MODULES check completely so ${pdir}/usr/lib/uml/modules
+will always be created and modules.builtin.(modinfo) will be installed
+under it for ARCH=um.
+
+Fixes: b611daae5efc ("kbuild: deb-pkg: split image and debug objects staging out into functions")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/package/builddeb | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/scripts/package/builddeb b/scripts/package/builddeb
+index 07087ca68fe4b..a0af4c0f971ca 100755
+--- a/scripts/package/builddeb
++++ b/scripts/package/builddeb
+@@ -63,17 +63,13 @@ install_linux_image () {
+ fi
+
+ ${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" modules_install
+- if is_enabled CONFIG_MODULES; then
+- rm -f "${pdir}/lib/modules/${KERNELRELEASE}/build"
+- rm -f "${pdir}/lib/modules/${KERNELRELEASE}/source"
+- if [ "${SRCARCH}" = um ] ; then
+- mkdir -p "${pdir}/usr/lib/uml/modules"
+- mv "${pdir}/lib/modules/${KERNELRELEASE}" "${pdir}/usr/lib/uml/modules/${KERNELRELEASE}"
+- fi
+- fi
++ rm -f "${pdir}/lib/modules/${KERNELRELEASE}/build"
++ rm -f "${pdir}/lib/modules/${KERNELRELEASE}/source"
+
+ # Install the kernel
+ if [ "${ARCH}" = um ] ; then
++ mkdir -p "${pdir}/usr/lib/uml/modules"
++ mv "${pdir}/lib/modules/${KERNELRELEASE}" "${pdir}/usr/lib/uml/modules/${KERNELRELEASE}"
+ mkdir -p "${pdir}/usr/bin" "${pdir}/usr/share/doc/${pname}"
+ cp System.map "${pdir}/usr/lib/uml/modules/${KERNELRELEASE}/System.map"
+ cp ${KCONFIG_CONFIG} "${pdir}/usr/share/doc/${pname}/config"
+--
+2.39.2
+
--- /dev/null
+From d7dc1948d9b7f5be4e9139691ecb8f2724f6d34b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Jun 2023 00:11:43 +0000
+Subject: kbuild: Disable GCOV for *.mod.o
+
+From: Sami Tolvanen <samitolvanen@google.com>
+
+[ Upstream commit 25a21fbb934a0d989e1858f83c2ddf4cfb2ebe30 ]
+
+With GCOV_PROFILE_ALL, Clang injects __llvm_gcov_* functions to each
+object file, including the *.mod.o. As we filter out CC_FLAGS_CFI
+for *.mod.o, the compiler won't generate type hashes for the
+injected functions, and therefore indirectly calling them during
+module loading trips indirect call checking.
+
+Enabling CFI for *.mod.o isn't sufficient to fix this issue after
+commit 0c3e806ec0f9 ("x86/cfi: Add boot time hash randomization"),
+as *.mod.o aren't processed by objtool, which means any hashes
+emitted there won't be randomized. Therefore, in addition to
+disabling CFI for *.mod.o, also disable GCOV, as the object files
+don't otherwise contain any executable code.
+
+Fixes: cf68fffb66d6 ("add support for Clang CFI")
+Reported-by: Joe Fradley <joefradley@google.com>
+Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/Makefile.modfinal | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
+index 4703f652c0098..fc19f67039bda 100644
+--- a/scripts/Makefile.modfinal
++++ b/scripts/Makefile.modfinal
+@@ -23,7 +23,7 @@ modname = $(notdir $(@:.mod.o=))
+ part-of-module = y
+
+ quiet_cmd_cc_o_c = CC [M] $@
+- cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI), $(c_flags)) -c -o $@ $<
++ cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI) $(CFLAGS_GCOV), $(c_flags)) -c -o $@ $<
+
+ %.mod.o: %.mod.c FORCE
+ $(call if_changed_dep,cc_o_c)
+--
+2.39.2
+
--- /dev/null
+From f5609f101f394cff41002f037e49910133a1234a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Jun 2023 00:11:42 +0000
+Subject: kbuild: Fix CFI failures with GCOV
+
+From: Sami Tolvanen <samitolvanen@google.com>
+
+[ Upstream commit ddf56288eebd1fe82c46fc9f693b5b18045cddb6 ]
+
+With GCOV_PROFILE_ALL, Clang injects __llvm_gcov_* functions to
+each object file, and the functions are indirectly called during
+boot. However, when code is injected to object files that are not
+part of vmlinux.o, it's also not processed by objtool, which breaks
+CFI hash randomization as the hashes in these files won't be
+included in the .cfi_sites section and thus won't be randomized.
+
+Similarly to commit 42633ed852de ("kbuild: Fix CFI hash
+randomization with KASAN"), disable GCOV for .vmlinux.export.o and
+init/version-timestamp.o to avoid emitting unnecessary functions to
+object files that don't otherwise have executable code.
+
+Fixes: 0c3e806ec0f9 ("x86/cfi: Add boot time hash randomization")
+Reported-by: Joe Fradley <joefradley@google.com>
+Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ init/Makefile | 1 +
+ scripts/Makefile.vmlinux | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/init/Makefile b/init/Makefile
+index 26de459006c4e..ec557ada3c12e 100644
+--- a/init/Makefile
++++ b/init/Makefile
+@@ -60,3 +60,4 @@ include/generated/utsversion.h: FORCE
+ $(obj)/version-timestamp.o: include/generated/utsversion.h
+ CFLAGS_version-timestamp.o := -include include/generated/utsversion.h
+ KASAN_SANITIZE_version-timestamp.o := n
++GCOV_PROFILE_version-timestamp.o := n
+diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux
+index 10176dec97eac..3cd6ca15f390d 100644
+--- a/scripts/Makefile.vmlinux
++++ b/scripts/Makefile.vmlinux
+@@ -19,6 +19,7 @@ quiet_cmd_cc_o_c = CC $@
+
+ ifdef CONFIG_MODULES
+ KASAN_SANITIZE_.vmlinux.export.o := n
++GCOV_PROFILE_.vmlinux.export.o := n
+ targets += .vmlinux.export.o
+ vmlinux: .vmlinux.export.o
+ endif
+--
+2.39.2
+
--- /dev/null
+From 508d0f46b9f2c26a247d10e494b0bd6629ee4739 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 17:31:17 +0200
+Subject: kcsan: Don't expect 64 bits atomic builtins from 32 bits
+ architectures
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 353e7300a1db928e427462f2745f9a2cd1625b3d ]
+
+Activating KCSAN on a 32 bits architecture leads to the following
+link-time failure:
+
+ LD .tmp_vmlinux.kallsyms1
+ powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_load':
+ kernel/kcsan/core.c:1273: undefined reference to `__atomic_load_8'
+ powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_store':
+ kernel/kcsan/core.c:1273: undefined reference to `__atomic_store_8'
+ powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_exchange':
+ kernel/kcsan/core.c:1273: undefined reference to `__atomic_exchange_8'
+ powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_add':
+ kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_add_8'
+ powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_sub':
+ kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_sub_8'
+ powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_and':
+ kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_and_8'
+ powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_or':
+ kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_or_8'
+ powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_xor':
+ kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_xor_8'
+ powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_nand':
+ kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_nand_8'
+ powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_compare_exchange_strong':
+ kernel/kcsan/core.c:1273: undefined reference to `__atomic_compare_exchange_8'
+ powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_compare_exchange_weak':
+ kernel/kcsan/core.c:1273: undefined reference to `__atomic_compare_exchange_8'
+ powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_compare_exchange_val':
+ kernel/kcsan/core.c:1273: undefined reference to `__atomic_compare_exchange_8'
+
+32 bits architectures don't have 64 bits atomic builtins. Only
+include DEFINE_TSAN_ATOMIC_OPS(64) on 64 bits architectures.
+
+Fixes: 0f8ad5f2e934 ("kcsan: Add support for atomic builtins")
+Suggested-by: Marco Elver <elver@google.com>
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Reviewed-by: Marco Elver <elver@google.com>
+Acked-by: Marco Elver <elver@google.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/d9c6afc28d0855240171a4e0ad9ffcdb9d07fceb.1683892665.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/kcsan/core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c
+index 5a60cc52adc0c..8a7baf4e332e3 100644
+--- a/kernel/kcsan/core.c
++++ b/kernel/kcsan/core.c
+@@ -1270,7 +1270,9 @@ static __always_inline void kcsan_atomic_builtin_memorder(int memorder)
+ DEFINE_TSAN_ATOMIC_OPS(8);
+ DEFINE_TSAN_ATOMIC_OPS(16);
+ DEFINE_TSAN_ATOMIC_OPS(32);
++#ifdef CONFIG_64BIT
+ DEFINE_TSAN_ATOMIC_OPS(64);
++#endif
+
+ void __tsan_atomic_thread_fence(int memorder);
+ void __tsan_atomic_thread_fence(int memorder)
+--
+2.39.2
+
--- /dev/null
+From ffe066b29bafc9e9f8f36cb8522fa991ec530042 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 May 2023 20:34:34 +0800
+Subject: kexec: fix a memory leak in crash_shrink_memory()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit 1cba6c4309f03de570202c46f03df3f73a0d4c82 ]
+
+Patch series "kexec: enable kexec_crash_size to support two crash kernel
+regions".
+
+When crashkernel=X fails to reserve region under 4G, it will fall back to
+reserve region above 4G and a region of the default size will also be
+reserved under 4G. Unfortunately, /sys/kernel/kexec_crash_size only
+supports one crash kernel region now, the user cannot sense the low memory
+reserved by reading /sys/kernel/kexec_crash_size. Also, low memory cannot
+be freed by writing this file.
+
+For example:
+resource_size(crashk_res) = 512M
+resource_size(crashk_low_res) = 256M
+
+The result of 'cat /sys/kernel/kexec_crash_size' is 512M, but it should be
+768M. When we execute 'echo 0 > /sys/kernel/kexec_crash_size', the size
+of crashk_res becomes 0 and resource_size(crashk_low_res) is still 256 MB,
+which is incorrect.
+
+Since crashk_res manages the memory with high address and crashk_low_res
+manages the memory with low address, crashk_low_res is shrunken only when
+all crashk_res is shrunken. And because when there is only one crash
+kernel region, crashk_res is always used. Therefore, if all crashk_res is
+shrunken and crashk_low_res still exists, swap them.
+
+This patch (of 6):
+
+If the value of parameter 'new_size' is in the semi-open and semi-closed
+interval (crashk_res.end - KEXEC_CRASH_MEM_ALIGN + 1, crashk_res.end], the
+calculation result of ram_res is:
+
+ ram_res->start = crashk_res.end + 1
+ ram_res->end = crashk_res.end
+
+The operation of insert_resource() fails, and ram_res is not added to
+iomem_resource. As a result, the memory of the control block ram_res is
+leaked.
+
+In fact, on all architectures, the start address and size of crashk_res
+are already aligned by KEXEC_CRASH_MEM_ALIGN. Therefore, we do not need
+to round up crashk_res.start again. Instead, we should round up
+'new_size' in advance.
+
+Link: https://lkml.kernel.org/r/20230527123439.772-1-thunder.leizhen@huawei.com
+Link: https://lkml.kernel.org/r/20230527123439.772-2-thunder.leizhen@huawei.com
+Fixes: 6480e5a09237 ("kdump: add missing RAM resource in crash_shrink_memory()")
+Fixes: 06a7f711246b ("kexec: premit reduction of the reserved memory size")
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Acked-by: Baoquan He <bhe@redhat.com>
+Cc: Cong Wang <amwang@redhat.com>
+Cc: Eric W. Biederman <ebiederm@xmission.com>
+Cc: Michael Holzheu <holzheu@linux.vnet.ibm.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/kexec_core.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
+index 3d578c6fefee3..22acee18195a5 100644
+--- a/kernel/kexec_core.c
++++ b/kernel/kexec_core.c
+@@ -1122,6 +1122,7 @@ int crash_shrink_memory(unsigned long new_size)
+ start = crashk_res.start;
+ end = crashk_res.end;
+ old_size = (end == 0) ? 0 : end - start + 1;
++ new_size = roundup(new_size, KEXEC_CRASH_MEM_ALIGN);
+ if (new_size >= old_size) {
+ ret = (new_size == old_size) ? 0 : -EINVAL;
+ goto unlock;
+@@ -1133,9 +1134,7 @@ int crash_shrink_memory(unsigned long new_size)
+ goto unlock;
+ }
+
+- start = roundup(start, KEXEC_CRASH_MEM_ALIGN);
+- end = roundup(start + new_size, KEXEC_CRASH_MEM_ALIGN);
+-
++ end = start + new_size;
+ crash_free_reserved_phys_range(end, crashk_res.end);
+
+ if ((start == end) && (crashk_res.parent != NULL))
+--
+2.39.2
+
--- /dev/null
+From b2f12411944a4b3047546871a0e226a77843eead Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 11:47:43 +0100
+Subject: kselftest: vDSO: Fix accumulation of uninitialized ret when
+ CLOCK_REALTIME is undefined
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+[ Upstream commit 375b9ff53cb6f9c042817b75f2be0a650626dc4f ]
+
+In the unlikely case that CLOCK_REALTIME is not defined, variable ret is
+not initialized and further accumulation of return values to ret can leave
+ret in an undefined state. Fix this by initialized ret to zero and changing
+the assignment of ret to an accumulation for the CLOCK_REALTIME case.
+
+Fixes: 03f55c7952c9 ("kselftest: Extend vDSO selftest to clock_getres")
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/vDSO/vdso_test_clock_getres.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/vDSO/vdso_test_clock_getres.c b/tools/testing/selftests/vDSO/vdso_test_clock_getres.c
+index 15dcee16ff726..38d46a8bf7cba 100644
+--- a/tools/testing/selftests/vDSO/vdso_test_clock_getres.c
++++ b/tools/testing/selftests/vDSO/vdso_test_clock_getres.c
+@@ -84,12 +84,12 @@ static inline int vdso_test_clock(unsigned int clock_id)
+
+ int main(int argc, char **argv)
+ {
+- int ret;
++ int ret = 0;
+
+ #if _POSIX_TIMERS > 0
+
+ #ifdef CLOCK_REALTIME
+- ret = vdso_test_clock(CLOCK_REALTIME);
++ ret += vdso_test_clock(CLOCK_REALTIME);
+ #endif
+
+ #ifdef CLOCK_BOOTTIME
+--
+2.39.2
+
--- /dev/null
+From 818caef83253d97cb2802ac4927b799b52b5e436 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 10:19:38 +0200
+Subject: ksmbd: avoid field overflow warning
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 9cedc58bdbe9fff9aacd0ca19ee5777659f28fd7 ]
+
+clang warns about a possible field overflow in a memcpy:
+
+In file included from fs/smb/server/smb_common.c:7:
+include/linux/fortify-string.h:583:4: error: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
+ __write_overflow_field(p_size_field, size);
+
+It appears to interpret the "&out[baselen + 4]" as referring to a single
+byte of the character array, while the equivalen "out + baselen + 4" is
+seen as an offset into the array.
+
+I don't see that kind of warning elsewhere, so just go with the simple
+rework.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ksmbd/smb_common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ksmbd/smb_common.c b/fs/ksmbd/smb_common.c
+index 569e5eecdf3db..3e391a7d5a3ab 100644
+--- a/fs/ksmbd/smb_common.c
++++ b/fs/ksmbd/smb_common.c
+@@ -536,7 +536,7 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname,
+ out[baselen + 3] = PERIOD;
+
+ if (dot_present)
+- memcpy(&out[baselen + 4], extension, 4);
++ memcpy(out + baselen + 4, extension, 4);
+ else
+ out[baselen + 4] = '\0';
+ smbConvertToUTF16((__le16 *)shortname, out, PATH_MAX,
+--
+2.39.2
+
--- /dev/null
+From d288f6cdd4c9be3bbe50fae947f6f74f7153d737 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 20:06:57 +0100
+Subject: lib/ts_bm: reset initial match offset for every block of text
+
+From: Jeremy Sowden <jeremy@azazel.net>
+
+[ Upstream commit 6f67fbf8192da80c4db01a1800c7fceaca9cf1f9 ]
+
+The `shift` variable which indicates the offset in the string at which
+to start matching the pattern is initialized to `bm->patlen - 1`, but it
+is not reset when a new block is retrieved. This means the implemen-
+tation may start looking at later and later positions in each successive
+block and miss occurrences of the pattern at the beginning. E.g.,
+consider a HTTP packet held in a non-linear skb, where the HTTP request
+line occurs in the second block:
+
+ [... 52 bytes of packet headers ...]
+ GET /bmtest HTTP/1.1\r\nHost: www.example.com\r\n\r\n
+
+and the pattern is "GET /bmtest".
+
+Once the first block comprising the packet headers has been examined,
+`shift` will be pointing to somewhere near the end of the block, and so
+when the second block is examined the request line at the beginning will
+be missed.
+
+Reinitialize the variable for each new block.
+
+Fixes: 8082e4ed0a61 ("[LIB]: Boyer-Moore extension for textsearch infrastructure strike #2")
+Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1390
+Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/ts_bm.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/lib/ts_bm.c b/lib/ts_bm.c
+index 1f2234221dd11..c8ecbf74ef295 100644
+--- a/lib/ts_bm.c
++++ b/lib/ts_bm.c
+@@ -60,10 +60,12 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state)
+ struct ts_bm *bm = ts_config_priv(conf);
+ unsigned int i, text_len, consumed = state->offset;
+ const u8 *text;
+- int shift = bm->patlen - 1, bs;
++ int bs;
+ const u8 icase = conf->flags & TS_IGNORECASE;
+
+ for (;;) {
++ int shift = bm->patlen - 1;
++
+ text_len = conf->get_next_block(consumed, &text, conf, state);
+
+ if (unlikely(text_len == 0))
+--
+2.39.2
+
--- /dev/null
+From c11218ea99f4b6734a559b481599e42b8fccd057 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Apr 2023 18:36:38 -0700
+Subject: libbpf: btf_dump_type_data_check_overflow needs to consider
+ BTF_MEMBER_BITFIELD_SIZE
+
+From: Martin KaFai Lau <martin.lau@kernel.org>
+
+[ Upstream commit c39028b333f3a3a765c5c0b9726b8e38aedf0ba1 ]
+
+The btf_dump/struct_data selftest is failing with:
+
+ [...]
+ test_btf_dump_struct_data:FAIL:unexpected return value dumping fs_context unexpected unexpected return value dumping fs_context: actual -7 != expected 264
+ [...]
+
+The reason is in btf_dump_type_data_check_overflow(). It does not use
+BTF_MEMBER_BITFIELD_SIZE from the struct's member (btf_member). Instead,
+it is using the enum size which is 4. It had been working till the recent
+commit 4e04143c869c ("fs_context: drop the unused lsm_flags member")
+removed an integer member which also removed the 4 bytes padding at the
+end of the fs_context. Missing this 4 bytes padding exposed this bug. In
+particular, when btf_dump_type_data_check_overflow() reaches the member
+'phase', -E2BIG is returned.
+
+The fix is to pass bit_sz to btf_dump_type_data_check_overflow(). In
+btf_dump_type_data_check_overflow(), it does a different size check when
+bit_sz is not zero.
+
+The current fs_context:
+
+[3600] ENUM 'fs_context_purpose' encoding=UNSIGNED size=4 vlen=3
+ 'FS_CONTEXT_FOR_MOUNT' val=0
+ 'FS_CONTEXT_FOR_SUBMOUNT' val=1
+ 'FS_CONTEXT_FOR_RECONFIGURE' val=2
+[3601] ENUM 'fs_context_phase' encoding=UNSIGNED size=4 vlen=7
+ 'FS_CONTEXT_CREATE_PARAMS' val=0
+ 'FS_CONTEXT_CREATING' val=1
+ 'FS_CONTEXT_AWAITING_MOUNT' val=2
+ 'FS_CONTEXT_AWAITING_RECONF' val=3
+ 'FS_CONTEXT_RECONF_PARAMS' val=4
+ 'FS_CONTEXT_RECONFIGURING' val=5
+ 'FS_CONTEXT_FAILED' val=6
+[3602] STRUCT 'fs_context' size=264 vlen=21
+ 'ops' type_id=3603 bits_offset=0
+ 'uapi_mutex' type_id=235 bits_offset=64
+ 'fs_type' type_id=872 bits_offset=1216
+ 'fs_private' type_id=21 bits_offset=1280
+ 'sget_key' type_id=21 bits_offset=1344
+ 'root' type_id=781 bits_offset=1408
+ 'user_ns' type_id=251 bits_offset=1472
+ 'net_ns' type_id=984 bits_offset=1536
+ 'cred' type_id=1785 bits_offset=1600
+ 'log' type_id=3621 bits_offset=1664
+ 'source' type_id=42 bits_offset=1792
+ 'security' type_id=21 bits_offset=1856
+ 's_fs_info' type_id=21 bits_offset=1920
+ 'sb_flags' type_id=20 bits_offset=1984
+ 'sb_flags_mask' type_id=20 bits_offset=2016
+ 's_iflags' type_id=20 bits_offset=2048
+ 'purpose' type_id=3600 bits_offset=2080 bitfield_size=8
+ 'phase' type_id=3601 bits_offset=2088 bitfield_size=8
+ 'need_free' type_id=67 bits_offset=2096 bitfield_size=1
+ 'global' type_id=67 bits_offset=2097 bitfield_size=1
+ 'oldapi' type_id=67 bits_offset=2098 bitfield_size=1
+
+Fixes: 920d16af9b42 ("libbpf: BTF dumper support for typed data")
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Yonghong Song <yhs@fb.com>
+Link: https://lore.kernel.org/bpf/20230428013638.1581263-1-martin.lau@linux.dev
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/btf_dump.c | 22 +++++++++++++++++++---
+ 1 file changed, 19 insertions(+), 3 deletions(-)
+
+diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
+index 580985ee55458..4d9f30bf7f014 100644
+--- a/tools/lib/bpf/btf_dump.c
++++ b/tools/lib/bpf/btf_dump.c
+@@ -2250,9 +2250,25 @@ static int btf_dump_type_data_check_overflow(struct btf_dump *d,
+ const struct btf_type *t,
+ __u32 id,
+ const void *data,
+- __u8 bits_offset)
++ __u8 bits_offset,
++ __u8 bit_sz)
+ {
+- __s64 size = btf__resolve_size(d->btf, id);
++ __s64 size;
++
++ if (bit_sz) {
++ /* bits_offset is at most 7. bit_sz is at most 128. */
++ __u8 nr_bytes = (bits_offset + bit_sz + 7) / 8;
++
++ /* When bit_sz is non zero, it is called from
++ * btf_dump_struct_data() where it only cares about
++ * negative error value.
++ * Return nr_bytes in success case to make it
++ * consistent as the regular integer case below.
++ */
++ return data + nr_bytes > d->typed_dump->data_end ? -E2BIG : nr_bytes;
++ }
++
++ size = btf__resolve_size(d->btf, id);
+
+ if (size < 0 || size >= INT_MAX) {
+ pr_warn("unexpected size [%zu] for id [%u]\n",
+@@ -2407,7 +2423,7 @@ static int btf_dump_dump_type_data(struct btf_dump *d,
+ {
+ int size, err = 0;
+
+- size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset);
++ size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset, bit_sz);
+ if (size < 0)
+ return size;
+ err = btf_dump_type_data_check_zero(d, t, id, data, bits_offset, bit_sz);
+--
+2.39.2
+
--- /dev/null
+From d5f89173360cf7635dde0472ac4af52ec53c9973 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 May 2023 23:55:02 -0700
+Subject: libbpf: fix offsetof() and container_of() to work with CO-RE
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit bdeeed3498c7871c17465bb4f11d1bc67f9098af ]
+
+It seems like __builtin_offset() doesn't preserve CO-RE field
+relocations properly. So if offsetof() macro is defined through
+__builtin_offset(), CO-RE-enabled BPF code using container_of() will be
+subtly and silently broken.
+
+To avoid this problem, redefine offsetof() and container_of() in the
+form that works with CO-RE relocations more reliably.
+
+Fixes: 5fbc220862fc ("tools/libpf: Add offsetof/container_of macro in bpf_helpers.h")
+Reported-by: Lennart Poettering <lennart@poettering.net>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Yonghong Song <yhs@fb.com>
+Link: https://lore.kernel.org/r/20230509065502.2306180-1-andrii@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/bpf_helpers.h | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h
+index 5ec1871acb2fc..85a29cd69154e 100644
+--- a/tools/lib/bpf/bpf_helpers.h
++++ b/tools/lib/bpf/bpf_helpers.h
+@@ -77,16 +77,21 @@
+ /*
+ * Helper macros to manipulate data structures
+ */
+-#ifndef offsetof
+-#define offsetof(TYPE, MEMBER) ((unsigned long)&((TYPE *)0)->MEMBER)
+-#endif
+-#ifndef container_of
++
++/* offsetof() definition that uses __builtin_offset() might not preserve field
++ * offset CO-RE relocation properly, so force-redefine offsetof() using
++ * old-school approach which works with CO-RE correctly
++ */
++#undef offsetof
++#define offsetof(type, member) ((unsigned long)&((type *)0)->member)
++
++/* redefined container_of() to ensure we use the above offsetof() macro */
++#undef container_of
+ #define container_of(ptr, type, member) \
+ ({ \
+ void *__mptr = (void *)(ptr); \
+ ((type *)(__mptr - offsetof(type, member))); \
+ })
+-#endif
+
+ /*
+ * Compiler (optimization) barrier.
+--
+2.39.2
+
--- /dev/null
+From 44e5d05a1217133f3b4d08aeab0fa7a1d6176240 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Jun 2023 07:14:14 +1000
+Subject: lockd: drop inappropriate svc_get() from locked_get()
+
+From: NeilBrown <neilb@suse.de>
+
+[ Upstream commit 665e89ab7c5af1f2d260834c861a74b01a30f95f ]
+
+The below-mentioned patch was intended to simplify refcounting on the
+svc_serv used by locked. The goal was to only ever have a single
+reference from the single thread. To that end we dropped a call to
+lockd_start_svc() (except when creating thread) which would take a
+reference, and dropped the svc_put(serv) that would drop that reference.
+
+Unfortunately we didn't also remove the svc_get() from
+lockd_create_svc() in the case where the svc_serv already existed.
+So after the patch:
+ - on the first call the svc_serv was allocated and the one reference
+ was given to the thread, so there are no extra references
+ - on subsequent calls svc_get() was called so there is now an extra
+ reference.
+This is clearly not consistent.
+
+The inconsistency is also clear in the current code in lockd_get()
+takes *two* references, one on nlmsvc_serv and one by incrementing
+nlmsvc_users. This clearly does not match lockd_put().
+
+So: drop that svc_get() from lockd_get() (which used to be in
+lockd_create_svc().
+
+Reported-by: Ido Schimmel <idosch@idosch.org>
+Closes: https://lore.kernel.org/linux-nfs/ZHsI%2FH16VX9kJQX1@shredder/T/#u
+Fixes: b73a2972041b ("lockd: move lockd_start_svc() call into lockd_create_svc()")
+Signed-off-by: NeilBrown <neilb@suse.de>
+Tested-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/lockd/svc.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
+index 9a47303b2cba6..0c05668019c2b 100644
+--- a/fs/lockd/svc.c
++++ b/fs/lockd/svc.c
+@@ -355,7 +355,6 @@ static int lockd_get(void)
+ int error;
+
+ if (nlmsvc_serv) {
+- svc_get(nlmsvc_serv);
+ nlmsvc_users++;
+ return 0;
+ }
+--
+2.39.2
+
--- /dev/null
+From ab056ecb4786a2def4b4da7d6dbe998f5e2bfe05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 08:00:58 +0100
+Subject: locking/atomic: arm: fix sync ops
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit dda5f312bb09e56e7a1c3e3851f2000eb2e9c879 ]
+
+The sync_*() ops on arch/arm are defined in terms of the regular bitops
+with no special handling. This is not correct, as UP kernels elide
+barriers for the fully-ordered operations, and so the required ordering
+is lost when such UP kernels are run under a hypervsior on an SMP
+system.
+
+Fix this by defining sync ops with the required barriers.
+
+Note: On 32-bit arm, the sync_*() ops are currently only used by Xen,
+which requires ARMv7, but the semantics can be implemented for ARMv6+.
+
+Fixes: e54d2f61528165bb ("xen/arm: sync_bitops")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20230605070124.3741859-2-mark.rutland@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/include/asm/assembler.h | 17 +++++++++++++++++
+ arch/arm/include/asm/sync_bitops.h | 29 +++++++++++++++++++++++++----
+ arch/arm/lib/bitops.h | 14 +++++++++++---
+ arch/arm/lib/testchangebit.S | 4 ++++
+ arch/arm/lib/testclearbit.S | 4 ++++
+ arch/arm/lib/testsetbit.S | 4 ++++
+ 6 files changed, 65 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
+index 505a306e0271a..aebe2c8f6a686 100644
+--- a/arch/arm/include/asm/assembler.h
++++ b/arch/arm/include/asm/assembler.h
+@@ -394,6 +394,23 @@ ALT_UP_B(.L0_\@)
+ #endif
+ .endm
+
++/*
++ * Raw SMP data memory barrier
++ */
++ .macro __smp_dmb mode
++#if __LINUX_ARM_ARCH__ >= 7
++ .ifeqs "\mode","arm"
++ dmb ish
++ .else
++ W(dmb) ish
++ .endif
++#elif __LINUX_ARM_ARCH__ == 6
++ mcr p15, 0, r0, c7, c10, 5 @ dmb
++#else
++ .error "Incompatible SMP platform"
++#endif
++ .endm
++
+ #if defined(CONFIG_CPU_V7M)
+ /*
+ * setmode is used to assert to be in svc mode during boot. For v7-M
+diff --git a/arch/arm/include/asm/sync_bitops.h b/arch/arm/include/asm/sync_bitops.h
+index 6f5d627c44a3c..f46b3c570f92e 100644
+--- a/arch/arm/include/asm/sync_bitops.h
++++ b/arch/arm/include/asm/sync_bitops.h
+@@ -14,14 +14,35 @@
+ * ops which are SMP safe even on a UP kernel.
+ */
+
++/*
++ * Unordered
++ */
++
+ #define sync_set_bit(nr, p) _set_bit(nr, p)
+ #define sync_clear_bit(nr, p) _clear_bit(nr, p)
+ #define sync_change_bit(nr, p) _change_bit(nr, p)
+-#define sync_test_and_set_bit(nr, p) _test_and_set_bit(nr, p)
+-#define sync_test_and_clear_bit(nr, p) _test_and_clear_bit(nr, p)
+-#define sync_test_and_change_bit(nr, p) _test_and_change_bit(nr, p)
+ #define sync_test_bit(nr, addr) test_bit(nr, addr)
+-#define arch_sync_cmpxchg arch_cmpxchg
+
++/*
++ * Fully ordered
++ */
++
++int _sync_test_and_set_bit(int nr, volatile unsigned long * p);
++#define sync_test_and_set_bit(nr, p) _sync_test_and_set_bit(nr, p)
++
++int _sync_test_and_clear_bit(int nr, volatile unsigned long * p);
++#define sync_test_and_clear_bit(nr, p) _sync_test_and_clear_bit(nr, p)
++
++int _sync_test_and_change_bit(int nr, volatile unsigned long * p);
++#define sync_test_and_change_bit(nr, p) _sync_test_and_change_bit(nr, p)
++
++#define arch_sync_cmpxchg(ptr, old, new) \
++({ \
++ __typeof__(*(ptr)) __ret; \
++ __smp_mb__before_atomic(); \
++ __ret = arch_cmpxchg_relaxed((ptr), (old), (new)); \
++ __smp_mb__after_atomic(); \
++ __ret; \
++})
+
+ #endif
+diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
+index 95bd359912889..f069d1b2318e6 100644
+--- a/arch/arm/lib/bitops.h
++++ b/arch/arm/lib/bitops.h
+@@ -28,7 +28,7 @@ UNWIND( .fnend )
+ ENDPROC(\name )
+ .endm
+
+- .macro testop, name, instr, store
++ .macro __testop, name, instr, store, barrier
+ ENTRY( \name )
+ UNWIND( .fnstart )
+ ands ip, r1, #3
+@@ -38,7 +38,7 @@ UNWIND( .fnstart )
+ mov r0, r0, lsr #5
+ add r1, r1, r0, lsl #2 @ Get word offset
+ mov r3, r2, lsl r3 @ create mask
+- smp_dmb
++ \barrier
+ #if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
+ .arch_extension mp
+ ALT_SMP(W(pldw) [r1])
+@@ -50,13 +50,21 @@ UNWIND( .fnstart )
+ strex ip, r2, [r1]
+ cmp ip, #0
+ bne 1b
+- smp_dmb
++ \barrier
+ cmp r0, #0
+ movne r0, #1
+ 2: bx lr
+ UNWIND( .fnend )
+ ENDPROC(\name )
+ .endm
++
++ .macro testop, name, instr, store
++ __testop \name, \instr, \store, smp_dmb
++ .endm
++
++ .macro sync_testop, name, instr, store
++ __testop \name, \instr, \store, __smp_dmb
++ .endm
+ #else
+ .macro bitop, name, instr
+ ENTRY( \name )
+diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S
+index 4ebecc67e6e04..f13fe9bc2399a 100644
+--- a/arch/arm/lib/testchangebit.S
++++ b/arch/arm/lib/testchangebit.S
+@@ -10,3 +10,7 @@
+ .text
+
+ testop _test_and_change_bit, eor, str
++
++#if __LINUX_ARM_ARCH__ >= 6
++sync_testop _sync_test_and_change_bit, eor, str
++#endif
+diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S
+index 009afa0f5b4a7..4d2c5ca620ebf 100644
+--- a/arch/arm/lib/testclearbit.S
++++ b/arch/arm/lib/testclearbit.S
+@@ -10,3 +10,7 @@
+ .text
+
+ testop _test_and_clear_bit, bicne, strne
++
++#if __LINUX_ARM_ARCH__ >= 6
++sync_testop _sync_test_and_clear_bit, bicne, strne
++#endif
+diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S
+index f3192e55acc87..649dbab65d8d0 100644
+--- a/arch/arm/lib/testsetbit.S
++++ b/arch/arm/lib/testsetbit.S
+@@ -10,3 +10,7 @@
+ .text
+
+ testop _test_and_set_bit, orreq, streq
++
++#if __LINUX_ARM_ARCH__ >= 6
++sync_testop _sync_test_and_set_bit, orreq, streq
++#endif
+--
+2.39.2
+
--- /dev/null
+From c1fd52156ecdcd41d05473d9c3a0002b3d1276c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 May 2023 21:11:01 +0800
+Subject: md/raid1-10: factor out a helper to add bio to plug
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 5ec6ca140a034682e421e2e808ef5ddfdfd65242 ]
+
+The code in raid1 and raid10 is identical, prepare to limit the number
+of plugged bios.
+
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230529131106.2123367-3-yukuai1@huaweicloud.com
+Stable-dep-of: 7db922bae3ab ("md/raid1-10: submit write io directly if bitmap is not enabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid1-10.c | 16 ++++++++++++++++
+ drivers/md/raid1.c | 12 +-----------
+ drivers/md/raid10.c | 11 +----------
+ 3 files changed, 18 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c
+index e61f6cad4e08e..9bf19a3409cef 100644
+--- a/drivers/md/raid1-10.c
++++ b/drivers/md/raid1-10.c
+@@ -109,3 +109,19 @@ static void md_bio_reset_resync_pages(struct bio *bio, struct resync_pages *rp,
+ size -= len;
+ } while (idx++ < RESYNC_PAGES && size > 0);
+ }
++
++static inline bool raid1_add_bio_to_plug(struct mddev *mddev, struct bio *bio,
++ blk_plug_cb_fn unplug)
++{
++ struct raid1_plug_cb *plug = NULL;
++ struct blk_plug_cb *cb = blk_check_plugged(unplug, mddev,
++ sizeof(*plug));
++
++ if (!cb)
++ return false;
++
++ plug = container_of(cb, struct raid1_plug_cb, cb);
++ bio_list_add(&plug->pending, bio);
++
++ return true;
++}
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index 68a9e2d9985b2..131d8fd5ccaab 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -1343,8 +1343,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
+ struct bitmap *bitmap = mddev->bitmap;
+ unsigned long flags;
+ struct md_rdev *blocked_rdev;
+- struct blk_plug_cb *cb;
+- struct raid1_plug_cb *plug = NULL;
+ int first_clone;
+ int max_sectors;
+ bool write_behind = false;
+@@ -1573,15 +1571,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
+ r1_bio->sector);
+ /* flush_pending_writes() needs access to the rdev so...*/
+ mbio->bi_bdev = (void *)rdev;
+-
+- cb = blk_check_plugged(raid1_unplug, mddev, sizeof(*plug));
+- if (cb)
+- plug = container_of(cb, struct raid1_plug_cb, cb);
+- else
+- plug = NULL;
+- if (plug) {
+- bio_list_add(&plug->pending, mbio);
+- } else {
++ if (!raid1_add_bio_to_plug(mddev, mbio, raid1_unplug)) {
+ spin_lock_irqsave(&conf->device_lock, flags);
+ bio_list_add(&conf->pending_bio_list, mbio);
+ spin_unlock_irqrestore(&conf->device_lock, flags);
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index 5af4e8aa08e96..a6cc066a86f09 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1288,8 +1288,6 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
+ const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
+ const blk_opf_t do_fua = bio->bi_opf & REQ_FUA;
+ unsigned long flags;
+- struct blk_plug_cb *cb;
+- struct raid1_plug_cb *plug = NULL;
+ struct r10conf *conf = mddev->private;
+ struct md_rdev *rdev;
+ int devnum = r10_bio->devs[n_copy].devnum;
+@@ -1329,14 +1327,7 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
+
+ atomic_inc(&r10_bio->remaining);
+
+- cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug));
+- if (cb)
+- plug = container_of(cb, struct raid1_plug_cb, cb);
+- else
+- plug = NULL;
+- if (plug) {
+- bio_list_add(&plug->pending, mbio);
+- } else {
++ if (!raid1_add_bio_to_plug(mddev, mbio, raid10_unplug)) {
+ spin_lock_irqsave(&conf->device_lock, flags);
+ bio_list_add(&conf->pending_bio_list, mbio);
+ spin_unlock_irqrestore(&conf->device_lock, flags);
+--
+2.39.2
+
--- /dev/null
+From 2052246e91d36cd2e7f1f4fc976a2558f552c181 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 May 2023 21:11:02 +0800
+Subject: md/raid1-10: factor out a helper to submit normal write
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 8295efbe68c080047e98d9c0eb5cb933b238a8cb ]
+
+There are multiple places to do the same thing, factor out a helper to
+prevent redundant code, and the helper will be used in following patch
+as well.
+
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230529131106.2123367-4-yukuai1@huaweicloud.com
+Stable-dep-of: 7db922bae3ab ("md/raid1-10: submit write io directly if bitmap is not enabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid1-10.c | 17 +++++++++++++++++
+ drivers/md/raid1.c | 13 ++-----------
+ drivers/md/raid10.c | 26 ++++----------------------
+ 3 files changed, 23 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c
+index 9bf19a3409cef..506299bd55cb6 100644
+--- a/drivers/md/raid1-10.c
++++ b/drivers/md/raid1-10.c
+@@ -110,6 +110,23 @@ static void md_bio_reset_resync_pages(struct bio *bio, struct resync_pages *rp,
+ } while (idx++ < RESYNC_PAGES && size > 0);
+ }
+
++
++static inline void raid1_submit_write(struct bio *bio)
++{
++ struct md_rdev *rdev = (struct md_rdev *)bio->bi_bdev;
++
++ bio->bi_next = NULL;
++ bio_set_dev(bio, rdev->bdev);
++ if (test_bit(Faulty, &rdev->flags))
++ bio_io_error(bio);
++ else if (unlikely(bio_op(bio) == REQ_OP_DISCARD &&
++ !bdev_max_discard_sectors(bio->bi_bdev)))
++ /* Just ignore it */
++ bio_endio(bio);
++ else
++ submit_bio_noacct(bio);
++}
++
+ static inline bool raid1_add_bio_to_plug(struct mddev *mddev, struct bio *bio,
+ blk_plug_cb_fn unplug)
+ {
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index 131d8fd5ccaab..e51b77a3a8397 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -799,17 +799,8 @@ static void flush_bio_list(struct r1conf *conf, struct bio *bio)
+
+ while (bio) { /* submit pending writes */
+ struct bio *next = bio->bi_next;
+- struct md_rdev *rdev = (void *)bio->bi_bdev;
+- bio->bi_next = NULL;
+- bio_set_dev(bio, rdev->bdev);
+- if (test_bit(Faulty, &rdev->flags)) {
+- bio_io_error(bio);
+- } else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
+- !bdev_max_discard_sectors(bio->bi_bdev)))
+- /* Just ignore it */
+- bio_endio(bio);
+- else
+- submit_bio_noacct(bio);
++
++ raid1_submit_write(bio);
+ bio = next;
+ cond_resched();
+ }
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index a6cc066a86f09..f2f7538dd2a68 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -917,17 +917,8 @@ static void flush_pending_writes(struct r10conf *conf)
+
+ while (bio) { /* submit pending writes */
+ struct bio *next = bio->bi_next;
+- struct md_rdev *rdev = (void*)bio->bi_bdev;
+- bio->bi_next = NULL;
+- bio_set_dev(bio, rdev->bdev);
+- if (test_bit(Faulty, &rdev->flags)) {
+- bio_io_error(bio);
+- } else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
+- !bdev_max_discard_sectors(bio->bi_bdev)))
+- /* Just ignore it */
+- bio_endio(bio);
+- else
+- submit_bio_noacct(bio);
++
++ raid1_submit_write(bio);
+ bio = next;
+ }
+ blk_finish_plug(&plug);
+@@ -1136,17 +1127,8 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
+
+ while (bio) { /* submit pending writes */
+ struct bio *next = bio->bi_next;
+- struct md_rdev *rdev = (void*)bio->bi_bdev;
+- bio->bi_next = NULL;
+- bio_set_dev(bio, rdev->bdev);
+- if (test_bit(Faulty, &rdev->flags)) {
+- bio_io_error(bio);
+- } else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
+- !bdev_max_discard_sectors(bio->bi_bdev)))
+- /* Just ignore it */
+- bio_endio(bio);
+- else
+- submit_bio_noacct(bio);
++
++ raid1_submit_write(bio);
+ bio = next;
+ }
+ kfree(plug);
+--
+2.39.2
+
--- /dev/null
+From f2feba212aa27bd286fc1b6c7c37c2e980aef786 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 May 2023 21:11:03 +0800
+Subject: md/raid1-10: submit write io directly if bitmap is not enabled
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 7db922bae3abdf0a1db81ef7228cc0b996a0c1e3 ]
+
+Commit 6cce3b23f6f8 ("[PATCH] md: write intent bitmap support for raid10")
+add bitmap support, and it changed that write io is submitted through
+daemon thread because bitmap need to be updated before write io. And
+later, plug is used to fix performance regression because all the write io
+will go to demon thread, which means io can't be issued concurrently.
+
+However, if bitmap is not enabled, the write io should not go to daemon
+thread in the first place, and plug is not needed as well.
+
+Fixes: 6cce3b23f6f8 ("[PATCH] md: write intent bitmap support for raid10")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230529131106.2123367-5-yukuai1@huaweicloud.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md-bitmap.c | 4 +---
+ drivers/md/md-bitmap.h | 7 +++++++
+ drivers/md/raid1-10.c | 13 +++++++++++--
+ 3 files changed, 19 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index 9640741e8d369..8bbeeec70905c 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -993,7 +993,6 @@ static int md_bitmap_file_test_bit(struct bitmap *bitmap, sector_t block)
+ return set;
+ }
+
+-
+ /* this gets called when the md device is ready to unplug its underlying
+ * (slave) device queues -- before we let any writes go down, we need to
+ * sync the dirty pages of the bitmap file to disk */
+@@ -1003,8 +1002,7 @@ void md_bitmap_unplug(struct bitmap *bitmap)
+ int dirty, need_write;
+ int writing = 0;
+
+- if (!bitmap || !bitmap->storage.filemap ||
+- test_bit(BITMAP_STALE, &bitmap->flags))
++ if (!md_bitmap_enabled(bitmap))
+ return;
+
+ /* look at each page to see if there are any set bits that need to be
+diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
+index cfd7395de8fd3..3a4750952b3a7 100644
+--- a/drivers/md/md-bitmap.h
++++ b/drivers/md/md-bitmap.h
+@@ -273,6 +273,13 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot,
+ sector_t *lo, sector_t *hi, bool clear_bits);
+ void md_bitmap_free(struct bitmap *bitmap);
+ void md_bitmap_wait_behind_writes(struct mddev *mddev);
++
++static inline bool md_bitmap_enabled(struct bitmap *bitmap)
++{
++ return bitmap && bitmap->storage.filemap &&
++ !test_bit(BITMAP_STALE, &bitmap->flags);
++}
++
+ #endif
+
+ #endif
+diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c
+index 506299bd55cb6..73cc3cb9154d8 100644
+--- a/drivers/md/raid1-10.c
++++ b/drivers/md/raid1-10.c
+@@ -131,9 +131,18 @@ static inline bool raid1_add_bio_to_plug(struct mddev *mddev, struct bio *bio,
+ blk_plug_cb_fn unplug)
+ {
+ struct raid1_plug_cb *plug = NULL;
+- struct blk_plug_cb *cb = blk_check_plugged(unplug, mddev,
+- sizeof(*plug));
++ struct blk_plug_cb *cb;
++
++ /*
++ * If bitmap is not enabled, it's safe to submit the io directly, and
++ * this can get optimal performance.
++ */
++ if (!md_bitmap_enabled(mddev->bitmap)) {
++ raid1_submit_write(bio);
++ return true;
++ }
+
++ cb = blk_check_plugged(unplug, mddev, sizeof(*plug));
+ if (!cb)
+ return false;
+
+--
+2.39.2
+
--- /dev/null
+From c23cb13dda922a4ee31ebb97afa8584498236bc1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 21:48:05 +0800
+Subject: md/raid10: check slab-out-of-bounds in md_bitmap_get_counter
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 301867b1c16805aebbc306aafa6ecdc68b73c7e5 ]
+
+If we write a large number to md/bitmap_set_bits, md_bitmap_checkpage()
+will return -EINVAL because 'page >= bitmap->pages', but the return value
+was not checked immediately in md_bitmap_get_counter() in order to set
+*blocks value and slab-out-of-bounds occurs.
+
+Move check of 'page >= bitmap->pages' to md_bitmap_get_counter() and
+return directly if true.
+
+Fixes: ef4256733506 ("md/bitmap: optimise scanning of empty bitmaps.")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230515134808.3936750-2-linan666@huaweicloud.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md-bitmap.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index e7cc6ba1b657f..9640741e8d369 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -54,14 +54,7 @@ __acquires(bitmap->lock)
+ {
+ unsigned char *mappage;
+
+- if (page >= bitmap->pages) {
+- /* This can happen if bitmap_start_sync goes beyond
+- * End-of-device while looking for a whole page.
+- * It is harmless.
+- */
+- return -EINVAL;
+- }
+-
++ WARN_ON_ONCE(page >= bitmap->pages);
+ if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */
+ return 0;
+
+@@ -1364,6 +1357,14 @@ __acquires(bitmap->lock)
+ sector_t csize;
+ int err;
+
++ if (page >= bitmap->pages) {
++ /*
++ * This can happen if bitmap_start_sync goes beyond
++ * End-of-device while looking for a whole page or
++ * user set a huge number to sysfs bitmap_set_bits.
++ */
++ return NULL;
++ }
+ err = md_bitmap_checkpage(bitmap, page, create, 0);
+
+ if (bitmap->bp[page].hijacked ||
+--
+2.39.2
+
--- /dev/null
+From dba7c922acdf60595ecaf33d9df56b71bf6dce5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 17:18:39 +0800
+Subject: md/raid10: fix io loss while replacement replace rdev
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 2ae6aaf76912bae53c74b191569d2ab484f24bf3 ]
+
+When removing a disk with replacement, the replacement will be used to
+replace rdev. During this process, there is a brief window in which both
+rdev and replacement are read as NULL in raid10_write_request(). This
+will result in io not being submitted but it should be.
+
+ //remove //write
+ raid10_remove_disk raid10_write_request
+ mirror->rdev = NULL
+ read rdev -> NULL
+ mirror->rdev = mirror->replacement
+ mirror->replacement = NULL
+ read replacement -> NULL
+
+Fix it by reading replacement first and rdev later, meanwhile, use smp_mb()
+to prevent memory reordering.
+
+Fixes: 475b0321a4df ("md/raid10: writes should get directed to replacement as well as original.")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230602091839.743798-3-linan666@huaweicloud.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid10.c | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index 7b5f26726b310..5af4e8aa08e96 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -779,8 +779,16 @@ static struct md_rdev *read_balance(struct r10conf *conf,
+ disk = r10_bio->devs[slot].devnum;
+ rdev = rcu_dereference(conf->mirrors[disk].replacement);
+ if (rdev == NULL || test_bit(Faulty, &rdev->flags) ||
+- r10_bio->devs[slot].addr + sectors > rdev->recovery_offset)
++ r10_bio->devs[slot].addr + sectors >
++ rdev->recovery_offset) {
++ /*
++ * Read replacement first to prevent reading both rdev
++ * and replacement as NULL during replacement replace
++ * rdev.
++ */
++ smp_mb();
+ rdev = rcu_dereference(conf->mirrors[disk].rdev);
++ }
+ if (rdev == NULL ||
+ test_bit(Faulty, &rdev->flags))
+ continue;
+@@ -1477,9 +1485,15 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
+
+ for (i = 0; i < conf->copies; i++) {
+ int d = r10_bio->devs[i].devnum;
+- struct md_rdev *rdev = rcu_dereference(conf->mirrors[d].rdev);
+- struct md_rdev *rrdev = rcu_dereference(
+- conf->mirrors[d].replacement);
++ struct md_rdev *rdev, *rrdev;
++
++ rrdev = rcu_dereference(conf->mirrors[d].replacement);
++ /*
++ * Read replacement first to prevent reading both rdev and
++ * replacement as NULL during replacement replace rdev.
++ */
++ smp_mb();
++ rdev = rcu_dereference(conf->mirrors[d].rdev);
+ if (rdev == rrdev)
+ rrdev = NULL;
+ if (rdev && (test_bit(Faulty, &rdev->flags)))
+--
+2.39.2
+
--- /dev/null
+From ab324850f143429621b1c1ba1d8d893dd10d4eed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 May 2023 15:22:15 +0800
+Subject: md/raid10: fix null-ptr-deref of mreplace in raid10_sync_request
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 34817a2441747b48e444cb0e05d84e14bc9443da ]
+
+There are two check of 'mreplace' in raid10_sync_request(). In the first
+check, 'need_replace' will be set and 'mreplace' will be used later if
+no-Faulty 'mreplace' exists, In the second check, 'mreplace' will be
+set to NULL if it is Faulty, but 'need_replace' will not be changed
+accordingly. null-ptr-deref occurs if Faulty is set between two check.
+
+Fix it by merging two checks into one. And replace 'need_replace' with
+'mreplace' because their values are always the same.
+
+Fixes: ee37d7314a32 ("md/raid10: Fix raid10 replace hang when new added disk faulty")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230527072218.2365857-2-linan666@huaweicloud.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid10.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index ea6967aeaa02a..7b5f26726b310 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -3436,7 +3436,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
+ int must_sync;
+ int any_working;
+ int need_recover = 0;
+- int need_replace = 0;
+ struct raid10_info *mirror = &conf->mirrors[i];
+ struct md_rdev *mrdev, *mreplace;
+
+@@ -3448,11 +3447,10 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
+ !test_bit(Faulty, &mrdev->flags) &&
+ !test_bit(In_sync, &mrdev->flags))
+ need_recover = 1;
+- if (mreplace != NULL &&
+- !test_bit(Faulty, &mreplace->flags))
+- need_replace = 1;
++ if (mreplace && test_bit(Faulty, &mreplace->flags))
++ mreplace = NULL;
+
+- if (!need_recover && !need_replace) {
++ if (!need_recover && !mreplace) {
+ rcu_read_unlock();
+ continue;
+ }
+@@ -3468,8 +3466,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
+ rcu_read_unlock();
+ continue;
+ }
+- if (mreplace && test_bit(Faulty, &mreplace->flags))
+- mreplace = NULL;
+ /* Unless we are doing a full sync, or a replacement
+ * we only need to recover the block if it is set in
+ * the bitmap
+@@ -3592,11 +3588,11 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
+ bio = r10_bio->devs[1].repl_bio;
+ if (bio)
+ bio->bi_end_io = NULL;
+- /* Note: if need_replace, then bio
++ /* Note: if replace is not NULL, then bio
+ * cannot be NULL as r10buf_pool_alloc will
+ * have allocated it.
+ */
+- if (!need_replace)
++ if (!mreplace)
+ break;
+ bio->bi_next = biolist;
+ biolist = bio;
+--
+2.39.2
+
--- /dev/null
+From d3e12d386d8480c2c3d6c6fef67c3f40e001ef5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 May 2023 15:25:33 +0800
+Subject: md/raid10: fix overflow of md/safe_mode_delay
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 6beb489b2eed25978523f379a605073f99240c50 ]
+
+There is no input check when echo md/safe_mode_delay in safe_delay_store().
+And msec might also overflow when HZ < 1000 in safe_delay_show(), Fix it by
+checking overflow in safe_delay_store() and use unsigned long conversion in
+safe_delay_show().
+
+Fixes: 72e02075a33f ("md: factor out parsing of fixed-point numbers")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230522072535.1523740-2-linan666@huaweicloud.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index d479e1656ef33..61ad7dfe0e99a 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -3814,8 +3814,9 @@ int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale)
+ static ssize_t
+ safe_delay_show(struct mddev *mddev, char *page)
+ {
+- int msec = (mddev->safemode_delay*1000)/HZ;
+- return sprintf(page, "%d.%03d\n", msec/1000, msec%1000);
++ unsigned int msec = ((unsigned long)mddev->safemode_delay*1000)/HZ;
++
++ return sprintf(page, "%u.%03u\n", msec/1000, msec%1000);
+ }
+ static ssize_t
+ safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len)
+@@ -3827,7 +3828,7 @@ safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len)
+ return -EINVAL;
+ }
+
+- if (strict_strtoul_scaled(cbuf, &msec, 3) < 0)
++ if (strict_strtoul_scaled(cbuf, &msec, 3) < 0 || msec > UINT_MAX / HZ)
+ return -EINVAL;
+ if (msec == 0)
+ mddev->safemode_delay = 0;
+--
+2.39.2
+
--- /dev/null
+From 059e8f3eba90b29636d14c3e6b1a8b9ea6feafb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 May 2023 15:25:34 +0800
+Subject: md/raid10: fix wrong setting of max_corr_read_errors
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit f8b20a405428803bd9881881d8242c9d72c6b2b2 ]
+
+There is no input check when echo md/max_read_errors and overflow might
+occur. Add check of input number.
+
+Fixes: 1e50915fe0bb ("raid: improve MD/raid10 handling of correctable read errors.")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230522072535.1523740-3-linan666@huaweicloud.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 61ad7dfe0e99a..2674cb1d699c0 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -4498,6 +4498,8 @@ max_corrected_read_errors_store(struct mddev *mddev, const char *buf, size_t len
+ rv = kstrtouint(buf, 10, &n);
+ if (rv < 0)
+ return rv;
++ if (n > INT_MAX)
++ return -EINVAL;
+ atomic_set(&mddev->max_corr_read_errors, n);
+ return len;
+ }
+--
+2.39.2
+
--- /dev/null
+From 0c7314363f1dff39c0bb8d4c2b93b500d5801ea5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 May 2023 13:29:31 +0200
+Subject: memory: brcmstb_dpfe: fix testing array offset after use
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 1d9e93fad549bc38f593147479ee063f2872c170 ]
+
+Code should first check for valid value of array offset, then use it as
+the index. Fixes smatch warning:
+
+ drivers/memory/brcmstb_dpfe.c:443 __send_command() error: testing array offset 'cmd' after use.
+
+Fixes: 2f330caff577 ("memory: brcmstb: Add driver for DPFE")
+Acked-by: Markus Mayer <mmayer@broadcom.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://lore.kernel.org/r/20230513112931.176066-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memory/brcmstb_dpfe.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/memory/brcmstb_dpfe.c b/drivers/memory/brcmstb_dpfe.c
+index 76c82e9c8fceb..9339f80b21c50 100644
+--- a/drivers/memory/brcmstb_dpfe.c
++++ b/drivers/memory/brcmstb_dpfe.c
+@@ -434,15 +434,17 @@ static void __finalize_command(struct brcmstb_dpfe_priv *priv)
+ static int __send_command(struct brcmstb_dpfe_priv *priv, unsigned int cmd,
+ u32 result[])
+ {
+- const u32 *msg = priv->dpfe_api->command[cmd];
+ void __iomem *regs = priv->regs;
+ unsigned int i, chksum, chksum_idx;
++ const u32 *msg;
+ int ret = 0;
+ u32 resp;
+
+ if (cmd >= DPFE_CMD_MAX)
+ return -1;
+
++ msg = priv->dpfe_api->command[cmd];
++
+ mutex_lock(&priv->lock);
+
+ /* Wait for DCPU to become ready */
+--
+2.39.2
+
--- /dev/null
+From ee790267f63e3345fce234c9f0204ed1acc84925 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 May 2023 22:27:04 +0200
+Subject: memstick r592: make memstick_debug_get_tpc_name() static
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 434587df9f7fd68575f99a889cc5f2efc2eaee5e ]
+
+There are no other files referencing this function, apparently
+it was left global to avoid an 'unused function' warning when
+the only caller is left out. With a 'W=1' build, it causes
+a 'missing prototype' warning though:
+
+drivers/memstick/host/r592.c:47:13: error: no previous prototype for 'memstick_debug_get_tpc_name' [-Werror=missing-prototypes]
+
+Annotate the function as 'static __maybe_unused' to avoid both
+problems.
+
+Fixes: 926341250102 ("memstick: add driver for Ricoh R5C592 card reader")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20230516202714.560929-1-arnd@kernel.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memstick/host/r592.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c
+index 42bfc46842b82..461f5ffd02bc1 100644
+--- a/drivers/memstick/host/r592.c
++++ b/drivers/memstick/host/r592.c
+@@ -44,12 +44,10 @@ static const char *tpc_names[] = {
+ * memstick_debug_get_tpc_name - debug helper that returns string for
+ * a TPC number
+ */
+-const char *memstick_debug_get_tpc_name(int tpc)
++static __maybe_unused const char *memstick_debug_get_tpc_name(int tpc)
+ {
+ return tpc_names[tpc-1];
+ }
+-EXPORT_SYMBOL(memstick_debug_get_tpc_name);
+-
+
+ /* Read a register*/
+ static inline u32 r592_read_reg(struct r592_device *dev, int address)
+--
+2.39.2
+
--- /dev/null
+From c09d5de46ff0dfae17e08e773698a9b12f3f78c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Jun 2023 16:56:36 +0200
+Subject: MIPS: DTS: CI20: Add parent supplies to ACT8600 regulators
+
+From: Paul Cercueil <paul@crapouillou.net>
+
+[ Upstream commit fbf1e42093f8d6346baf17079585fbcebb2ff284 ]
+
+Provide parent regulators to the ACT8600 regulators that need one.
+
+Signed-off-by: Paul Cercueil <paul@crapouillou.net>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Stable-dep-of: 944520f85d5b ("MIPS: DTS: CI20: Raise VDDCORE voltage to 1.125 volts")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/boot/dts/ingenic/ci20.dts | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
+index 2b1284c6c64a6..eac6b3411b5f7 100644
+--- a/arch/mips/boot/dts/ingenic/ci20.dts
++++ b/arch/mips/boot/dts/ingenic/ci20.dts
+@@ -242,16 +242,19 @@ regulators {
+ vddcore: DCDC1 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
++ vp1-supply = <&vcc_33v>;
+ regulator-always-on;
+ };
+ vddmem: DCDC2 {
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
++ vp2-supply = <&vcc_33v>;
+ regulator-always-on;
+ };
+ vcc_33: DCDC3 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
++ vp3-supply = <&vcc_33v>;
+ regulator-always-on;
+ };
+ vcc_50: SUDCDC_REG4 {
+@@ -262,21 +265,25 @@ vcc_50: SUDCDC_REG4 {
+ vcc_25: LDO5 {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
++ inl-supply = <&vcc_33v>;
+ regulator-always-on;
+ };
+ wifi_io: LDO6 {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
++ inl-supply = <&vcc_33v>;
+ regulator-always-on;
+ };
+ cim_io_28: LDO7 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
++ inl-supply = <&vcc_33v>;
+ regulator-always-on;
+ };
+ cim_io_15: LDO8 {
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
++ inl-supply = <&vcc_33v>;
+ regulator-always-on;
+ };
+ vrtc_18: LDO_REG9 {
+--
+2.39.2
+
--- /dev/null
+From d2e8263bfb8b59ad705442c2ba7e095a6ba37fbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Jun 2023 16:56:35 +0200
+Subject: MIPS: DTS: CI20: Fix ACT8600 regulator node names
+
+From: Paul Cercueil <paul@crapouillou.net>
+
+[ Upstream commit 08384e80a70fb1942510ab5f0ce27bad134e634e ]
+
+The Device Tree was using invalid node names for the ACT8600 regulators.
+To be fair, it is not the original committer's fault, as the
+documentation did gives invalid names as well.
+
+In theory, the fix should have been to modify the driver to accept the
+alternative names. However, even though the act8865 driver spits
+warnings, the kernel seemed to work fine with what is currently
+supported upstream. For that reason, I think it is okay to just update
+the DTS.
+
+I removed the "regulator-name" too, since they really didn't bring any
+information. The node names are enough.
+
+Fixes: 73f2b940474d ("MIPS: CI20: DTS: Add I2C nodes")
+Signed-off-by: Paul Cercueil <paul@crapouillou.net>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/boot/dts/ingenic/ci20.dts | 27 ++++++++-------------------
+ 1 file changed, 8 insertions(+), 19 deletions(-)
+
+diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
+index 239c4537484d0..2b1284c6c64a6 100644
+--- a/arch/mips/boot/dts/ingenic/ci20.dts
++++ b/arch/mips/boot/dts/ingenic/ci20.dts
+@@ -237,59 +237,49 @@ &i2c0 {
+ act8600: act8600@5a {
+ compatible = "active-semi,act8600";
+ reg = <0x5a>;
+- status = "okay";
+
+ regulators {
+- vddcore: SUDCDC1 {
+- regulator-name = "DCDC_REG1";
++ vddcore: DCDC1 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+- vddmem: SUDCDC2 {
+- regulator-name = "DCDC_REG2";
++ vddmem: DCDC2 {
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ };
+- vcc_33: SUDCDC3 {
+- regulator-name = "DCDC_REG3";
++ vcc_33: DCDC3 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+- vcc_50: SUDCDC4 {
+- regulator-name = "SUDCDC_REG4";
++ vcc_50: SUDCDC_REG4 {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+- vcc_25: LDO_REG5 {
+- regulator-name = "LDO_REG5";
++ vcc_25: LDO5 {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+- wifi_io: LDO_REG6 {
+- regulator-name = "LDO_REG6";
++ wifi_io: LDO6 {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+- vcc_28: LDO_REG7 {
+- regulator-name = "LDO_REG7";
++ cim_io_28: LDO7 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+- vcc_15: LDO_REG8 {
+- regulator-name = "LDO_REG8";
++ cim_io_15: LDO8 {
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ };
+ vrtc_18: LDO_REG9 {
+- regulator-name = "LDO_REG9";
+ /* Despite the datasheet stating 3.3V
+ * for REG9 and the driver expecting that,
+ * REG9 outputs 1.8V.
+@@ -303,7 +293,6 @@ vrtc_18: LDO_REG9 {
+ regulator-always-on;
+ };
+ vcc_11: LDO_REG10 {
+- regulator-name = "LDO_REG10";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+--
+2.39.2
+
--- /dev/null
+From 60c3161e643ed4367d99adc615e891957b16f6a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 19:59:34 +0200
+Subject: MIPS: DTS: CI20: Raise VDDCORE voltage to 1.125 volts
+
+From: Paul Cercueil <paul@crapouillou.net>
+
+[ Upstream commit 944520f85d5b1fb2f9ea243be41f9c9af3d4cef3 ]
+
+Commit 08384e80a70f ("MIPS: DTS: CI20: Fix ACT8600 regulator node
+names") caused the VDDCORE power supply (regulated by the ACT8600's
+DCDC1 output) to drop from a voltage of 1.2V configured by the
+bootloader, to the 1.1V set in the Device Tree.
+
+According to the documentation, the VDDCORE supply should be between
+0.99V and 1.21V; both values are therefore within the supported range.
+
+However, VDDCORE being 1.1V results in the CI20 being very unstable,
+with corrupted memory, failures to boot, or reboots at random. The
+reason might be succint drops of the voltage below the minimum required.
+
+Raising the minimum voltage to 1.125 volts seems to be enough to address
+this issue, while still keeping a relatively low core voltage which
+helps for power consumption and thermals.
+
+Fixes: 08384e80a70f ("MIPS: DTS: CI20: Fix ACT8600 regulator node names")
+Signed-off-by: Paul Cercueil <paul@crapouillou.net>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/boot/dts/ingenic/ci20.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
+index eac6b3411b5f7..c0f6c4d3618e1 100644
+--- a/arch/mips/boot/dts/ingenic/ci20.dts
++++ b/arch/mips/boot/dts/ingenic/ci20.dts
+@@ -240,8 +240,8 @@ act8600: act8600@5a {
+
+ regulators {
+ vddcore: DCDC1 {
+- regulator-min-microvolt = <1100000>;
+- regulator-max-microvolt = <1100000>;
++ regulator-min-microvolt = <1125000>;
++ regulator-max-microvolt = <1125000>;
+ vp1-supply = <&vcc_33v>;
+ regulator-always-on;
+ };
+--
+2.39.2
+
--- /dev/null
+From 39ba2bab2ee2436b4453c09511410398defca975 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 12:27:13 +0200
+Subject: mmc: Add MMC_QUIRK_BROKEN_SD_CACHE for Kingston Canvas Go Plus from
+ 11/2019
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit c467c8f081859d4f4ca4eee4fba54bb5d85d6c97 ]
+
+This microSD card never clears Flush Cache bit after cache flush has
+been started in sd_flush_cache(). This leads e.g. to failure to mount
+file system. Add a quirk which disables the SD cache for this specific
+card from specific manufacturing date of 11/2019, since on newer dated
+cards from 05/2023 the cache flush works correctly.
+
+Fixes: 08ebf903af57 ("mmc: core: Fixup support for writeback-cache for eMMC and SD")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Link: https://lore.kernel.org/r/20230620102713.7701-1-marex@denx.de
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/card.h | 30 +++++++++++++++++++++++-------
+ drivers/mmc/core/quirks.h | 13 +++++++++++++
+ drivers/mmc/core/sd.c | 2 +-
+ include/linux/mmc/card.h | 1 +
+ 4 files changed, 38 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h
+index cfdd1ff40b865..4edf9057fa79d 100644
+--- a/drivers/mmc/core/card.h
++++ b/drivers/mmc/core/card.h
+@@ -53,6 +53,10 @@ struct mmc_fixup {
+ unsigned int manfid;
+ unsigned short oemid;
+
++ /* Manufacturing date */
++ unsigned short year;
++ unsigned char month;
++
+ /* SDIO-specific fields. You can use SDIO_ANY_ID here of course */
+ u16 cis_vendor, cis_device;
+
+@@ -68,6 +72,8 @@ struct mmc_fixup {
+
+ #define CID_MANFID_ANY (-1u)
+ #define CID_OEMID_ANY ((unsigned short) -1)
++#define CID_YEAR_ANY ((unsigned short) -1)
++#define CID_MONTH_ANY ((unsigned char) -1)
+ #define CID_NAME_ANY (NULL)
+
+ #define EXT_CSD_REV_ANY (-1u)
+@@ -81,17 +87,21 @@ struct mmc_fixup {
+ #define CID_MANFID_APACER 0x27
+ #define CID_MANFID_KINGSTON 0x70
+ #define CID_MANFID_HYNIX 0x90
++#define CID_MANFID_KINGSTON_SD 0x9F
+ #define CID_MANFID_NUMONYX 0xFE
+
+ #define END_FIXUP { NULL }
+
+-#define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end, \
+- _cis_vendor, _cis_device, \
+- _fixup, _data, _ext_csd_rev) \
++#define _FIXUP_EXT(_name, _manfid, _oemid, _year, _month, \
++ _rev_start, _rev_end, \
++ _cis_vendor, _cis_device, \
++ _fixup, _data, _ext_csd_rev) \
+ { \
+ .name = (_name), \
+ .manfid = (_manfid), \
+ .oemid = (_oemid), \
++ .year = (_year), \
++ .month = (_month), \
+ .rev_start = (_rev_start), \
+ .rev_end = (_rev_end), \
+ .cis_vendor = (_cis_vendor), \
+@@ -103,8 +113,8 @@ struct mmc_fixup {
+
+ #define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end, \
+ _fixup, _data, _ext_csd_rev) \
+- _FIXUP_EXT(_name, _manfid, \
+- _oemid, _rev_start, _rev_end, \
++ _FIXUP_EXT(_name, _manfid, _oemid, CID_YEAR_ANY, CID_MONTH_ANY, \
++ _rev_start, _rev_end, \
+ SDIO_ANY_ID, SDIO_ANY_ID, \
+ _fixup, _data, _ext_csd_rev) \
+
+@@ -118,8 +128,9 @@ struct mmc_fixup {
+ _ext_csd_rev)
+
+ #define SDIO_FIXUP(_vendor, _device, _fixup, _data) \
+- _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, \
+- CID_OEMID_ANY, 0, -1ull, \
++ _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, CID_OEMID_ANY, \
++ CID_YEAR_ANY, CID_MONTH_ANY, \
++ 0, -1ull, \
+ _vendor, _device, \
+ _fixup, _data, EXT_CSD_REV_ANY) \
+
+@@ -264,4 +275,9 @@ static inline int mmc_card_broken_sd_discard(const struct mmc_card *c)
+ return c->quirks & MMC_QUIRK_BROKEN_SD_DISCARD;
+ }
+
++static inline int mmc_card_broken_sd_cache(const struct mmc_card *c)
++{
++ return c->quirks & MMC_QUIRK_BROKEN_SD_CACHE;
++}
++
+ #endif
+diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
+index 29b9497936df9..a7ffbc930ea9d 100644
+--- a/drivers/mmc/core/quirks.h
++++ b/drivers/mmc/core/quirks.h
+@@ -53,6 +53,15 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = {
+ MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_QUIRK_BLK_NO_CMD23),
+
++ /*
++ * Kingston Canvas Go! Plus microSD cards never finish SD cache flush.
++ * This has so far only been observed on cards from 11/2019, while new
++ * cards from 2023/05 do not exhibit this behavior.
++ */
++ _FIXUP_EXT("SD64G", CID_MANFID_KINGSTON_SD, 0x5449, 2019, 11,
++ 0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
++ MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
++
+ /*
+ * Some SD cards lockup while using CMD23 multiblock transfers.
+ */
+@@ -209,6 +218,10 @@ static inline void mmc_fixup_device(struct mmc_card *card,
+ if (f->of_compatible &&
+ !mmc_fixup_of_compatible_match(card, f->of_compatible))
+ continue;
++ if (f->year != CID_YEAR_ANY && f->year != card->cid.year)
++ continue;
++ if (f->month != CID_MONTH_ANY && f->month != card->cid.month)
++ continue;
+
+ dev_dbg(&card->dev, "calling %ps\n", f->vendor_fixup);
+ f->vendor_fixup(card, f->data);
+diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
+index 72b664ed90cf6..246ce027ae0aa 100644
+--- a/drivers/mmc/core/sd.c
++++ b/drivers/mmc/core/sd.c
+@@ -1170,7 +1170,7 @@ static int sd_parse_ext_reg_perf(struct mmc_card *card, u8 fno, u8 page,
+ card->ext_perf.feature_support |= SD_EXT_PERF_HOST_MAINT;
+
+ /* Cache support at bit 0. */
+- if (reg_buf[4] & BIT(0))
++ if ((reg_buf[4] & BIT(0)) && !mmc_card_broken_sd_cache(card))
+ card->ext_perf.feature_support |= SD_EXT_PERF_CACHE;
+
+ /* Command queue support indicated via queue depth bits (0 to 4). */
+diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
+index c726ea7812552..daa2f40d9ce65 100644
+--- a/include/linux/mmc/card.h
++++ b/include/linux/mmc/card.h
+@@ -294,6 +294,7 @@ struct mmc_card {
+ #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 */
++#define MMC_QUIRK_BROKEN_SD_CACHE (1<<15) /* Disable broken SD cache support */
+
+ bool reenable_cmdq; /* Re-enable Command Queue */
+
+--
+2.39.2
+
--- /dev/null
+From efd94e217f7e8c88d77e8a293b5683fd5224e139 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 May 2023 06:44:54 -0700
+Subject: mmc: mediatek: Avoid ugly error message when SDIO wakeup IRQ isn't
+ used
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit a3332b7aad346b14770797e03ddd02ebdb14db41 ]
+
+When I boot a kukui-kodama board, I see an ugly warning in my kernel
+log:
+ mtk-msdc 11240000.mmc: error -ENXIO: IRQ sdio_wakeup not found
+
+It's pretty normal not to have an "sdio_wakeup" IRQ defined. In fact,
+no device trees in mainline seem to have it. Let's use the
+platform_get_irq_byname_optional() to avoid the error message.
+
+Fixes: 527f36f5efa4 ("mmc: mediatek: add support for SDIO eint wakup IRQ")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Link: https://lore.kernel.org/r/20230510064434.1.I935404c5396e6bf952e99bb7ffb744c6f7fd430b@changeid
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/mtk-sd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index 9785ec91654f7..97c42aacaf346 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -2707,7 +2707,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
+
+ /* Support for SDIO eint irq ? */
+ if ((mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ) && (mmc->pm_caps & MMC_PM_KEEP_POWER)) {
+- host->eint_irq = platform_get_irq_byname(pdev, "sdio_wakeup");
++ host->eint_irq = platform_get_irq_byname_optional(pdev, "sdio_wakeup");
+ if (host->eint_irq > 0) {
+ host->pins_eint = pinctrl_lookup_state(host->pinctrl, "state_eint");
+ if (IS_ERR(host->pins_eint)) {
+--
+2.39.2
+
--- /dev/null
+From 6fd9c066ffede8981a3ffcc10508e242e6be2826 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Jun 2023 11:23:40 +0300
+Subject: modpost: fix off by one in is_executable_section()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 3a3f1e573a105328a2cca45a7cfbebabbf5e3192 ]
+
+The > comparison should be >= to prevent an out of bounds array
+access.
+
+Fixes: 52dc0595d540 ("modpost: handle relocations mismatch in __ex_table.")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/mod/modpost.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
+index 30d2ebc391f4a..b1163bad652aa 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -1296,7 +1296,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,
+
+ static int is_executable_section(struct elf_info* elf, unsigned int section_index)
+ {
+- if (section_index > elf->num_sections)
++ if (section_index >= elf->num_sections)
+ fatal("section_index is outside elf->num_sections!\n");
+
+ return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR);
+--
+2.39.2
+
--- /dev/null
+From 579c41027e512f385f2e028972282ed803e98825 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 21:09:56 +0900
+Subject: modpost: fix section mismatch message for R_ARM_{PC24,CALL,JUMP24}
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 56a24b8ce6a7f9c4a21b2276a8644f6f3d8fc14d ]
+
+addend_arm_rel() processes R_ARM_PC24, R_ARM_CALL, R_ARM_JUMP24 in a
+wrong way.
+
+Here, test code.
+
+[test code for R_ARM_JUMP24]
+
+ .section .init.text,"ax"
+ bar:
+ bx lr
+
+ .section .text,"ax"
+ .globl foo
+ foo:
+ b bar
+
+[test code for R_ARM_CALL]
+
+ .section .init.text,"ax"
+ bar:
+ bx lr
+
+ .section .text,"ax"
+ .globl foo
+ foo:
+ push {lr}
+ bl bar
+ pop {pc}
+
+If you compile it with ARM multi_v7_defconfig, modpost will show the
+symbol name, (unknown).
+
+ WARNING: modpost: vmlinux.o: section mismatch in reference: foo (section: .text) -> (unknown) (section: .init.text)
+
+(You need to use GNU linker instead of LLD to reproduce it.)
+
+Fix the code to make modpost show the correct symbol name.
+
+I imported (with adjustment) sign_extend32() from include/linux/bitops.h.
+
+The '+8' is the compensation for pc-relative instruction. It is
+documented in "ELF for the Arm Architecture" [1].
+
+ "If the relocation is pc-relative then compensation for the PC bias
+ (the PC value is 8 bytes ahead of the executing instruction in Arm
+ state and 4 bytes in Thumb state) must be encoded in the relocation
+ by the object producer."
+
+[1]: https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst
+
+Fixes: 56a974fa2d59 ("kbuild: make better section mismatch reports on arm")
+Fixes: 6e2e340b59d2 ("ARM: 7324/1: modpost: Fix section warnings for ARM for many compilers")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/mod/modpost.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
+index ff7a8df9e54cd..30d2ebc391f4a 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -1417,12 +1417,20 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
+ #define R_ARM_THM_JUMP19 51
+ #endif
+
++static int32_t sign_extend32(int32_t value, int index)
++{
++ uint8_t shift = 31 - index;
++
++ return (int32_t)(value << shift) >> shift;
++}
++
+ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
+ {
+ unsigned int r_typ = ELF_R_TYPE(r->r_info);
+ Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info);
+ void *loc = reloc_location(elf, sechdr, r);
+ uint32_t inst;
++ int32_t offset;
+
+ switch (r_typ) {
+ case R_ARM_ABS32:
+@@ -1432,6 +1440,10 @@ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
+ case R_ARM_PC24:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
++ inst = TO_NATIVE(*(uint32_t *)loc);
++ offset = sign_extend32((inst & 0x00ffffff) << 2, 25);
++ r->r_addend = offset + sym->st_value + 8;
++ break;
+ case R_ARM_THM_CALL:
+ case R_ARM_THM_JUMP24:
+ case R_ARM_THM_JUMP19:
+--
+2.39.2
+
--- /dev/null
+From 34250af8a5e51eff0780913ec6d398c88006e15b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 21:09:55 +0900
+Subject: modpost: fix section mismatch message for R_ARM_ABS32
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit b7c63520f6703a25eebb4f8138fed764fcae1c6f ]
+
+addend_arm_rel() processes R_ARM_ABS32 in a wrong way.
+
+Here, test code.
+
+ [test code 1]
+
+ #include <linux/init.h>
+
+ int __initdata foo;
+ int get_foo(void) { return foo; }
+
+If you compile it with ARM versatile_defconfig, modpost will show the
+symbol name, (unknown).
+
+ WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> (unknown) (section: .init.data)
+
+(You need to use GNU linker instead of LLD to reproduce it.)
+
+If you compile it for other architectures, modpost will show the correct
+symbol name.
+
+ WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> foo (section: .init.data)
+
+For R_ARM_ABS32, addend_arm_rel() sets r->r_addend to a wrong value.
+
+I just mimicked the code in arch/arm/kernel/module.c.
+
+However, there is more difficulty for ARM.
+
+Here, test code.
+
+ [test code 2]
+
+ #include <linux/init.h>
+
+ int __initdata foo;
+ int get_foo(void) { return foo; }
+
+ int __initdata bar;
+ int get_bar(void) { return bar; }
+
+With this commit applied, modpost will show the following messages
+for ARM versatile_defconfig:
+
+ WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> foo (section: .init.data)
+ WARNING: modpost: vmlinux.o: section mismatch in reference: get_bar (section: .text) -> foo (section: .init.data)
+
+The reference from 'get_bar' to 'foo' seems wrong.
+
+I have no solution for this because it is true in assembly level.
+
+In the following output, relocation at 0x1c is no longer associated
+with 'bar'. The two relocation entries point to the same symbol, and
+the offset to 'bar' is encoded in the instruction 'r0, [r3, #4]'.
+
+ Disassembly of section .text:
+
+ 00000000 <get_foo>:
+ 0: e59f3004 ldr r3, [pc, #4] @ c <get_foo+0xc>
+ 4: e5930000 ldr r0, [r3]
+ 8: e12fff1e bx lr
+ c: 00000000 .word 0x00000000
+
+ 00000010 <get_bar>:
+ 10: e59f3004 ldr r3, [pc, #4] @ 1c <get_bar+0xc>
+ 14: e5930004 ldr r0, [r3, #4]
+ 18: e12fff1e bx lr
+ 1c: 00000000 .word 0x00000000
+
+ Relocation section '.rel.text' at offset 0x244 contains 2 entries:
+ Offset Info Type Sym.Value Sym. Name
+ 0000000c 00000c02 R_ARM_ABS32 00000000 .init.data
+ 0000001c 00000c02 R_ARM_ABS32 00000000 .init.data
+
+When find_elf_symbol() gets into a situation where relsym->st_name is
+zero, there is no guarantee to get the symbol name as written in C.
+
+I am keeping the current logic because it is useful in many architectures,
+but the symbol name is not always correct depending on the optimization.
+I left some comments in find_tosym().
+
+Fixes: 56a974fa2d59 ("kbuild: make better section mismatch reports on arm")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/mod/modpost.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
+index 934e9d90de540..ff7a8df9e54cd 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -1156,6 +1156,10 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
+ if (relsym->st_name != 0)
+ return relsym;
+
++ /*
++ * Strive to find a better symbol name, but the resulting name may not
++ * match the symbol referenced in the original code.
++ */
+ relsym_secindex = get_secindex(elf, relsym);
+ for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
+ if (get_secindex(elf, sym) != relsym_secindex)
+@@ -1416,12 +1420,14 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
+ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
+ {
+ unsigned int r_typ = ELF_R_TYPE(r->r_info);
++ Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info);
++ void *loc = reloc_location(elf, sechdr, r);
++ uint32_t inst;
+
+ switch (r_typ) {
+ case R_ARM_ABS32:
+- /* From ARM ABI: (S + A) | T */
+- r->r_addend = (int)(long)
+- (elf->symtab_start + ELF_R_SYM(r->r_info));
++ inst = TO_NATIVE(*(uint32_t *)loc);
++ r->r_addend = inst + sym->st_value;
+ break;
+ case R_ARM_PC24:
+ case R_ARM_CALL:
+--
+2.39.2
+
--- /dev/null
+From 49375c335729fe4609e0774fa5ce3f5bc46230af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 00:27:19 +0900
+Subject: modpost: remove broken calculation of exception_table_entry size
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit d0acc76a49aa917c1a455d11d32d34a01e8b2835 ]
+
+find_extable_entry_size() is completely broken. It has awesome comments
+about how to calculate sizeof(struct exception_table_entry).
+
+It was based on these assumptions:
+
+ - struct exception_table_entry has two fields
+ - both of the fields have the same size
+
+Then, we came up with this equation:
+
+ (offset of the second field) * 2 == (size of struct)
+
+It was true for all architectures when commit 52dc0595d540 ("modpost:
+handle relocations mismatch in __ex_table.") was applied.
+
+Our mathematics broke when commit 548acf19234d ("x86/mm: Expand the
+exception table logic to allow new handling options") introduced the
+third field.
+
+Now, the definition of exception_table_entry is highly arch-dependent.
+
+For x86, sizeof(struct exception_table_entry) is apparently 12, but
+find_extable_entry_size() sets extable_entry_size to 8.
+
+I could fix it, but I do not see much value in this code.
+
+extable_entry_size is used just for selecting a slightly different
+error message.
+
+If the first field ("insn") references to a non-executable section,
+
+ The relocation at %s+0x%lx references
+ section "%s" which is not executable, IOW
+ it is not possible for the kernel to fault
+ at that address. Something is seriously wrong
+ and should be fixed.
+
+If the second field ("fixup") references to a non-executable section,
+
+ The relocation at %s+0x%lx references
+ section "%s" which is not executable, IOW
+ the kernel will fault if it ever tries to
+ jump to it. Something is seriously wrong
+ and should be fixed.
+
+Merge the two error messages rather than adding even more complexity.
+
+Change fatal() to error() to make it continue running and catch more
+possible errors.
+
+Fixes: 548acf19234d ("x86/mm: Expand the exception table logic to allow new handling options")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/mod/modpost.c | 60 +++----------------------------------------
+ 1 file changed, 3 insertions(+), 57 deletions(-)
+
+diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
+index 5b3964b39709f..934e9d90de540 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -1298,43 +1298,6 @@ static int is_executable_section(struct elf_info* elf, unsigned int section_inde
+ return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR);
+ }
+
+-/*
+- * We rely on a gross hack in section_rel[a]() calling find_extable_entry_size()
+- * to know the sizeof(struct exception_table_entry) for the target architecture.
+- */
+-static unsigned int extable_entry_size = 0;
+-static void find_extable_entry_size(const char* const sec, const Elf_Rela* r)
+-{
+- /*
+- * If we're currently checking the second relocation within __ex_table,
+- * that relocation offset tells us the offsetof(struct
+- * exception_table_entry, fixup) which is equal to sizeof(struct
+- * exception_table_entry) divided by two. We use that to our advantage
+- * since there's no portable way to get that size as every architecture
+- * seems to go with different sized types. Not pretty but better than
+- * hard-coding the size for every architecture..
+- */
+- if (!extable_entry_size)
+- extable_entry_size = r->r_offset * 2;
+-}
+-
+-static inline bool is_extable_fault_address(Elf_Rela *r)
+-{
+- /*
+- * extable_entry_size is only discovered after we've handled the
+- * _second_ relocation in __ex_table, so only abort when we're not
+- * handling the first reloc and extable_entry_size is zero.
+- */
+- if (r->r_offset && extable_entry_size == 0)
+- fatal("extable_entry size hasn't been discovered!\n");
+-
+- return ((r->r_offset == 0) ||
+- (r->r_offset % extable_entry_size == 0));
+-}
+-
+-#define is_second_extable_reloc(Start, Cur, Sec) \
+- (((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0))
+-
+ static void report_extable_warnings(const char* modname, struct elf_info* elf,
+ const struct sectioncheck* const mismatch,
+ Elf_Rela* r, Elf_Sym* sym,
+@@ -1390,22 +1353,9 @@ static void extable_mismatch_handler(const char* modname, struct elf_info *elf,
+ "You might get more information about where this is\n"
+ "coming from by using scripts/check_extable.sh %s\n",
+ fromsec, (long)r->r_offset, tosec, modname);
+- else if (!is_executable_section(elf, get_secindex(elf, sym))) {
+- if (is_extable_fault_address(r))
+- fatal("The relocation at %s+0x%lx references\n"
+- "section \"%s\" which is not executable, IOW\n"
+- "it is not possible for the kernel to fault\n"
+- "at that address. Something is seriously wrong\n"
+- "and should be fixed.\n",
+- fromsec, (long)r->r_offset, tosec);
+- else
+- fatal("The relocation at %s+0x%lx references\n"
+- "section \"%s\" which is not executable, IOW\n"
+- "the kernel will fault if it ever tries to\n"
+- "jump to it. Something is seriously wrong\n"
+- "and should be fixed.\n",
+- fromsec, (long)r->r_offset, tosec);
+- }
++ else if (!is_executable_section(elf, get_secindex(elf, sym)))
++ error("%s+0x%lx references non-executable section '%s'\n",
++ fromsec, (long)r->r_offset, tosec);
+ }
+
+ static void check_section_mismatch(const char *modname, struct elf_info *elf,
+@@ -1580,8 +1530,6 @@ static void section_rela(const char *modname, struct elf_info *elf,
+ /* Skip special sections */
+ if (is_shndx_special(sym->st_shndx))
+ continue;
+- if (is_second_extable_reloc(start, rela, fromsec))
+- find_extable_entry_size(fromsec, &r);
+ check_section_mismatch(modname, elf, &r, sym, fromsec);
+ }
+ }
+@@ -1639,8 +1587,6 @@ static void section_rel(const char *modname, struct elf_info *elf,
+ /* Skip special sections */
+ if (is_shndx_special(sym->st_shndx))
+ continue;
+- if (is_second_extable_reloc(start, rel, fromsec))
+- find_extable_entry_size(fromsec, &r);
+ check_section_mismatch(modname, elf, &r, sym, fromsec);
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From fd3f7315007a807d64043209fd6dd9d1711ce90c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 22:22:45 +0300
+Subject: net: axienet: Move reset before 64-bit DMA detection
+
+From: Maxim Kochetkov <fido_max@inbox.ru>
+
+[ Upstream commit f1bc9fc4a06de0108e0dca2a9a7e99ba1fc632f9 ]
+
+64-bit DMA detection will fail if axienet was started before (by boot
+loader, boot ROM, etc). In this state axienet will not start properly.
+XAXIDMA_TX_CDESC_OFFSET + 4 register (MM2S_CURDESC_MSB) is used to detect
+64-bit DMA capability here. But datasheet says: When DMACR.RS is 1
+(axienet is in enabled state), CURDESC_PTR becomes Read Only (RO) and
+is used to fetch the first descriptor. So iowrite32()/ioread32() trick
+to this register to detect 64-bit DMA will not work.
+So move axienet reset before 64-bit DMA detection.
+
+Fixes: f735c40ed93c ("net: axienet: Autodetect 64-bit DMA capability")
+Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru>
+Reviewed-by: Robert Hancock <robert.hancock@calian.com>
+Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
+Link: https://lore.kernel.org/r/20230622192245.116864-1-fido_max@inbox.ru
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 3e310b55bce2b..734822321e0ab 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -2042,6 +2042,11 @@ static int axienet_probe(struct platform_device *pdev)
+ goto cleanup_clk;
+ }
+
++ /* Reset core now that clocks are enabled, prior to accessing MDIO */
++ ret = __axienet_device_reset(lp);
++ if (ret)
++ goto cleanup_clk;
++
+ /* Autodetect the need for 64-bit DMA pointers.
+ * When the IP is configured for a bus width bigger than 32 bits,
+ * writing the MSB registers is mandatory, even if they are all 0.
+@@ -2096,11 +2101,6 @@ static int axienet_probe(struct platform_device *pdev)
+ lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
+ lp->coalesce_usec_tx = XAXIDMA_DFT_TX_USEC;
+
+- /* Reset core now that clocks are enabled, prior to accessing MDIO */
+- ret = __axienet_device_reset(lp);
+- if (ret)
+- goto cleanup_clk;
+-
+ ret = axienet_mdio_setup(lp);
+ if (ret)
+ dev_warn(&pdev->dev,
+--
+2.39.2
+
--- /dev/null
+From 23d683775577d3ea372458b3b8718ffd741ac77c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 18:44:02 +0300
+Subject: net: dsa: avoid suspicious RCU usage for synced VLAN-aware MAC
+ addresses
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit d06f925f13976ab82167c93467c70a337a0a3cda ]
+
+When using the felix driver (the only one which supports UC filtering
+and MC filtering) as a DSA master for a random other DSA switch, one can
+see the following stack trace when the downstream switch ports join a
+VLAN-aware bridge:
+
+=============================
+WARNING: suspicious RCU usage
+-----------------------------
+net/8021q/vlan_core.c:238 suspicious rcu_dereference_protected() usage!
+
+stack backtrace:
+Workqueue: dsa_ordered dsa_slave_switchdev_event_work
+Call trace:
+ lockdep_rcu_suspicious+0x170/0x210
+ vlan_for_each+0x8c/0x188
+ dsa_slave_sync_uc+0x128/0x178
+ __hw_addr_sync_dev+0x138/0x158
+ dsa_slave_set_rx_mode+0x58/0x70
+ __dev_set_rx_mode+0x88/0xa8
+ dev_uc_add+0x74/0xa0
+ dsa_port_bridge_host_fdb_add+0xec/0x180
+ dsa_slave_switchdev_event_work+0x7c/0x1c8
+ process_one_work+0x290/0x568
+
+What it's saying is that vlan_for_each() expects rtnl_lock() context and
+it's not getting it, when it's called from the DSA master's ndo_set_rx_mode().
+
+The caller of that - dsa_slave_set_rx_mode() - is the slave DSA
+interface's dsa_port_bridge_host_fdb_add() which comes from the deferred
+dsa_slave_switchdev_event_work().
+
+We went to great lengths to avoid the rtnl_lock() context in that call
+path in commit 0faf890fc519 ("net: dsa: drop rtnl_lock from
+dsa_slave_switchdev_event_work"), and calling rtnl_lock() is simply not
+an option due to the possibility of deadlocking when calling
+dsa_flush_workqueue() from the call paths that do hold rtnl_lock() -
+basically all of them.
+
+So, when the DSA master calls vlan_for_each() from its ndo_set_rx_mode(),
+the state of the 8021q driver on this device is really not protected
+from concurrent access by anything.
+
+Looking at net/8021q/, I don't think that vlan_info->vid_list was
+particularly designed with RCU traversal in mind, so introducing an RCU
+read-side form of vlan_for_each() - vlan_for_each_rcu() - won't be so
+easy, and it also wouldn't be exactly what we need anyway.
+
+In general I believe that the solution isn't in net/8021q/ anyway;
+vlan_for_each() is not cut out for this task. DSA doesn't need rtnl_lock()
+to be held per se - since it's not a netdev state change that we're
+blocking, but rather, just concurrent additions/removals to a VLAN list.
+We don't even need sleepable context - the callback of vlan_for_each()
+just schedules deferred work.
+
+The proposed escape is to remove the dependency on vlan_for_each() and
+to open-code a non-sleepable, rtnl-free alternative to that, based on
+copies of the VLAN list modified from .ndo_vlan_rx_add_vid() and
+.ndo_vlan_rx_kill_vid().
+
+Fixes: 64fdc5f341db ("net: dsa: sync unicast and multicast addresses for VLAN filters too")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://lore.kernel.org/r/20230626154402.3154454-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/dsa.h | 12 +++++--
+ net/dsa/dsa.c | 2 +-
+ net/dsa/slave.c | 84 ++++++++++++++++++++++++++++++++---------------
+ net/dsa/switch.c | 4 +--
+ net/dsa/switch.h | 3 ++
+ 5 files changed, 74 insertions(+), 31 deletions(-)
+
+diff --git a/include/net/dsa.h b/include/net/dsa.h
+index def06ef676dd8..56e297e7848d6 100644
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -329,9 +329,17 @@ struct dsa_port {
+ struct list_head fdbs;
+ struct list_head mdbs;
+
+- /* List of VLANs that CPU and DSA ports are members of. */
+ struct mutex vlans_lock;
+- struct list_head vlans;
++ union {
++ /* List of VLANs that CPU and DSA ports are members of.
++ * Access to this is serialized by the sleepable @vlans_lock.
++ */
++ struct list_head vlans;
++ /* List of VLANs that user ports are members of.
++ * Access to this is serialized by netif_addr_lock_bh().
++ */
++ struct list_head user_vlans;
++ };
+ };
+
+ /* TODO: ideally DSA ports would have a single dp->link_dp member,
+diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
+index 6cd8607a3928f..390d790c0b056 100644
+--- a/net/dsa/dsa.c
++++ b/net/dsa/dsa.c
+@@ -1105,7 +1105,7 @@ static struct dsa_port *dsa_port_touch(struct dsa_switch *ds, int index)
+ mutex_init(&dp->vlans_lock);
+ INIT_LIST_HEAD(&dp->fdbs);
+ INIT_LIST_HEAD(&dp->mdbs);
+- INIT_LIST_HEAD(&dp->vlans);
++ INIT_LIST_HEAD(&dp->vlans); /* also initializes &dp->user_vlans */
+ INIT_LIST_HEAD(&dp->list);
+ list_add_tail(&dp->list, &dst->ports);
+
+diff --git a/net/dsa/slave.c b/net/dsa/slave.c
+index 165bb2cb84316..527b1d576460f 100644
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -27,6 +27,7 @@
+ #include "master.h"
+ #include "netlink.h"
+ #include "slave.h"
++#include "switch.h"
+ #include "tag.h"
+
+ struct dsa_switchdev_event_work {
+@@ -161,8 +162,7 @@ static int dsa_slave_schedule_standalone_work(struct net_device *dev,
+ return 0;
+ }
+
+-static int dsa_slave_host_vlan_rx_filtering(struct net_device *vdev, int vid,
+- void *arg)
++static int dsa_slave_host_vlan_rx_filtering(void *arg, int vid)
+ {
+ struct dsa_host_vlan_rx_filtering_ctx *ctx = arg;
+
+@@ -170,6 +170,28 @@ static int dsa_slave_host_vlan_rx_filtering(struct net_device *vdev, int vid,
+ ctx->addr, vid);
+ }
+
++static int dsa_slave_vlan_for_each(struct net_device *dev,
++ int (*cb)(void *arg, int vid), void *arg)
++{
++ struct dsa_port *dp = dsa_slave_to_port(dev);
++ struct dsa_vlan *v;
++ int err;
++
++ lockdep_assert_held(&dev->addr_list_lock);
++
++ err = cb(arg, 0);
++ if (err)
++ return err;
++
++ list_for_each_entry(v, &dp->user_vlans, list) {
++ err = cb(arg, v->vid);
++ if (err)
++ return err;
++ }
++
++ return 0;
++}
++
+ static int dsa_slave_sync_uc(struct net_device *dev,
+ const unsigned char *addr)
+ {
+@@ -180,18 +202,14 @@ static int dsa_slave_sync_uc(struct net_device *dev,
+ .addr = addr,
+ .event = DSA_UC_ADD,
+ };
+- int err;
+
+ dev_uc_add(master, addr);
+
+ if (!dsa_switch_supports_uc_filtering(dp->ds))
+ return 0;
+
+- err = dsa_slave_schedule_standalone_work(dev, DSA_UC_ADD, addr, 0);
+- if (err)
+- return err;
+-
+- return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
++ return dsa_slave_vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering,
++ &ctx);
+ }
+
+ static int dsa_slave_unsync_uc(struct net_device *dev,
+@@ -204,18 +222,14 @@ static int dsa_slave_unsync_uc(struct net_device *dev,
+ .addr = addr,
+ .event = DSA_UC_DEL,
+ };
+- int err;
+
+ dev_uc_del(master, addr);
+
+ if (!dsa_switch_supports_uc_filtering(dp->ds))
+ return 0;
+
+- err = dsa_slave_schedule_standalone_work(dev, DSA_UC_DEL, addr, 0);
+- if (err)
+- return err;
+-
+- return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
++ return dsa_slave_vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering,
++ &ctx);
+ }
+
+ static int dsa_slave_sync_mc(struct net_device *dev,
+@@ -228,18 +242,14 @@ static int dsa_slave_sync_mc(struct net_device *dev,
+ .addr = addr,
+ .event = DSA_MC_ADD,
+ };
+- int err;
+
+ dev_mc_add(master, addr);
+
+ if (!dsa_switch_supports_mc_filtering(dp->ds))
+ return 0;
+
+- err = dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD, addr, 0);
+- if (err)
+- return err;
+-
+- return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
++ return dsa_slave_vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering,
++ &ctx);
+ }
+
+ static int dsa_slave_unsync_mc(struct net_device *dev,
+@@ -252,18 +262,14 @@ static int dsa_slave_unsync_mc(struct net_device *dev,
+ .addr = addr,
+ .event = DSA_MC_DEL,
+ };
+- int err;
+
+ dev_mc_del(master, addr);
+
+ if (!dsa_switch_supports_mc_filtering(dp->ds))
+ return 0;
+
+- err = dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL, addr, 0);
+- if (err)
+- return err;
+-
+- return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
++ return dsa_slave_vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering,
++ &ctx);
+ }
+
+ void dsa_slave_sync_ha(struct net_device *dev)
+@@ -1759,6 +1765,7 @@ static int dsa_slave_vlan_rx_add_vid(struct net_device *dev, __be16 proto,
+ struct netlink_ext_ack extack = {0};
+ struct dsa_switch *ds = dp->ds;
+ struct netdev_hw_addr *ha;
++ struct dsa_vlan *v;
+ int ret;
+
+ /* User port... */
+@@ -1782,8 +1789,17 @@ static int dsa_slave_vlan_rx_add_vid(struct net_device *dev, __be16 proto,
+ !dsa_switch_supports_mc_filtering(ds))
+ return 0;
+
++ v = kzalloc(sizeof(*v), GFP_KERNEL);
++ if (!v) {
++ ret = -ENOMEM;
++ goto rollback;
++ }
++
+ netif_addr_lock_bh(dev);
+
++ v->vid = vid;
++ list_add_tail(&v->list, &dp->user_vlans);
++
+ if (dsa_switch_supports_mc_filtering(ds)) {
+ netdev_for_each_synced_mc_addr(ha, dev) {
+ dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD,
+@@ -1803,6 +1819,12 @@ static int dsa_slave_vlan_rx_add_vid(struct net_device *dev, __be16 proto,
+ dsa_flush_workqueue();
+
+ return 0;
++
++rollback:
++ dsa_port_host_vlan_del(dp, &vlan);
++ dsa_port_vlan_del(dp, &vlan);
++
++ return ret;
+ }
+
+ static int dsa_slave_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
+@@ -1816,6 +1838,7 @@ static int dsa_slave_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
+ };
+ struct dsa_switch *ds = dp->ds;
+ struct netdev_hw_addr *ha;
++ struct dsa_vlan *v;
+ int err;
+
+ err = dsa_port_vlan_del(dp, &vlan);
+@@ -1832,6 +1855,15 @@ static int dsa_slave_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
+
+ netif_addr_lock_bh(dev);
+
++ v = dsa_vlan_find(&dp->user_vlans, &vlan);
++ if (!v) {
++ netif_addr_unlock_bh(dev);
++ return -ENOENT;
++ }
++
++ list_del(&v->list);
++ kfree(v);
++
+ if (dsa_switch_supports_mc_filtering(ds)) {
+ netdev_for_each_synced_mc_addr(ha, dev) {
+ dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL,
+diff --git a/net/dsa/switch.c b/net/dsa/switch.c
+index d5bc4bb7310dc..36f8ffea2d168 100644
+--- a/net/dsa/switch.c
++++ b/net/dsa/switch.c
+@@ -634,8 +634,8 @@ static bool dsa_port_host_vlan_match(struct dsa_port *dp,
+ return false;
+ }
+
+-static struct dsa_vlan *dsa_vlan_find(struct list_head *vlan_list,
+- const struct switchdev_obj_port_vlan *vlan)
++struct dsa_vlan *dsa_vlan_find(struct list_head *vlan_list,
++ const struct switchdev_obj_port_vlan *vlan)
+ {
+ struct dsa_vlan *v;
+
+diff --git a/net/dsa/switch.h b/net/dsa/switch.h
+index 15e67b95eb6e1..ea034677da153 100644
+--- a/net/dsa/switch.h
++++ b/net/dsa/switch.h
+@@ -111,6 +111,9 @@ struct dsa_notifier_master_state_info {
+ bool operational;
+ };
+
++struct dsa_vlan *dsa_vlan_find(struct list_head *vlan_list,
++ const struct switchdev_obj_port_vlan *vlan);
++
+ int dsa_tree_notify(struct dsa_switch_tree *dst, unsigned long e, void *v);
+ int dsa_broadcast(unsigned long e, void *v);
+
+--
+2.39.2
+
--- /dev/null
+From b86fa7aee608ec4bf329205d7d73f83f1e1170d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jun 2023 17:10:07 +0800
+Subject: net: nfc: Fix use-after-free caused by nfc_llcp_find_local
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit 6709d4b7bc2e079241fdef15d1160581c5261c10 ]
+
+This commit fixes several use-after-free that caused by function
+nfc_llcp_find_local(). For example, one UAF can happen when below buggy
+time window occurs.
+
+// nfc_genl_llc_get_params | // nfc_unregister_device
+ |
+dev = nfc_get_device(idx); | device_lock(...)
+if (!dev) | dev->shutting_down = true;
+ return -ENODEV; | device_unlock(...);
+ |
+device_lock(...); | // nfc_llcp_unregister_device
+ | nfc_llcp_find_local()
+nfc_llcp_find_local(...); |
+ | local_cleanup()
+if (!local) { |
+ rc = -ENODEV; | // nfc_llcp_local_put
+ goto exit; | kref_put(.., local_release)
+} |
+ | // local_release
+ | list_del(&local->list)
+ // nfc_genl_send_params | kfree()
+ local->dev->idx !!!UAF!!! |
+ |
+
+and the crash trace for the one of the discussed UAF like:
+
+BUG: KASAN: slab-use-after-free in nfc_genl_llc_get_params+0x72f/0x780 net/nfc/netlink.c:1045
+Read of size 8 at addr ffff888105b0e410 by task 20114
+
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x72/0xa0 lib/dump_stack.c:106
+ print_address_description mm/kasan/report.c:319 [inline]
+ print_report+0xcc/0x620 mm/kasan/report.c:430
+ kasan_report+0xb2/0xe0 mm/kasan/report.c:536
+ nfc_genl_send_params net/nfc/netlink.c:999 [inline]
+ nfc_genl_llc_get_params+0x72f/0x780 net/nfc/netlink.c:1045
+ genl_family_rcv_msg_doit.isra.0+0x1ee/0x2e0 net/netlink/genetlink.c:968
+ genl_family_rcv_msg net/netlink/genetlink.c:1048 [inline]
+ genl_rcv_msg+0x503/0x7d0 net/netlink/genetlink.c:1065
+ netlink_rcv_skb+0x161/0x430 net/netlink/af_netlink.c:2548
+ genl_rcv+0x28/0x40 net/netlink/genetlink.c:1076
+ netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline]
+ netlink_unicast+0x644/0x900 net/netlink/af_netlink.c:1365
+ netlink_sendmsg+0x934/0xe70 net/netlink/af_netlink.c:1913
+ sock_sendmsg_nosec net/socket.c:724 [inline]
+ sock_sendmsg+0x1b6/0x200 net/socket.c:747
+ ____sys_sendmsg+0x6e9/0x890 net/socket.c:2501
+ ___sys_sendmsg+0x110/0x1b0 net/socket.c:2555
+ __sys_sendmsg+0xf7/0x1d0 net/socket.c:2584
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+RIP: 0033:0x7f34640a2389
+RSP: 002b:00007f3463415168 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f34641c1f80 RCX: 00007f34640a2389
+RDX: 0000000000000000 RSI: 0000000020000240 RDI: 0000000000000006
+RBP: 00007f34640ed493 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 00007ffe38449ecf R14: 00007f3463415300 R15: 0000000000022000
+ </TASK>
+
+Allocated by task 20116:
+ kasan_save_stack+0x22/0x50 mm/kasan/common.c:45
+ kasan_set_track+0x25/0x30 mm/kasan/common.c:52
+ ____kasan_kmalloc mm/kasan/common.c:374 [inline]
+ __kasan_kmalloc+0x7f/0x90 mm/kasan/common.c:383
+ kmalloc include/linux/slab.h:580 [inline]
+ kzalloc include/linux/slab.h:720 [inline]
+ nfc_llcp_register_device+0x49/0xa40 net/nfc/llcp_core.c:1567
+ nfc_register_device+0x61/0x260 net/nfc/core.c:1124
+ nci_register_device+0x776/0xb20 net/nfc/nci/core.c:1257
+ virtual_ncidev_open+0x147/0x230 drivers/nfc/virtual_ncidev.c:148
+ misc_open+0x379/0x4a0 drivers/char/misc.c:165
+ chrdev_open+0x26c/0x780 fs/char_dev.c:414
+ do_dentry_open+0x6c4/0x12a0 fs/open.c:920
+ do_open fs/namei.c:3560 [inline]
+ path_openat+0x24fe/0x37e0 fs/namei.c:3715
+ do_filp_open+0x1ba/0x410 fs/namei.c:3742
+ do_sys_openat2+0x171/0x4c0 fs/open.c:1356
+ do_sys_open fs/open.c:1372 [inline]
+ __do_sys_openat fs/open.c:1388 [inline]
+ __se_sys_openat fs/open.c:1383 [inline]
+ __x64_sys_openat+0x143/0x200 fs/open.c:1383
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+
+Freed by task 20115:
+ kasan_save_stack+0x22/0x50 mm/kasan/common.c:45
+ kasan_set_track+0x25/0x30 mm/kasan/common.c:52
+ kasan_save_free_info+0x2e/0x50 mm/kasan/generic.c:521
+ ____kasan_slab_free mm/kasan/common.c:236 [inline]
+ ____kasan_slab_free mm/kasan/common.c:200 [inline]
+ __kasan_slab_free+0x10a/0x190 mm/kasan/common.c:244
+ kasan_slab_free include/linux/kasan.h:162 [inline]
+ slab_free_hook mm/slub.c:1781 [inline]
+ slab_free_freelist_hook mm/slub.c:1807 [inline]
+ slab_free mm/slub.c:3787 [inline]
+ __kmem_cache_free+0x7a/0x190 mm/slub.c:3800
+ local_release net/nfc/llcp_core.c:174 [inline]
+ kref_put include/linux/kref.h:65 [inline]
+ nfc_llcp_local_put net/nfc/llcp_core.c:182 [inline]
+ nfc_llcp_local_put net/nfc/llcp_core.c:177 [inline]
+ nfc_llcp_unregister_device+0x206/0x290 net/nfc/llcp_core.c:1620
+ nfc_unregister_device+0x160/0x1d0 net/nfc/core.c:1179
+ virtual_ncidev_close+0x52/0xa0 drivers/nfc/virtual_ncidev.c:163
+ __fput+0x252/0xa20 fs/file_table.c:321
+ task_work_run+0x174/0x270 kernel/task_work.c:179
+ resume_user_mode_work include/linux/resume_user_mode.h:49 [inline]
+ exit_to_user_mode_loop kernel/entry/common.c:171 [inline]
+ exit_to_user_mode_prepare+0x108/0x110 kernel/entry/common.c:204
+ __syscall_exit_to_user_mode_work kernel/entry/common.c:286 [inline]
+ syscall_exit_to_user_mode+0x21/0x50 kernel/entry/common.c:297
+ do_syscall_64+0x4c/0x90 arch/x86/entry/common.c:86
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+
+Last potentially related work creation:
+ kasan_save_stack+0x22/0x50 mm/kasan/common.c:45
+ __kasan_record_aux_stack+0x95/0xb0 mm/kasan/generic.c:491
+ kvfree_call_rcu+0x29/0xa80 kernel/rcu/tree.c:3328
+ drop_sysctl_table+0x3be/0x4e0 fs/proc/proc_sysctl.c:1735
+ unregister_sysctl_table.part.0+0x9c/0x190 fs/proc/proc_sysctl.c:1773
+ unregister_sysctl_table+0x24/0x30 fs/proc/proc_sysctl.c:1753
+ neigh_sysctl_unregister+0x5f/0x80 net/core/neighbour.c:3895
+ addrconf_notify+0x140/0x17b0 net/ipv6/addrconf.c:3684
+ notifier_call_chain+0xbe/0x210 kernel/notifier.c:87
+ call_netdevice_notifiers_info+0xb5/0x150 net/core/dev.c:1937
+ call_netdevice_notifiers_extack net/core/dev.c:1975 [inline]
+ call_netdevice_notifiers net/core/dev.c:1989 [inline]
+ dev_change_name+0x3c3/0x870 net/core/dev.c:1211
+ dev_ifsioc+0x800/0xf70 net/core/dev_ioctl.c:376
+ dev_ioctl+0x3d9/0xf80 net/core/dev_ioctl.c:542
+ sock_do_ioctl+0x160/0x260 net/socket.c:1213
+ sock_ioctl+0x3f9/0x670 net/socket.c:1316
+ vfs_ioctl fs/ioctl.c:51 [inline]
+ __do_sys_ioctl fs/ioctl.c:870 [inline]
+ __se_sys_ioctl fs/ioctl.c:856 [inline]
+ __x64_sys_ioctl+0x19e/0x210 fs/ioctl.c:856
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+
+The buggy address belongs to the object at ffff888105b0e400
+ which belongs to the cache kmalloc-1k of size 1024
+The buggy address is located 16 bytes inside of
+ freed 1024-byte region [ffff888105b0e400, ffff888105b0e800)
+
+The buggy address belongs to the physical page:
+head:ffffea000416c200 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+flags: 0x200000000010200(slab|head|node=0|zone=2)
+raw: 0200000000010200 ffff8881000430c0 ffffea00044c7010 ffffea0004510e10
+raw: 0000000000000000 00000000000a000a 00000001ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+
+Memory state around the buggy address:
+ ffff888105b0e300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+ ffff888105b0e380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+>ffff888105b0e400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ^
+ ffff888105b0e480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff888105b0e500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+
+In summary, this patch solves those use-after-free by
+
+1. Re-implement the nfc_llcp_find_local(). The current version does not
+grab the reference when getting the local from the linked list. For
+example, the llcp_sock_bind() gets the reference like below:
+
+// llcp_sock_bind()
+
+ local = nfc_llcp_find_local(dev); // A
+ ..... \
+ | raceable
+ ..... /
+ llcp_sock->local = nfc_llcp_local_get(local); // B
+
+There is an apparent race window that one can drop the reference
+and free the local object fetched in (A) before (B) gets the reference.
+
+2. Some callers of the nfc_llcp_find_local() do not grab the reference
+at all. For example, the nfc_genl_llc_{{get/set}_params/sdreq} functions.
+We add the nfc_llcp_local_put() for them. Moreover, we add the necessary
+error handling function to put the reference.
+
+3. Add the nfc_llcp_remove_local() helper. The local object is removed
+from the linked list in local_release() when all reference is gone. This
+patch removes it when nfc_llcp_unregister_device() is called.
+
+Therefore, every caller of nfc_llcp_find_local() will get a reference
+even when the nfc_llcp_unregister_device() is called. This promises no
+use-after-free for the local object is ever possible.
+
+Fixes: 52feb444a903 ("NFC: Extend netlink interface for LTO, RW, and MIUX parameters support")
+Fixes: c7aa12252f51 ("NFC: Take a reference on the LLCP local pointer when creating a socket")
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp.h | 1 -
+ net/nfc/llcp_commands.c | 12 +++++++---
+ net/nfc/llcp_core.c | 49 +++++++++++++++++++++++++++++++++++------
+ net/nfc/llcp_sock.c | 18 ++++++++-------
+ net/nfc/netlink.c | 20 ++++++++++++-----
+ net/nfc/nfc.h | 1 +
+ 6 files changed, 77 insertions(+), 24 deletions(-)
+
+diff --git a/net/nfc/llcp.h b/net/nfc/llcp.h
+index c1d9be636933c..d8345ed57c954 100644
+--- a/net/nfc/llcp.h
++++ b/net/nfc/llcp.h
+@@ -201,7 +201,6 @@ void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *s);
+ void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *s);
+ void nfc_llcp_socket_remote_param_init(struct nfc_llcp_sock *sock);
+ struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
+-struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local);
+ int nfc_llcp_local_put(struct nfc_llcp_local *local);
+ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
+ struct nfc_llcp_sock *sock);
+diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
+index cdb001de06928..e2680a3bef799 100644
+--- a/net/nfc/llcp_commands.c
++++ b/net/nfc/llcp_commands.c
+@@ -359,6 +359,7 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
+ struct sk_buff *skb;
+ struct nfc_llcp_local *local;
+ u16 size = 0;
++ int err;
+
+ local = nfc_llcp_find_local(dev);
+ if (local == NULL)
+@@ -368,8 +369,10 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
+ size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE;
+
+ skb = alloc_skb(size, GFP_KERNEL);
+- if (skb == NULL)
+- return -ENOMEM;
++ if (skb == NULL) {
++ err = -ENOMEM;
++ goto out;
++ }
+
+ skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
+
+@@ -379,8 +382,11 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
+
+ nfc_llcp_send_to_raw_sock(local, skb, NFC_DIRECTION_TX);
+
+- return nfc_data_exchange(dev, local->target_idx, skb,
++ err = nfc_data_exchange(dev, local->target_idx, skb,
+ nfc_llcp_recv, local);
++out:
++ nfc_llcp_local_put(local);
++ return err;
+ }
+
+ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
+diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
+index a27e1842b2a09..f60e424e06076 100644
+--- a/net/nfc/llcp_core.c
++++ b/net/nfc/llcp_core.c
+@@ -17,6 +17,8 @@
+ static u8 llcp_magic[3] = {0x46, 0x66, 0x6d};
+
+ static LIST_HEAD(llcp_devices);
++/* Protects llcp_devices list */
++static DEFINE_SPINLOCK(llcp_devices_lock);
+
+ static void nfc_llcp_rx_skb(struct nfc_llcp_local *local, struct sk_buff *skb);
+
+@@ -141,7 +143,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device,
+ write_unlock(&local->raw_sockets.lock);
+ }
+
+-struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
++static struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
+ {
+ kref_get(&local->ref);
+
+@@ -169,7 +171,6 @@ static void local_release(struct kref *ref)
+
+ local = container_of(ref, struct nfc_llcp_local, ref);
+
+- list_del(&local->list);
+ local_cleanup(local);
+ kfree(local);
+ }
+@@ -282,12 +283,33 @@ static void nfc_llcp_sdreq_timer(struct timer_list *t)
+ struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev)
+ {
+ struct nfc_llcp_local *local;
++ struct nfc_llcp_local *res = NULL;
+
++ spin_lock(&llcp_devices_lock);
+ list_for_each_entry(local, &llcp_devices, list)
+- if (local->dev == dev)
++ if (local->dev == dev) {
++ res = nfc_llcp_local_get(local);
++ break;
++ }
++ spin_unlock(&llcp_devices_lock);
++
++ return res;
++}
++
++static struct nfc_llcp_local *nfc_llcp_remove_local(struct nfc_dev *dev)
++{
++ struct nfc_llcp_local *local, *tmp;
++
++ spin_lock(&llcp_devices_lock);
++ list_for_each_entry_safe(local, tmp, &llcp_devices, list)
++ if (local->dev == dev) {
++ list_del(&local->list);
++ spin_unlock(&llcp_devices_lock);
+ return local;
++ }
++ spin_unlock(&llcp_devices_lock);
+
+- pr_debug("No device found\n");
++ pr_warn("Shutting down device not found\n");
+
+ return NULL;
+ }
+@@ -608,12 +630,15 @@ u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len)
+
+ *general_bytes_len = local->gb_len;
+
++ nfc_llcp_local_put(local);
++
+ return local->gb;
+ }
+
+ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len)
+ {
+ struct nfc_llcp_local *local;
++ int err;
+
+ if (gb_len < 3 || gb_len > NFC_MAX_GT_LEN)
+ return -EINVAL;
+@@ -630,12 +655,16 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len)
+
+ if (memcmp(local->remote_gb, llcp_magic, 3)) {
+ pr_err("MAC does not support LLCP\n");
+- return -EINVAL;
++ err = -EINVAL;
++ goto out;
+ }
+
+- return nfc_llcp_parse_gb_tlv(local,
++ err = nfc_llcp_parse_gb_tlv(local,
+ &local->remote_gb[3],
+ local->remote_gb_len - 3);
++out:
++ nfc_llcp_local_put(local);
++ return err;
+ }
+
+ static u8 nfc_llcp_dsap(const struct sk_buff *pdu)
+@@ -1517,6 +1546,8 @@ int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb)
+
+ __nfc_llcp_recv(local, skb);
+
++ nfc_llcp_local_put(local);
++
+ return 0;
+ }
+
+@@ -1533,6 +1564,8 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
+
+ /* Close and purge all existing sockets */
+ nfc_llcp_socket_release(local, true, 0);
++
++ nfc_llcp_local_put(local);
+ }
+
+ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
+@@ -1558,6 +1591,8 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
+ mod_timer(&local->link_timer,
+ jiffies + msecs_to_jiffies(local->remote_lto));
+ }
++
++ nfc_llcp_local_put(local);
+ }
+
+ int nfc_llcp_register_device(struct nfc_dev *ndev)
+@@ -1608,7 +1643,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
+
+ void nfc_llcp_unregister_device(struct nfc_dev *dev)
+ {
+- struct nfc_llcp_local *local = nfc_llcp_find_local(dev);
++ struct nfc_llcp_local *local = nfc_llcp_remove_local(dev);
+
+ if (local == NULL) {
+ pr_debug("No such device\n");
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index 77642d18a3b43..645677f84dba2 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -99,7 +99,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
+ }
+
+ llcp_sock->dev = dev;
+- llcp_sock->local = nfc_llcp_local_get(local);
++ llcp_sock->local = local;
+ llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
+ llcp_sock->service_name_len = min_t(unsigned int,
+ llcp_addr.service_name_len,
+@@ -186,7 +186,7 @@ static int llcp_raw_sock_bind(struct socket *sock, struct sockaddr *addr,
+ }
+
+ llcp_sock->dev = dev;
+- llcp_sock->local = nfc_llcp_local_get(local);
++ llcp_sock->local = local;
+ llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
+
+ nfc_llcp_sock_link(&local->raw_sockets, sk);
+@@ -696,22 +696,22 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
+ if (dev->dep_link_up == false) {
+ ret = -ENOLINK;
+ device_unlock(&dev->dev);
+- goto put_dev;
++ goto sock_llcp_put_local;
+ }
+ device_unlock(&dev->dev);
+
+ if (local->rf_mode == NFC_RF_INITIATOR &&
+ addr->target_idx != local->target_idx) {
+ ret = -ENOLINK;
+- goto put_dev;
++ goto sock_llcp_put_local;
+ }
+
+ llcp_sock->dev = dev;
+- llcp_sock->local = nfc_llcp_local_get(local);
++ llcp_sock->local = local;
+ llcp_sock->ssap = nfc_llcp_get_local_ssap(local);
+ if (llcp_sock->ssap == LLCP_SAP_MAX) {
+ ret = -ENOMEM;
+- goto sock_llcp_put_local;
++ goto sock_llcp_nullify;
+ }
+
+ llcp_sock->reserved_ssap = llcp_sock->ssap;
+@@ -757,11 +757,13 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
+ sock_llcp_release:
+ nfc_llcp_put_ssap(local, llcp_sock->ssap);
+
+-sock_llcp_put_local:
+- nfc_llcp_local_put(llcp_sock->local);
++sock_llcp_nullify:
+ llcp_sock->local = NULL;
+ llcp_sock->dev = NULL;
+
++sock_llcp_put_local:
++ nfc_llcp_local_put(local);
++
+ put_dev:
+ nfc_put_device(dev);
+
+diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
+index b9264e730fd93..e9ac6a6f934e7 100644
+--- a/net/nfc/netlink.c
++++ b/net/nfc/netlink.c
+@@ -1039,11 +1039,14 @@ static int nfc_genl_llc_get_params(struct sk_buff *skb, struct genl_info *info)
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg) {
+ rc = -ENOMEM;
+- goto exit;
++ goto put_local;
+ }
+
+ rc = nfc_genl_send_params(msg, local, info->snd_portid, info->snd_seq);
+
++put_local:
++ nfc_llcp_local_put(local);
++
+ exit:
+ device_unlock(&dev->dev);
+
+@@ -1105,7 +1108,7 @@ static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info)
+ if (info->attrs[NFC_ATTR_LLC_PARAM_LTO]) {
+ if (dev->dep_link_up) {
+ rc = -EINPROGRESS;
+- goto exit;
++ goto put_local;
+ }
+
+ local->lto = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_LTO]);
+@@ -1117,6 +1120,9 @@ static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info)
+ if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX])
+ local->miux = cpu_to_be16(miux);
+
++put_local:
++ nfc_llcp_local_put(local);
++
+ exit:
+ device_unlock(&dev->dev);
+
+@@ -1172,7 +1178,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
+
+ if (rc != 0) {
+ rc = -EINVAL;
+- goto exit;
++ goto put_local;
+ }
+
+ if (!sdp_attrs[NFC_SDP_ATTR_URI])
+@@ -1191,7 +1197,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
+ sdreq = nfc_llcp_build_sdreq_tlv(tid, uri, uri_len);
+ if (sdreq == NULL) {
+ rc = -ENOMEM;
+- goto exit;
++ goto put_local;
+ }
+
+ tlvs_len += sdreq->tlv_len;
+@@ -1201,10 +1207,14 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
+
+ if (hlist_empty(&sdreq_list)) {
+ rc = -EINVAL;
+- goto exit;
++ goto put_local;
+ }
+
+ rc = nfc_llcp_send_snl_sdreq(local, &sdreq_list, tlvs_len);
++
++put_local:
++ nfc_llcp_local_put(local);
++
+ exit:
+ device_unlock(&dev->dev);
+
+diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h
+index de2ec66d7e83a..0b1e6466f4fbf 100644
+--- a/net/nfc/nfc.h
++++ b/net/nfc/nfc.h
+@@ -52,6 +52,7 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len);
+ u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len);
+ int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb);
+ struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
++int nfc_llcp_local_put(struct nfc_llcp_local *local);
+ int __init nfc_llcp_init(void);
+ void nfc_llcp_exit(void);
+ void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp);
+--
+2.39.2
+
--- /dev/null
+From 5fd2d1c2d1b4b0a854aa3a8ef93211fbab1dfc33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 15:55:37 +0200
+Subject: net: stmmac: fix double serdes powerdown
+
+From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+[ Upstream commit c4fc88ad2a765224a648db8ab35f125e120fe41b ]
+
+Commit 49725ffc15fc ("net: stmmac: power up/down serdes in
+stmmac_open/release") correctly added a call to the serdes_powerdown()
+callback to stmmac_release() but did not remove the one from
+stmmac_remove() which leads to a doubled call to serdes_powerdown().
+
+This can lead to all kinds of problems: in the case of the qcom ethqos
+driver, it caused an unbalanced regulator disable splat.
+
+Fixes: 49725ffc15fc ("net: stmmac: power up/down serdes in stmmac_open/release")
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Acked-by: Junxiao Chang <junxiao.chang@intel.com>
+Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
+Tested-by: Andrew Halaney <ahalaney@redhat.com>
+Link: https://lore.kernel.org/r/20230621135537.376649-1-brgl@bgdev.pl
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 4e59f0e164ec0..29d70ecdac846 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -7394,12 +7394,6 @@ void stmmac_dvr_remove(struct device *dev)
+ netif_carrier_off(ndev);
+ unregister_netdev(ndev);
+
+- /* Serdes power down needs to happen after VLAN filter
+- * is deleted that is triggered by unregister_netdev().
+- */
+- if (priv->plat->serdes_powerdown)
+- priv->plat->serdes_powerdown(ndev, priv->plat->bsp_priv);
+-
+ #ifdef CONFIG_DEBUG_FS
+ stmmac_exit_fs(ndev);
+ #endif
+--
+2.39.2
+
--- /dev/null
+From 7fe2fb65267bf02295dbcaca96480165e5131491 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 17:56:53 +0200
+Subject: netfilter: conntrack: dccp: copy entire header to stack buffer, not
+ just basic one
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit ff0a3a7d52ff7282dbd183e7fc29a1fe386b0c30 ]
+
+Eric Dumazet says:
+ nf_conntrack_dccp_packet() has an unique:
+
+ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
+
+ And nothing more is 'pulled' from the packet, depending on the content.
+ dh->dccph_doff, and/or dh->dccph_x ...)
+ So dccp_ack_seq() is happily reading stuff past the _dh buffer.
+
+BUG: KASAN: stack-out-of-bounds in nf_conntrack_dccp_packet+0x1134/0x11c0
+Read of size 4 at addr ffff000128f66e0c by task syz-executor.2/29371
+[..]
+
+Fix this by increasing the stack buffer to also include room for
+the extra sequence numbers and all the known dccp packet type headers,
+then pull again after the initial validation of the basic header.
+
+While at it, mark packets invalid that lack 48bit sequence bit but
+where RFC says the type MUST use them.
+
+Compile tested only.
+
+v2: first skb_header_pointer() now needs to adjust the size to
+ only pull the generic header. (Eric)
+
+Heads-up: I intend to remove dccp conntrack support later this year.
+
+Fixes: 2bc780499aa3 ("[NETFILTER]: nf_conntrack: add DCCP protocol support")
+Reported-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_proto_dccp.c | 52 +++++++++++++++++++++++--
+ 1 file changed, 49 insertions(+), 3 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
+index c1557d47ccd1e..d4fd626d2b8c3 100644
+--- a/net/netfilter/nf_conntrack_proto_dccp.c
++++ b/net/netfilter/nf_conntrack_proto_dccp.c
+@@ -432,9 +432,19 @@ static bool dccp_error(const struct dccp_hdr *dh,
+ struct sk_buff *skb, unsigned int dataoff,
+ const struct nf_hook_state *state)
+ {
++ static const unsigned long require_seq48 = 1 << DCCP_PKT_REQUEST |
++ 1 << DCCP_PKT_RESPONSE |
++ 1 << DCCP_PKT_CLOSEREQ |
++ 1 << DCCP_PKT_CLOSE |
++ 1 << DCCP_PKT_RESET |
++ 1 << DCCP_PKT_SYNC |
++ 1 << DCCP_PKT_SYNCACK;
+ unsigned int dccp_len = skb->len - dataoff;
+ unsigned int cscov;
+ const char *msg;
++ u8 type;
++
++ BUILD_BUG_ON(DCCP_PKT_INVALID >= BITS_PER_LONG);
+
+ if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) ||
+ dh->dccph_doff * 4 > dccp_len) {
+@@ -459,34 +469,70 @@ static bool dccp_error(const struct dccp_hdr *dh,
+ goto out_invalid;
+ }
+
+- if (dh->dccph_type >= DCCP_PKT_INVALID) {
++ type = dh->dccph_type;
++ if (type >= DCCP_PKT_INVALID) {
+ msg = "nf_ct_dccp: reserved packet type ";
+ goto out_invalid;
+ }
++
++ if (test_bit(type, &require_seq48) && !dh->dccph_x) {
++ msg = "nf_ct_dccp: type lacks 48bit sequence numbers";
++ goto out_invalid;
++ }
++
+ return false;
+ out_invalid:
+ nf_l4proto_log_invalid(skb, state, IPPROTO_DCCP, "%s", msg);
+ return true;
+ }
+
++struct nf_conntrack_dccp_buf {
++ struct dccp_hdr dh; /* generic header part */
++ struct dccp_hdr_ext ext; /* optional depending dh->dccph_x */
++ union { /* depends on header type */
++ struct dccp_hdr_ack_bits ack;
++ struct dccp_hdr_request req;
++ struct dccp_hdr_response response;
++ struct dccp_hdr_reset rst;
++ } u;
++};
++
++static struct dccp_hdr *
++dccp_header_pointer(const struct sk_buff *skb, int offset, const struct dccp_hdr *dh,
++ struct nf_conntrack_dccp_buf *buf)
++{
++ unsigned int hdrlen = __dccp_hdr_len(dh);
++
++ if (hdrlen > sizeof(*buf))
++ return NULL;
++
++ return skb_header_pointer(skb, offset, hdrlen, buf);
++}
++
+ int nf_conntrack_dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
+ unsigned int dataoff,
+ enum ip_conntrack_info ctinfo,
+ const struct nf_hook_state *state)
+ {
+ enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+- struct dccp_hdr _dh, *dh;
++ struct nf_conntrack_dccp_buf _dh;
+ u_int8_t type, old_state, new_state;
+ enum ct_dccp_roles role;
+ unsigned int *timeouts;
++ struct dccp_hdr *dh;
+
+- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
++ dh = skb_header_pointer(skb, dataoff, sizeof(*dh), &_dh.dh);
+ if (!dh)
+ return NF_DROP;
+
+ if (dccp_error(dh, skb, dataoff, state))
+ return -NF_ACCEPT;
+
++ /* pull again, including possible 48 bit sequences and subtype header */
++ dh = dccp_header_pointer(skb, dataoff, dh, &_dh);
++ if (!dh)
++ return NF_DROP;
++
+ type = dh->dccph_type;
+ if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh, state))
+ return -NF_ACCEPT;
+--
+2.39.2
+
--- /dev/null
+From f30c5dae6367b5251bdf2191e1949aea35c17a88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Jun 2023 11:23:46 +0000
+Subject: netfilter: nf_conntrack_sip: fix the ct_sip_parse_numerical_param()
+ return value.
+
+From: Ilia.Gavrilov <Ilia.Gavrilov@infotecs.ru>
+
+[ Upstream commit f188d30087480eab421cd8ca552fb15f55d57f4d ]
+
+ct_sip_parse_numerical_param() returns only 0 or 1 now.
+But process_register_request() and process_register_response() imply
+checking for a negative value if parsing of a numerical header parameter
+failed.
+The invocation in nf_nat_sip() looks correct:
+ if (ct_sip_parse_numerical_param(...) > 0 &&
+ ...) { ... }
+
+Make the return value of the function ct_sip_parse_numerical_param()
+a tristate to fix all the cases
+a) return 1 if value is found; *val is set
+b) return 0 if value is not found; *val is unchanged
+c) return -1 on error; *val is undefined
+
+Found by InfoTeCS on behalf of Linux Verification Center
+(linuxtesting.org) with SVACE.
+
+Fixes: 0f32a40fc91a ("[NETFILTER]: nf_conntrack_sip: create signalling expectations")
+Signed-off-by: Ilia.Gavrilov <Ilia.Gavrilov@infotecs.ru>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_sip.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
+index 77f5e82d8e3fe..d0eac27f6ba03 100644
+--- a/net/netfilter/nf_conntrack_sip.c
++++ b/net/netfilter/nf_conntrack_sip.c
+@@ -611,7 +611,7 @@ int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr,
+ start += strlen(name);
+ *val = simple_strtoul(start, &end, 0);
+ if (start == end)
+- return 0;
++ return -1;
+ if (matchoff && matchlen) {
+ *matchoff = start - dptr;
+ *matchlen = end - start;
+--
+2.39.2
+
--- /dev/null
+From 553ea2daafbf1d36fe7c01f16e0654f85c30fbf6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 09:43:13 -0700
+Subject: netlink: Add __sock_i_ino() for __netlink_diag_dump().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 25a9c8a4431c364f97f75558cb346d2ad3f53fbb ]
+
+syzbot reported a warning in __local_bh_enable_ip(). [0]
+
+Commit 8d61f926d420 ("netlink: fix potential deadlock in
+netlink_set_err()") converted read_lock(&nl_table_lock) to
+read_lock_irqsave() in __netlink_diag_dump() to prevent a deadlock.
+
+However, __netlink_diag_dump() calls sock_i_ino() that uses
+read_lock_bh() and read_unlock_bh(). If CONFIG_TRACE_IRQFLAGS=y,
+read_unlock_bh() finally enables IRQ even though it should stay
+disabled until the following read_unlock_irqrestore().
+
+Using read_lock() in sock_i_ino() would trigger a lockdep splat
+in another place that was fixed in commit f064af1e500a ("net: fix
+a lockdep splat"), so let's add __sock_i_ino() that would be safe
+to use under BH disabled.
+
+[0]:
+WARNING: CPU: 0 PID: 5012 at kernel/softirq.c:376 __local_bh_enable_ip+0xbe/0x130 kernel/softirq.c:376
+Modules linked in:
+CPU: 0 PID: 5012 Comm: syz-executor487 Not tainted 6.4.0-rc7-syzkaller-00202-g6f68fc395f49 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023
+RIP: 0010:__local_bh_enable_ip+0xbe/0x130 kernel/softirq.c:376
+Code: 45 bf 01 00 00 00 e8 91 5b 0a 00 e8 3c 15 3d 00 fb 65 8b 05 ec e9 b5 7e 85 c0 74 58 5b 5d c3 65 8b 05 b2 b6 b4 7e 85 c0 75 a2 <0f> 0b eb 9e e8 89 15 3d 00 eb 9f 48 89 ef e8 6f 49 18 00 eb a8 0f
+RSP: 0018:ffffc90003a1f3d0 EFLAGS: 00010046
+RAX: 0000000000000000 RBX: 0000000000000201 RCX: 1ffffffff1cf5996
+RDX: 0000000000000000 RSI: 0000000000000201 RDI: ffffffff8805c6f3
+RBP: ffffffff8805c6f3 R08: 0000000000000001 R09: ffff8880152b03a3
+R10: ffffed1002a56074 R11: 0000000000000005 R12: 00000000000073e4
+R13: dffffc0000000000 R14: 0000000000000002 R15: 0000000000000000
+FS: 0000555556726300(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 000000007c646000 CR4: 00000000003506f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ sock_i_ino+0x83/0xa0 net/core/sock.c:2559
+ __netlink_diag_dump+0x45c/0x790 net/netlink/diag.c:171
+ netlink_diag_dump+0xd6/0x230 net/netlink/diag.c:207
+ netlink_dump+0x570/0xc50 net/netlink/af_netlink.c:2269
+ __netlink_dump_start+0x64b/0x910 net/netlink/af_netlink.c:2374
+ netlink_dump_start include/linux/netlink.h:329 [inline]
+ netlink_diag_handler_dump+0x1ae/0x250 net/netlink/diag.c:238
+ __sock_diag_cmd net/core/sock_diag.c:238 [inline]
+ sock_diag_rcv_msg+0x31e/0x440 net/core/sock_diag.c:269
+ netlink_rcv_skb+0x165/0x440 net/netlink/af_netlink.c:2547
+ sock_diag_rcv+0x2a/0x40 net/core/sock_diag.c:280
+ netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline]
+ netlink_unicast+0x547/0x7f0 net/netlink/af_netlink.c:1365
+ netlink_sendmsg+0x925/0xe30 net/netlink/af_netlink.c:1914
+ sock_sendmsg_nosec net/socket.c:724 [inline]
+ sock_sendmsg+0xde/0x190 net/socket.c:747
+ ____sys_sendmsg+0x71c/0x900 net/socket.c:2503
+ ___sys_sendmsg+0x110/0x1b0 net/socket.c:2557
+ __sys_sendmsg+0xf7/0x1c0 net/socket.c:2586
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+RIP: 0033:0x7f5303aaabb9
+Code: 28 c3 e8 2a 14 00 00 66 2e 0f 1f 84 00 00 00 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007ffc7506e548 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f5303aaabb9
+RDX: 0000000000000000 RSI: 0000000020000180 RDI: 0000000000000003
+RBP: 00007f5303a6ed60 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 00007f5303a6edf0
+R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+ </TASK>
+
+Fixes: 8d61f926d420 ("netlink: fix potential deadlock in netlink_set_err()")
+Reported-by: syzbot+5da61cf6a9bc1902d422@syzkaller.appspotmail.com
+Link: https://syzkaller.appspot.com/bug?extid=5da61cf6a9bc1902d422
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/r/20230626164313.52528-1-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 1 +
+ net/core/sock.c | 17 ++++++++++++++---
+ net/netlink/diag.c | 2 +-
+ 3 files changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index f0654c44acf5f..81ad7fa03b73a 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -2100,6 +2100,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent)
+ }
+
+ kuid_t sock_i_uid(struct sock *sk);
++unsigned long __sock_i_ino(struct sock *sk);
+ unsigned long sock_i_ino(struct sock *sk);
+
+ static inline kuid_t sock_net_uid(const struct net *net, const struct sock *sk)
+diff --git a/net/core/sock.c b/net/core/sock.c
+index b34c48f802e98..a009e1fac4a69 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -2555,13 +2555,24 @@ kuid_t sock_i_uid(struct sock *sk)
+ }
+ EXPORT_SYMBOL(sock_i_uid);
+
+-unsigned long sock_i_ino(struct sock *sk)
++unsigned long __sock_i_ino(struct sock *sk)
+ {
+ unsigned long ino;
+
+- read_lock_bh(&sk->sk_callback_lock);
++ read_lock(&sk->sk_callback_lock);
+ ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0;
+- read_unlock_bh(&sk->sk_callback_lock);
++ read_unlock(&sk->sk_callback_lock);
++ return ino;
++}
++EXPORT_SYMBOL(__sock_i_ino);
++
++unsigned long sock_i_ino(struct sock *sk)
++{
++ unsigned long ino;
++
++ local_bh_disable();
++ ino = __sock_i_ino(sk);
++ local_bh_enable();
+ return ino;
+ }
+ EXPORT_SYMBOL(sock_i_ino);
+diff --git a/net/netlink/diag.c b/net/netlink/diag.c
+index 4143b2ea4195a..e4f21b1067bcc 100644
+--- a/net/netlink/diag.c
++++ b/net/netlink/diag.c
+@@ -168,7 +168,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
+ NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq,
+ NLM_F_MULTI,
+- sock_i_ino(sk)) < 0) {
++ __sock_i_ino(sk)) < 0) {
+ ret = 1;
+ break;
+ }
+--
+2.39.2
+
--- /dev/null
+From 795a46c3bab166a64d13c1bd5c1a216548b649fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 17:47:20 +0000
+Subject: netlink: do not hard code device address lenth in fdb dumps
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit aa5406950726e336c5c9585b09799a734b6e77bf ]
+
+syzbot reports that some netdev devices do not have a six bytes
+address [1]
+
+Replace ETH_ALEN by dev->addr_len.
+
+[1] (Case of a device where dev->addr_len = 4)
+
+BUG: KMSAN: kernel-infoleak in instrument_copy_to_user include/linux/instrumented.h:114 [inline]
+BUG: KMSAN: kernel-infoleak in copyout+0xb8/0x100 lib/iov_iter.c:169
+instrument_copy_to_user include/linux/instrumented.h:114 [inline]
+copyout+0xb8/0x100 lib/iov_iter.c:169
+_copy_to_iter+0x6d8/0x1d00 lib/iov_iter.c:536
+copy_to_iter include/linux/uio.h:206 [inline]
+simple_copy_to_iter+0x68/0xa0 net/core/datagram.c:513
+__skb_datagram_iter+0x123/0xdc0 net/core/datagram.c:419
+skb_copy_datagram_iter+0x5c/0x200 net/core/datagram.c:527
+skb_copy_datagram_msg include/linux/skbuff.h:3960 [inline]
+netlink_recvmsg+0x4ae/0x15a0 net/netlink/af_netlink.c:1970
+sock_recvmsg_nosec net/socket.c:1019 [inline]
+sock_recvmsg net/socket.c:1040 [inline]
+____sys_recvmsg+0x283/0x7f0 net/socket.c:2722
+___sys_recvmsg+0x223/0x840 net/socket.c:2764
+do_recvmmsg+0x4f9/0xfd0 net/socket.c:2858
+__sys_recvmmsg net/socket.c:2937 [inline]
+__do_sys_recvmmsg net/socket.c:2960 [inline]
+__se_sys_recvmmsg net/socket.c:2953 [inline]
+__x64_sys_recvmmsg+0x397/0x490 net/socket.c:2953
+do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
+entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Uninit was stored to memory at:
+__nla_put lib/nlattr.c:1009 [inline]
+nla_put+0x1c6/0x230 lib/nlattr.c:1067
+nlmsg_populate_fdb_fill+0x2b8/0x600 net/core/rtnetlink.c:4071
+nlmsg_populate_fdb net/core/rtnetlink.c:4418 [inline]
+ndo_dflt_fdb_dump+0x616/0x840 net/core/rtnetlink.c:4456
+rtnl_fdb_dump+0x14ff/0x1fc0 net/core/rtnetlink.c:4629
+netlink_dump+0x9d1/0x1310 net/netlink/af_netlink.c:2268
+netlink_recvmsg+0xc5c/0x15a0 net/netlink/af_netlink.c:1995
+sock_recvmsg_nosec+0x7a/0x120 net/socket.c:1019
+____sys_recvmsg+0x664/0x7f0 net/socket.c:2720
+___sys_recvmsg+0x223/0x840 net/socket.c:2764
+do_recvmmsg+0x4f9/0xfd0 net/socket.c:2858
+__sys_recvmmsg net/socket.c:2937 [inline]
+__do_sys_recvmmsg net/socket.c:2960 [inline]
+__se_sys_recvmmsg net/socket.c:2953 [inline]
+__x64_sys_recvmmsg+0x397/0x490 net/socket.c:2953
+do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
+entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Uninit was created at:
+slab_post_alloc_hook+0x12d/0xb60 mm/slab.h:716
+slab_alloc_node mm/slub.c:3451 [inline]
+__kmem_cache_alloc_node+0x4ff/0x8b0 mm/slub.c:3490
+kmalloc_trace+0x51/0x200 mm/slab_common.c:1057
+kmalloc include/linux/slab.h:559 [inline]
+__hw_addr_create net/core/dev_addr_lists.c:60 [inline]
+__hw_addr_add_ex+0x2e5/0x9e0 net/core/dev_addr_lists.c:118
+__dev_mc_add net/core/dev_addr_lists.c:867 [inline]
+dev_mc_add+0x9a/0x130 net/core/dev_addr_lists.c:885
+igmp6_group_added+0x267/0xbc0 net/ipv6/mcast.c:680
+ipv6_mc_up+0x296/0x3b0 net/ipv6/mcast.c:2754
+ipv6_mc_remap+0x1e/0x30 net/ipv6/mcast.c:2708
+addrconf_type_change net/ipv6/addrconf.c:3731 [inline]
+addrconf_notify+0x4d3/0x1d90 net/ipv6/addrconf.c:3699
+notifier_call_chain kernel/notifier.c:93 [inline]
+raw_notifier_call_chain+0xe4/0x430 kernel/notifier.c:461
+call_netdevice_notifiers_info net/core/dev.c:1935 [inline]
+call_netdevice_notifiers_extack net/core/dev.c:1973 [inline]
+call_netdevice_notifiers+0x1ee/0x2d0 net/core/dev.c:1987
+bond_enslave+0xccd/0x53f0 drivers/net/bonding/bond_main.c:1906
+do_set_master net/core/rtnetlink.c:2626 [inline]
+rtnl_newlink_create net/core/rtnetlink.c:3460 [inline]
+__rtnl_newlink net/core/rtnetlink.c:3660 [inline]
+rtnl_newlink+0x378c/0x40e0 net/core/rtnetlink.c:3673
+rtnetlink_rcv_msg+0x16a6/0x1840 net/core/rtnetlink.c:6395
+netlink_rcv_skb+0x371/0x650 net/netlink/af_netlink.c:2546
+rtnetlink_rcv+0x34/0x40 net/core/rtnetlink.c:6413
+netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline]
+netlink_unicast+0xf28/0x1230 net/netlink/af_netlink.c:1365
+netlink_sendmsg+0x122f/0x13d0 net/netlink/af_netlink.c:1913
+sock_sendmsg_nosec net/socket.c:724 [inline]
+sock_sendmsg net/socket.c:747 [inline]
+____sys_sendmsg+0x999/0xd50 net/socket.c:2503
+___sys_sendmsg+0x28d/0x3c0 net/socket.c:2557
+__sys_sendmsg net/socket.c:2586 [inline]
+__do_sys_sendmsg net/socket.c:2595 [inline]
+__se_sys_sendmsg net/socket.c:2593 [inline]
+__x64_sys_sendmsg+0x304/0x490 net/socket.c:2593
+do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
+entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Bytes 2856-2857 of 3500 are uninitialized
+Memory access of size 3500 starts at ffff888018d99104
+Data copied to user address 0000000020000480
+
+Fixes: d83b06036048 ("net: add fdb generic dump routine")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://lore.kernel.org/r/20230621174720.1845040-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/rtnetlink.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index bbecc31a2703f..f21254a9cd373 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -4093,7 +4093,7 @@ static int nlmsg_populate_fdb_fill(struct sk_buff *skb,
+ ndm->ndm_ifindex = dev->ifindex;
+ ndm->ndm_state = ndm_state;
+
+- if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr))
++ if (nla_put(skb, NDA_LLADDR, dev->addr_len, addr))
+ goto nla_put_failure;
+ if (vid)
+ if (nla_put(skb, NDA_VLAN, sizeof(u16), &vid))
+@@ -4107,10 +4107,10 @@ static int nlmsg_populate_fdb_fill(struct sk_buff *skb,
+ return -EMSGSIZE;
+ }
+
+-static inline size_t rtnl_fdb_nlmsg_size(void)
++static inline size_t rtnl_fdb_nlmsg_size(const struct net_device *dev)
+ {
+ return NLMSG_ALIGN(sizeof(struct ndmsg)) +
+- nla_total_size(ETH_ALEN) + /* NDA_LLADDR */
++ nla_total_size(dev->addr_len) + /* NDA_LLADDR */
+ nla_total_size(sizeof(u16)) + /* NDA_VLAN */
+ 0;
+ }
+@@ -4122,7 +4122,7 @@ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type,
+ struct sk_buff *skb;
+ int err = -ENOBUFS;
+
+- skb = nlmsg_new(rtnl_fdb_nlmsg_size(), GFP_ATOMIC);
++ skb = nlmsg_new(rtnl_fdb_nlmsg_size(dev), GFP_ATOMIC);
+ if (!skb)
+ goto errout;
+
+--
+2.39.2
+
--- /dev/null
+From 394bff7c696309b1f9425ff5152f7c169959a39a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 15:43:37 +0000
+Subject: netlink: fix potential deadlock in netlink_set_err()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 8d61f926d42045961e6b65191c09e3678d86a9cf ]
+
+syzbot reported a possible deadlock in netlink_set_err() [1]
+
+A similar issue was fixed in commit 1d482e666b8e ("netlink: disable IRQs
+for netlink_lock_table()") in netlink_lock_table()
+
+This patch adds IRQ safety to netlink_set_err() and __netlink_diag_dump()
+which were not covered by cited commit.
+
+[1]
+
+WARNING: possible irq lock inversion dependency detected
+6.4.0-rc6-syzkaller-00240-g4e9f0ec38852 #0 Not tainted
+
+syz-executor.2/23011 just changed the state of lock:
+ffffffff8e1a7a58 (nl_table_lock){.+.?}-{2:2}, at: netlink_set_err+0x2e/0x3a0 net/netlink/af_netlink.c:1612
+but this lock was taken by another, SOFTIRQ-safe lock in the past:
+ (&local->queue_stop_reason_lock){..-.}-{2:2}
+
+and interrupts could create inverse lock ordering between them.
+
+other info that might help us debug this:
+ Possible interrupt unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(nl_table_lock);
+ local_irq_disable();
+ lock(&local->queue_stop_reason_lock);
+ lock(nl_table_lock);
+ <Interrupt>
+ lock(&local->queue_stop_reason_lock);
+
+ *** DEADLOCK ***
+
+Fixes: 1d482e666b8e ("netlink: disable IRQs for netlink_lock_table()")
+Reported-by: syzbot+a7d200a347f912723e5c@syzkaller.appspotmail.com
+Link: https://syzkaller.appspot.com/bug?extid=a7d200a347f912723e5c
+Link: https://lore.kernel.org/netdev/000000000000e38d1605fea5747e@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Johannes Berg <johannes.berg@intel.com>
+Link: https://lore.kernel.org/r/20230621154337.1668594-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 5 +++--
+ net/netlink/diag.c | 5 +++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 717e27a4b66a0..f4adccb8d49a2 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1600,6 +1600,7 @@ static int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p)
+ int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code)
+ {
+ struct netlink_set_err_data info;
++ unsigned long flags;
+ struct sock *sk;
+ int ret = 0;
+
+@@ -1609,12 +1610,12 @@ int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code)
+ /* sk->sk_err wants a positive error value */
+ info.code = -code;
+
+- read_lock(&nl_table_lock);
++ read_lock_irqsave(&nl_table_lock, flags);
+
+ sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list)
+ ret += do_one_set_err(sk, &info);
+
+- read_unlock(&nl_table_lock);
++ read_unlock_irqrestore(&nl_table_lock, flags);
+ return ret;
+ }
+ EXPORT_SYMBOL(netlink_set_err);
+diff --git a/net/netlink/diag.c b/net/netlink/diag.c
+index c6255eac305c7..4143b2ea4195a 100644
+--- a/net/netlink/diag.c
++++ b/net/netlink/diag.c
+@@ -94,6 +94,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
+ struct net *net = sock_net(skb->sk);
+ struct netlink_diag_req *req;
+ struct netlink_sock *nlsk;
++ unsigned long flags;
+ struct sock *sk;
+ int num = 2;
+ int ret = 0;
+@@ -152,7 +153,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
+ num++;
+
+ mc_list:
+- read_lock(&nl_table_lock);
++ read_lock_irqsave(&nl_table_lock, flags);
+ sk_for_each_bound(sk, &tbl->mc_list) {
+ if (sk_hashed(sk))
+ continue;
+@@ -173,7 +174,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
+ }
+ num++;
+ }
+- read_unlock(&nl_table_lock);
++ read_unlock_irqrestore(&nl_table_lock, flags);
+
+ done:
+ cb->args[0] = num;
+--
+2.39.2
+
--- /dev/null
+From 179b605ae74ce1a191161aa4c0cfd9497803abfe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 May 2023 13:52:04 +0200
+Subject: nfc: llcp: fix possible use of uninitialized variable in
+ nfc_llcp_send_connect()
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 0d9b41daa5907756a31772d8af8ac5ff25cf17c1 ]
+
+If sock->service_name is NULL, the local variable
+service_name_tlv_length will not be assigned by nfc_llcp_build_tlv(),
+later leading to using value frmo the stack. Smatch warning:
+
+ net/nfc/llcp_commands.c:442 nfc_llcp_send_connect() error: uninitialized symbol 'service_name_tlv_length'.
+
+Fixes: de9e5aeb4f40 ("NFC: llcp: Fix usage of llcp_add_tlv()")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_commands.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
+index 41e3a20c89355..cdb001de06928 100644
+--- a/net/nfc/llcp_commands.c
++++ b/net/nfc/llcp_commands.c
+@@ -390,7 +390,8 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
+ const u8 *service_name_tlv = NULL;
+ const u8 *miux_tlv = NULL;
+ const u8 *rw_tlv = NULL;
+- u8 service_name_tlv_length, miux_tlv_length, rw_tlv_length, rw;
++ u8 service_name_tlv_length = 0;
++ u8 miux_tlv_length, rw_tlv_length, rw;
+ int err;
+ u16 size = 0;
+ __be16 miux;
+--
+2.39.2
+
--- /dev/null
+From 8b2eddd645b421480b67bbe87ae8f8cf2adb13f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Jun 2023 17:32:25 -0400
+Subject: NFSv4.1: freeze the session table upon receiving NFS4ERR_BADSESSION
+
+From: Olga Kornievskaia <kolga@netapp.com>
+
+[ Upstream commit c907e72f58ed979a24a9fdcadfbc447c51d5e509 ]
+
+When the client received NFS4ERR_BADSESSION, it schedules recovery
+and start the state manager thread which in turn freezes the
+session table and does not allow for any new requests to use the
+no-longer valid session. However, it is possible that before
+the state manager thread runs, a new operation would use the
+released slot that received BADSESSION and was therefore not
+updated its sequence number. Such re-use of the slot can lead
+the application errors.
+
+Fixes: 5c441544f045 ("NFSv4.x: Handle bad/dead sessions correctly in nfs41_sequence_process()")
+Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4proc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 5607b1e2b8212..23a23387211ba 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -921,6 +921,7 @@ static int nfs41_sequence_process(struct rpc_task *task,
+ out_noaction:
+ return ret;
+ session_recover:
++ set_bit(NFS4_SLOT_TBL_DRAINING, &session->fc_slot_table.slot_tbl_state);
+ nfs4_schedule_session_recovery(session, status);
+ dprintk("%s ERROR: %d Reset session\n", __func__, status);
+ nfs41_sequence_free_slot(res);
+--
+2.39.2
+
--- /dev/null
+From 20a901a68b41eed3ea9cfd10d79e36aa16b42c0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 11:19:46 +0000
+Subject: NFSv4.2: fix wrong shrinker_id
+
+From: Qi Zheng <zhengqi.arch@bytedance.com>
+
+[ Upstream commit 7f7ab336898f281e58540ef781a8fb375acc32a9 ]
+
+Currently, the list_lru::shrinker_id corresponding to the nfs4_xattr
+shrinkers is wrong:
+
+>>> prog["nfs4_xattr_cache_lru"].shrinker_id
+(int)0
+>>> prog["nfs4_xattr_entry_lru"].shrinker_id
+(int)0
+>>> prog["nfs4_xattr_large_entry_lru"].shrinker_id
+(int)0
+>>> prog["nfs4_xattr_cache_shrinker"].id
+(int)18
+>>> prog["nfs4_xattr_entry_shrinker"].id
+(int)19
+>>> prog["nfs4_xattr_large_entry_shrinker"].id
+(int)20
+
+This is not what we expect, which will cause these shrinkers
+not to be found in shrink_slab_memcg().
+
+We should assign shrinker::id before calling list_lru_init_memcg(),
+so that the corresponding list_lru::shrinker_id will be assigned
+the correct value like below:
+
+>>> prog["nfs4_xattr_cache_lru"].shrinker_id
+(int)16
+>>> prog["nfs4_xattr_entry_lru"].shrinker_id
+(int)17
+>>> prog["nfs4_xattr_large_entry_lru"].shrinker_id
+(int)18
+>>> prog["nfs4_xattr_cache_shrinker"].id
+(int)16
+>>> prog["nfs4_xattr_entry_shrinker"].id
+(int)17
+>>> prog["nfs4_xattr_large_entry_shrinker"].id
+(int)18
+
+So just do it.
+
+Fixes: 95ad37f90c33 ("NFSv4.2: add client side xattr caching.")
+Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs42xattr.c | 79 +++++++++++++++++++++++++--------------------
+ 1 file changed, 44 insertions(+), 35 deletions(-)
+
+diff --git a/fs/nfs/nfs42xattr.c b/fs/nfs/nfs42xattr.c
+index 76ae118342066..911f634ba3da7 100644
+--- a/fs/nfs/nfs42xattr.c
++++ b/fs/nfs/nfs42xattr.c
+@@ -991,6 +991,29 @@ static void nfs4_xattr_cache_init_once(void *p)
+ INIT_LIST_HEAD(&cache->dispose);
+ }
+
++static int nfs4_xattr_shrinker_init(struct shrinker *shrinker,
++ struct list_lru *lru, const char *name)
++{
++ int ret = 0;
++
++ ret = register_shrinker(shrinker, name);
++ if (ret)
++ return ret;
++
++ ret = list_lru_init_memcg(lru, shrinker);
++ if (ret)
++ unregister_shrinker(shrinker);
++
++ return ret;
++}
++
++static void nfs4_xattr_shrinker_destroy(struct shrinker *shrinker,
++ struct list_lru *lru)
++{
++ unregister_shrinker(shrinker);
++ list_lru_destroy(lru);
++}
++
+ int __init nfs4_xattr_cache_init(void)
+ {
+ int ret = 0;
+@@ -1002,44 +1025,30 @@ int __init nfs4_xattr_cache_init(void)
+ if (nfs4_xattr_cache_cachep == NULL)
+ return -ENOMEM;
+
+- ret = list_lru_init_memcg(&nfs4_xattr_large_entry_lru,
+- &nfs4_xattr_large_entry_shrinker);
+- if (ret)
+- goto out4;
+-
+- ret = list_lru_init_memcg(&nfs4_xattr_entry_lru,
+- &nfs4_xattr_entry_shrinker);
+- if (ret)
+- goto out3;
+-
+- ret = list_lru_init_memcg(&nfs4_xattr_cache_lru,
+- &nfs4_xattr_cache_shrinker);
+- if (ret)
+- goto out2;
+-
+- ret = register_shrinker(&nfs4_xattr_cache_shrinker, "nfs-xattr_cache");
++ ret = nfs4_xattr_shrinker_init(&nfs4_xattr_cache_shrinker,
++ &nfs4_xattr_cache_lru,
++ "nfs-xattr_cache");
+ if (ret)
+ goto out1;
+
+- ret = register_shrinker(&nfs4_xattr_entry_shrinker, "nfs-xattr_entry");
++ ret = nfs4_xattr_shrinker_init(&nfs4_xattr_entry_shrinker,
++ &nfs4_xattr_entry_lru,
++ "nfs-xattr_entry");
+ if (ret)
+- goto out;
++ goto out2;
+
+- ret = register_shrinker(&nfs4_xattr_large_entry_shrinker,
+- "nfs-xattr_large_entry");
++ ret = nfs4_xattr_shrinker_init(&nfs4_xattr_large_entry_shrinker,
++ &nfs4_xattr_large_entry_lru,
++ "nfs-xattr_large_entry");
+ if (!ret)
+ return 0;
+
+- unregister_shrinker(&nfs4_xattr_entry_shrinker);
+-out:
+- unregister_shrinker(&nfs4_xattr_cache_shrinker);
+-out1:
+- list_lru_destroy(&nfs4_xattr_cache_lru);
++ nfs4_xattr_shrinker_destroy(&nfs4_xattr_entry_shrinker,
++ &nfs4_xattr_entry_lru);
+ out2:
+- list_lru_destroy(&nfs4_xattr_entry_lru);
+-out3:
+- list_lru_destroy(&nfs4_xattr_large_entry_lru);
+-out4:
++ nfs4_xattr_shrinker_destroy(&nfs4_xattr_cache_shrinker,
++ &nfs4_xattr_cache_lru);
++out1:
+ kmem_cache_destroy(nfs4_xattr_cache_cachep);
+
+ return ret;
+@@ -1047,11 +1056,11 @@ int __init nfs4_xattr_cache_init(void)
+
+ void nfs4_xattr_cache_exit(void)
+ {
+- unregister_shrinker(&nfs4_xattr_large_entry_shrinker);
+- unregister_shrinker(&nfs4_xattr_entry_shrinker);
+- unregister_shrinker(&nfs4_xattr_cache_shrinker);
+- list_lru_destroy(&nfs4_xattr_large_entry_lru);
+- list_lru_destroy(&nfs4_xattr_entry_lru);
+- list_lru_destroy(&nfs4_xattr_cache_lru);
++ nfs4_xattr_shrinker_destroy(&nfs4_xattr_large_entry_shrinker,
++ &nfs4_xattr_large_entry_lru);
++ nfs4_xattr_shrinker_destroy(&nfs4_xattr_entry_shrinker,
++ &nfs4_xattr_entry_lru);
++ nfs4_xattr_shrinker_destroy(&nfs4_xattr_cache_shrinker,
++ &nfs4_xattr_cache_lru);
+ kmem_cache_destroy(nfs4_xattr_cache_cachep);
+ }
+--
+2.39.2
+
--- /dev/null
+From 0a0fa17652551f1dd0c8789864b1642c5c122e96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Apr 2023 00:31:14 -0700
+Subject: nvme-core: add missing fault-injection cleanup
+
+From: Chaitanya Kulkarni <kch@nvidia.com>
+
+[ Upstream commit 3a12a0b868a512fcada564699d00f5e652c0998c ]
+
+Add missing fault-injection cleanup in nvme_init_ctrl() in the error
+unwind path that also fixes following message for blktests:-
+
+linux-block (for-next) # grep debugfs debugfs-err.log
+[ 147.853464] debugfs: Directory 'nvme1' with parent '/' already present!
+[ 147.853973] nvme1: failed to create debugfs attr
+[ 148.802490] debugfs: Directory 'nvme1' with parent '/' already present!
+[ 148.803244] nvme1: failed to create debugfs attr
+[ 148.877304] debugfs: Directory 'nvme1' with parent '/' already present!
+[ 148.877775] nvme1: failed to create debugfs attr
+[ 149.816652] debugfs: Directory 'nvme1' with parent '/' already present!
+[ 149.818011] nvme1: failed to create debugfs attr
+
+Signed-off-by: Chaitanya Kulkarni <kch@nvidia.com>
+Tested-by: Yi Zhang <yi.zhang@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Stable-dep-of: 7ed5cf8e6d9b ("nvme-core: fix dev_pm_qos memleak")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index b03f5a34b1ee0..f07fd2fed3f9d 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -5249,6 +5249,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
+
+ return 0;
+ out_free_cdev:
++ nvme_fault_inject_fini(&ctrl->fault_inject);
+ cdev_device_del(&ctrl->cdev, ctrl->device);
+ out_free_name:
+ nvme_put_ctrl(ctrl);
+--
+2.39.2
+
--- /dev/null
+From 1c56f20a2f2a76d43433add23e7f1910efae153e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Apr 2023 00:31:15 -0700
+Subject: nvme-core: fix dev_pm_qos memleak
+
+From: Chaitanya Kulkarni <kch@nvidia.com>
+
+[ Upstream commit 7ed5cf8e6d9bfb6a78d0471317edff14f0f2b4dd ]
+
+Call dev_pm_qos_hide_latency_tolerance() in the error unwind patch to
+avoid following kmemleak:-
+
+blktests (master) # kmemleak-clear; ./check nvme/044;
+blktests (master) # kmemleak-scan ; kmemleak-show
+nvme/044 (Test bi-directional authentication) [passed]
+ runtime 2.111s ... 2.124s
+unreferenced object 0xffff888110c46240 (size 96):
+ comm "nvme", pid 33461, jiffies 4345365353 (age 75.586s)
+ hex dump (first 32 bytes):
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ backtrace:
+ [<0000000069ac2cec>] kmalloc_trace+0x25/0x90
+ [<000000006acc66d5>] dev_pm_qos_update_user_latency_tolerance+0x6f/0x100
+ [<00000000cc376ea7>] nvme_init_ctrl+0x38e/0x410 [nvme_core]
+ [<000000007df61b4b>] 0xffffffffc05e88b3
+ [<00000000d152b985>] 0xffffffffc05744cb
+ [<00000000f04a4041>] vfs_write+0xc5/0x3c0
+ [<00000000f9491baf>] ksys_write+0x5f/0xe0
+ [<000000001c46513d>] do_syscall_64+0x3b/0x90
+ [<00000000ecf348fe>] entry_SYSCALL_64_after_hwframe+0x72/0xdc
+
+Link: https://lore.kernel.org/linux-nvme/CAHj4cs-nDaKzMx2txO4dbE+Mz9ePwLtU0e3egz+StmzOUgWUrA@mail.gmail.com/
+Fixes: f50fff73d620 ("nvme: implement In-Band authentication")
+Signed-off-by: Chaitanya Kulkarni <kch@nvidia.com>
+Tested-by: Yi Zhang <yi.zhang@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index f07fd2fed3f9d..8d8403b65e1b3 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -5250,6 +5250,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
+ return 0;
+ out_free_cdev:
+ nvme_fault_inject_fini(&ctrl->fault_inject);
++ dev_pm_qos_hide_latency_tolerance(ctrl->device);
+ cdev_device_del(&ctrl->cdev, ctrl->device);
+ out_free_name:
+ nvme_put_ctrl(ctrl);
+--
+2.39.2
+
--- /dev/null
+From 97b733a3fbb0d2506192333588862a00ca26c14f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Apr 2023 00:31:13 -0700
+Subject: nvme-core: fix memory leak in dhchap_ctrl_secret
+
+From: Chaitanya Kulkarni <kch@nvidia.com>
+
+[ Upstream commit 99c2dcc8ffc24e210a3aa05c204d92f3ef460b05 ]
+
+Free dhchap_secret in nvme_ctrl_dhchap_ctrl_secret_store() before we
+return when nvme_auth_generate_key() returns error.
+
+Fixes: f50fff73d620 ("nvme: implement In-Band authentication")
+Signed-off-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 8a706ca1b3e14..b03f5a34b1ee0 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -3929,8 +3929,10 @@ static ssize_t nvme_ctrl_dhchap_ctrl_secret_store(struct device *dev,
+ int ret;
+
+ ret = nvme_auth_generate_key(dhchap_secret, &key);
+- if (ret)
++ if (ret) {
++ kfree(dhchap_secret);
+ return ret;
++ }
+ kfree(opts->dhchap_ctrl_secret);
+ opts->dhchap_ctrl_secret = dhchap_secret;
+ ctrl_key = ctrl->ctrl_key;
+@@ -3938,7 +3940,8 @@ static ssize_t nvme_ctrl_dhchap_ctrl_secret_store(struct device *dev,
+ ctrl->ctrl_key = key;
+ mutex_unlock(&ctrl->dhchap_auth_mutex);
+ nvme_auth_free_key(ctrl_key);
+- }
++ } else
++ kfree(dhchap_secret);
+ /* Start re-authentication */
+ dev_info(ctrl->device, "re-authenticating controller\n");
+ queue_work(nvme_wq, &ctrl->dhchap_auth_work);
+--
+2.39.2
+
--- /dev/null
+From 646d4c0eb4f66d3aa46f8ee651f44058ff221a9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Apr 2023 00:31:12 -0700
+Subject: nvme-core: fix memory leak in dhchap_secret_store
+
+From: Chaitanya Kulkarni <kch@nvidia.com>
+
+[ Upstream commit a836ca33c5b07d34dd5347af9f64d25651d12674 ]
+
+Free dhchap_secret in nvme_ctrl_dhchap_secret_store() before we return
+fix following kmemleack:-
+
+unreferenced object 0xffff8886376ea800 (size 64):
+ comm "check", pid 22048, jiffies 4344316705 (age 92.199s)
+ hex dump (first 32 bytes):
+ 44 48 48 43 2d 31 3a 30 30 3a 6e 78 72 35 4b 67 DHHC-1:00:nxr5Kg
+ 75 58 34 75 6f 41 78 73 4a 61 34 63 2f 68 75 4c uX4uoAxsJa4c/huL
+ backtrace:
+ [<0000000030ce5d4b>] __kmalloc+0x4b/0x130
+ [<000000009be1cdc1>] nvme_ctrl_dhchap_secret_store+0x8f/0x160 [nvme_core]
+ [<00000000ac06c96a>] kernfs_fop_write_iter+0x12b/0x1c0
+ [<00000000437e7ced>] vfs_write+0x2ba/0x3c0
+ [<00000000f9491baf>] ksys_write+0x5f/0xe0
+ [<000000001c46513d>] do_syscall_64+0x3b/0x90
+ [<00000000ecf348fe>] entry_SYSCALL_64_after_hwframe+0x72/0xdc
+unreferenced object 0xffff8886376eaf00 (size 64):
+ comm "check", pid 22048, jiffies 4344316736 (age 92.168s)
+ hex dump (first 32 bytes):
+ 44 48 48 43 2d 31 3a 30 30 3a 6e 78 72 35 4b 67 DHHC-1:00:nxr5Kg
+ 75 58 34 75 6f 41 78 73 4a 61 34 63 2f 68 75 4c uX4uoAxsJa4c/huL
+ backtrace:
+ [<0000000030ce5d4b>] __kmalloc+0x4b/0x130
+ [<000000009be1cdc1>] nvme_ctrl_dhchap_secret_store+0x8f/0x160 [nvme_core]
+ [<00000000ac06c96a>] kernfs_fop_write_iter+0x12b/0x1c0
+ [<00000000437e7ced>] vfs_write+0x2ba/0x3c0
+ [<00000000f9491baf>] ksys_write+0x5f/0xe0
+ [<000000001c46513d>] do_syscall_64+0x3b/0x90
+ [<00000000ecf348fe>] entry_SYSCALL_64_after_hwframe+0x72/0xdc
+
+Fixes: f50fff73d620 ("nvme: implement In-Band authentication")
+Signed-off-by: Chaitanya Kulkarni <kch@nvidia.com>
+Tested-by: Yi Zhang <yi.zhang@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 8a632bf7f5a8f..8a706ca1b3e14 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -3872,8 +3872,10 @@ static ssize_t nvme_ctrl_dhchap_secret_store(struct device *dev,
+ int ret;
+
+ ret = nvme_auth_generate_key(dhchap_secret, &key);
+- if (ret)
++ if (ret) {
++ kfree(dhchap_secret);
+ return ret;
++ }
+ kfree(opts->dhchap_secret);
+ opts->dhchap_secret = dhchap_secret;
+ host_key = ctrl->host_key;
+@@ -3881,7 +3883,8 @@ static ssize_t nvme_ctrl_dhchap_secret_store(struct device *dev,
+ ctrl->host_key = key;
+ mutex_unlock(&ctrl->dhchap_auth_mutex);
+ nvme_auth_free_key(host_key);
+- }
++ } else
++ kfree(dhchap_secret);
+ /* Start re-authentication */
+ dev_info(ctrl->device, "re-authenticating controller\n");
+ queue_work(nvme_wq, &ctrl->dhchap_auth_work);
+--
+2.39.2
+
--- /dev/null
+From ba1d235ba96e11dcdb743f384424cad3fa6c8e00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Jun 2023 23:55:10 +0100
+Subject: ocfs2: Fix use of slab data with sendpage
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 86d7bd6e66e9925f0f04a7bcf3c92c05fdfefb5a ]
+
+ocfs2 uses kzalloc() to allocate buffers for o2net_hand, o2net_keep_req and
+o2net_keep_resp and then passes these to sendpage. This isn't really
+allowed as the lifetime of slab objects is not controlled by page ref -
+though in this case it will probably work. sendmsg() with MSG_SPLICE_PAGES
+will, however, print a warning and give an error.
+
+Fix it to use folio_alloc() instead to allocate a buffer for the handshake
+message, keepalive request and reply messages.
+
+Fixes: 98211489d414 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem")
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Mark Fasheh <mark@fasheh.com>
+cc: Kurt Hackel <kurt.hackel@oracle.com>
+cc: Joel Becker <jlbec@evilplan.org>
+cc: Joseph Qi <joseph.qi@linux.alibaba.com>
+cc: ocfs2-devel@oss.oracle.com
+Link: https://lore.kernel.org/r/20230623225513.2732256-14-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/cluster/tcp.c | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
+index aecbd712a00cf..929a1133bc180 100644
+--- a/fs/ocfs2/cluster/tcp.c
++++ b/fs/ocfs2/cluster/tcp.c
+@@ -2087,18 +2087,24 @@ void o2net_stop_listening(struct o2nm_node *node)
+
+ int o2net_init(void)
+ {
++ struct folio *folio;
++ void *p;
+ unsigned long i;
+
+ o2quo_init();
+-
+ o2net_debugfs_init();
+
+- o2net_hand = kzalloc(sizeof(struct o2net_handshake), GFP_KERNEL);
+- o2net_keep_req = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL);
+- o2net_keep_resp = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL);
+- if (!o2net_hand || !o2net_keep_req || !o2net_keep_resp)
++ folio = folio_alloc(GFP_KERNEL | __GFP_ZERO, 0);
++ if (!folio)
+ goto out;
+
++ p = folio_address(folio);
++ o2net_hand = p;
++ p += sizeof(struct o2net_handshake);
++ o2net_keep_req = p;
++ p += sizeof(struct o2net_msg);
++ o2net_keep_resp = p;
++
+ o2net_hand->protocol_version = cpu_to_be64(O2NET_PROTOCOL_VERSION);
+ o2net_hand->connector_id = cpu_to_be64(1);
+
+@@ -2124,9 +2130,6 @@ int o2net_init(void)
+ return 0;
+
+ out:
+- kfree(o2net_hand);
+- kfree(o2net_keep_req);
+- kfree(o2net_keep_resp);
+ o2net_debugfs_exit();
+ o2quo_exit();
+ return -ENOMEM;
+@@ -2135,8 +2138,6 @@ int o2net_init(void)
+ void o2net_exit(void)
+ {
+ o2quo_exit();
+- kfree(o2net_hand);
+- kfree(o2net_keep_req);
+- kfree(o2net_keep_resp);
+ o2net_debugfs_exit();
++ folio_put(virt_to_folio(o2net_hand));
+ }
+--
+2.39.2
+
--- /dev/null
+From 94098b19b059ce10f89c389c931c08a4fcbf356d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Apr 2023 11:29:59 +0300
+Subject: ovl: update of dentry revalidate flags after copy up
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+[ Upstream commit b07d5cc93e1b28df47a72c519d09d0a836043613 ]
+
+After copy up, we may need to update d_flags if upper dentry is on a
+remote fs and lower dentries are not.
+
+Add helpers to allow incremental update of the revalidate flags.
+
+Fixes: bccece1ead36 ("ovl: allow remote upper")
+Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/overlayfs/copy_up.c | 2 ++
+ fs/overlayfs/dir.c | 3 +--
+ fs/overlayfs/export.c | 3 +--
+ fs/overlayfs/namei.c | 3 +--
+ fs/overlayfs/overlayfs.h | 6 ++++--
+ fs/overlayfs/super.c | 2 +-
+ fs/overlayfs/util.c | 24 ++++++++++++++++++++----
+ 7 files changed, 30 insertions(+), 13 deletions(-)
+
+diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
+index c14e90764e356..7bf101e756c8c 100644
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -576,6 +576,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c)
+ /* Restore timestamps on parent (best effort) */
+ ovl_set_timestamps(ofs, upperdir, &c->pstat);
+ ovl_dentry_set_upper_alias(c->dentry);
++ ovl_dentry_update_reval(c->dentry, upper);
+ }
+ }
+ inode_unlock(udir);
+@@ -895,6 +896,7 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
+ inode_unlock(udir);
+
+ ovl_dentry_set_upper_alias(c->dentry);
++ ovl_dentry_update_reval(c->dentry, ovl_dentry_upper(c->dentry));
+ }
+
+ out:
+diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
+index fc25fb95d5fc0..9be52d8013c83 100644
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -269,8 +269,7 @@ static int ovl_instantiate(struct dentry *dentry, struct inode *inode,
+
+ ovl_dir_modified(dentry->d_parent, false);
+ ovl_dentry_set_upper_alias(dentry);
+- ovl_dentry_update_reval(dentry, newdentry,
+- DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
++ ovl_dentry_init_reval(dentry, newdentry);
+
+ if (!hardlink) {
+ /*
+diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c
+index defd4e231ad2c..5c36fb3a7bab1 100644
+--- a/fs/overlayfs/export.c
++++ b/fs/overlayfs/export.c
+@@ -326,8 +326,7 @@ static struct dentry *ovl_obtain_alias(struct super_block *sb,
+ if (upper_alias)
+ ovl_dentry_set_upper_alias(dentry);
+
+- ovl_dentry_update_reval(dentry, upper,
+- DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
++ ovl_dentry_init_reval(dentry, upper);
+
+ return d_instantiate_anon(dentry, inode);
+
+diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
+index cfb3420b7df0e..100a492d2b2a6 100644
+--- a/fs/overlayfs/namei.c
++++ b/fs/overlayfs/namei.c
+@@ -1122,8 +1122,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
+ ovl_set_flag(OVL_UPPERDATA, inode);
+ }
+
+- ovl_dentry_update_reval(dentry, upperdentry,
+- DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
++ ovl_dentry_init_reval(dentry, upperdentry);
+
+ revert_creds(old_cred);
+ if (origin_path) {
+diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
+index 4d0b278f5630e..e100c55bb924a 100644
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -375,8 +375,10 @@ bool ovl_index_all(struct super_block *sb);
+ bool ovl_verify_lower(struct super_block *sb);
+ struct ovl_entry *ovl_alloc_entry(unsigned int numlower);
+ bool ovl_dentry_remote(struct dentry *dentry);
+-void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry,
+- unsigned int mask);
++void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *realdentry);
++void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry);
++void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry,
++ unsigned int mask);
+ bool ovl_dentry_weird(struct dentry *dentry);
+ enum ovl_path_type ovl_path_type(struct dentry *dentry);
+ void ovl_path_upper(struct dentry *dentry, struct path *path);
+diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
+index f1d9f75f8786c..49b6956468f9e 100644
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -1885,7 +1885,7 @@ static struct dentry *ovl_get_root(struct super_block *sb,
+ ovl_dentry_set_flag(OVL_E_CONNECTED, root);
+ ovl_set_upperdata(d_inode(root));
+ ovl_inode_init(d_inode(root), &oip, ino, fsid);
+- ovl_dentry_update_reval(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE);
++ ovl_dentry_init_flags(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE);
+
+ return root;
+ }
+diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
+index 923d66d131c16..6a0652bd51f24 100644
+--- a/fs/overlayfs/util.c
++++ b/fs/overlayfs/util.c
+@@ -94,14 +94,30 @@ struct ovl_entry *ovl_alloc_entry(unsigned int numlower)
+ return oe;
+ }
+
++#define OVL_D_REVALIDATE (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE)
++
+ bool ovl_dentry_remote(struct dentry *dentry)
+ {
+- return dentry->d_flags &
+- (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
++ return dentry->d_flags & OVL_D_REVALIDATE;
++}
++
++void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *realdentry)
++{
++ if (!ovl_dentry_remote(realdentry))
++ return;
++
++ spin_lock(&dentry->d_lock);
++ dentry->d_flags |= realdentry->d_flags & OVL_D_REVALIDATE;
++ spin_unlock(&dentry->d_lock);
++}
++
++void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry)
++{
++ return ovl_dentry_init_flags(dentry, upperdentry, OVL_D_REVALIDATE);
+ }
+
+-void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry,
+- unsigned int mask)
++void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry,
++ unsigned int mask)
+ {
+ struct ovl_entry *oe = OVL_E(dentry);
+ unsigned int i, flags = 0;
+--
+2.39.2
+
--- /dev/null
+From fbd91c2681da78aa49df2bb6843ba34ccf815027 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 May 2023 18:27:44 +0800
+Subject: PCI: Add pci_clear_master() stub for non-CONFIG_PCI
+
+From: Sui Jingfeng <suijingfeng@loongson.cn>
+
+[ Upstream commit 2aa5ac633259843f656eb6ecff4cf01e8e810c5e ]
+
+Add a pci_clear_master() stub when CONFIG_PCI is not set so drivers that
+support both PCI and platform devices don't need #ifdefs or extra Kconfig
+symbols for the PCI parts.
+
+[bhelgaas: commit log]
+Fixes: 6a479079c072 ("PCI: Add pci_clear_master() as opposite of pci_set_master()")
+Link: https://lore.kernel.org/r/20230531102744.2354313-1-suijingfeng@loongson.cn
+Signed-off-by: Sui Jingfeng <suijingfeng@loongson.cn>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/pci.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index a5dda515fcd1d..87d499ca7e176 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -1866,6 +1866,7 @@ static inline int pci_dev_present(const struct pci_device_id *ids)
+ #define pci_dev_put(dev) do { } while (0)
+
+ static inline void pci_set_master(struct pci_dev *dev) { }
++static inline void pci_clear_master(struct pci_dev *dev) { }
+ static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; }
+ static inline void pci_disable_device(struct pci_dev *dev) { }
+ static inline int pcim_enable_device(struct pci_dev *pdev) { return -EIO; }
+--
+2.39.2
+
--- /dev/null
+From 584c6b15cb11a7fa9b12c7d37f0f693759d8dc04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 May 2023 11:40:57 +0800
+Subject: PCI/ASPM: Disable ASPM on MFD function removal to avoid
+ use-after-free
+
+From: Ding Hui <dinghui@sangfor.com.cn>
+
+[ Upstream commit 456d8aa37d0f56fc9e985e812496e861dcd6f2f2 ]
+
+Struct pcie_link_state->downstream is a pointer to the pci_dev of function
+0. Previously we retained that pointer when removing function 0, and
+subsequent ASPM policy changes dereferenced it, resulting in a
+use-after-free warning from KASAN, e.g.:
+
+ # echo 1 > /sys/bus/pci/devices/0000:03:00.0/remove
+ # echo powersave > /sys/module/pcie_aspm/parameters/policy
+
+ BUG: KASAN: slab-use-after-free in pcie_config_aspm_link+0x42d/0x500
+ Call Trace:
+ kasan_report+0xae/0xe0
+ pcie_config_aspm_link+0x42d/0x500
+ pcie_aspm_set_policy+0x8e/0x1a0
+ param_attr_store+0x162/0x2c0
+ module_attr_store+0x3e/0x80
+
+PCIe spec r6.0, sec 7.5.3.7, recommends that software program the same ASPM
+Control value in all functions of multi-function devices.
+
+Disable ASPM and free the pcie_link_state when any child function is
+removed so we can discard the dangling pcie_link_state->downstream pointer
+and maintain the same ASPM Control configuration for all functions.
+
+[bhelgaas: commit log and comment]
+Debugged-by: Zongquan Qin <qinzongquan@sangfor.com.cn>
+Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
+Fixes: b5a0a9b59c81 ("PCI/ASPM: Read and set up L1 substate capabilities")
+Link: https://lore.kernel.org/r/20230507034057.20970-1-dinghui@sangfor.com.cn
+Signed-off-by: Ding Hui <dinghui@sangfor.com.cn>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/aspm.c | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
+index 66d7514ca111b..db32335039d61 100644
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -1010,21 +1010,24 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
+
+ down_read(&pci_bus_sem);
+ mutex_lock(&aspm_lock);
+- /*
+- * All PCIe functions are in one slot, remove one function will remove
+- * the whole slot, so just wait until we are the last function left.
+- */
+- if (!list_empty(&parent->subordinate->devices))
+- goto out;
+
+ link = parent->link_state;
+ root = link->root;
+ parent_link = link->parent;
+
+- /* All functions are removed, so just disable ASPM for the link */
++ /*
++ * link->downstream is a pointer to the pci_dev of function 0. If
++ * we remove that function, the pci_dev is about to be deallocated,
++ * so we can't use link->downstream again. Free the link state to
++ * avoid this.
++ *
++ * If we're removing a non-0 function, it's possible we could
++ * retain the link state, but PCIe r6.0, sec 7.5.3.7, recommends
++ * programming the same ASPM Control value for all functions of
++ * multi-function devices, so disable ASPM for all of them.
++ */
+ pcie_config_aspm_link(link, 0);
+ list_del(&link->sibling);
+- /* Clock PM is for endpoint device */
+ free_link_state(link);
+
+ /* Recheck latencies and configure upstream links */
+@@ -1032,7 +1035,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
+ pcie_update_aspm_capable(root);
+ pcie_config_aspm_path(parent_link);
+ }
+-out:
++
+ mutex_unlock(&aspm_lock);
+ up_read(&pci_bus_sem);
+ }
+--
+2.39.2
+
--- /dev/null
+From f8b1a880a949df8762f4e4b6a5897373e03e6f7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Mar 2023 12:38:00 +0530
+Subject: PCI: cadence: Fix Gen2 Link Retraining process
+
+From: Siddharth Vadapalli <s-vadapalli@ti.com>
+
+[ Upstream commit 0e12f830236928b6fadf40d917a7527f0a048d2f ]
+
+The Link Retraining process is initiated to account for the Gen2 defect in
+the Cadence PCIe controller in J721E SoC. The errata corresponding to this
+is i2085, documented at:
+https://www.ti.com/lit/er/sprz455c/sprz455c.pdf
+
+The existing workaround implemented for the errata waits for the Data Link
+initialization to complete and assumes that the link retraining process
+at the Physical Layer has completed. However, it is possible that the
+Physical Layer training might be ongoing as indicated by the
+PCI_EXP_LNKSTA_LT bit in the PCI_EXP_LNKSTA register.
+
+Fix the existing workaround, to ensure that the Physical Layer training
+has also completed, in addition to the Data Link initialization.
+
+Link: https://lore.kernel.org/r/20230315070800.1615527-1-s-vadapalli@ti.com
+Fixes: 4740b969aaf5 ("PCI: cadence: Retrain Link to work around Gen2 training defect")
+Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Reviewed-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../controller/cadence/pcie-cadence-host.c | 27 +++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
+index 940c7dd701d68..5b14f7ee3c798 100644
+--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
++++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
+@@ -12,6 +12,8 @@
+
+ #include "pcie-cadence.h"
+
++#define LINK_RETRAIN_TIMEOUT HZ
++
+ static u64 bar_max_size[] = {
+ [RP_BAR0] = _ULL(128 * SZ_2G),
+ [RP_BAR1] = SZ_2G,
+@@ -77,6 +79,27 @@ static struct pci_ops cdns_pcie_host_ops = {
+ .write = pci_generic_config_write,
+ };
+
++static int cdns_pcie_host_training_complete(struct cdns_pcie *pcie)
++{
++ u32 pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET;
++ unsigned long end_jiffies;
++ u16 lnk_stat;
++
++ /* Wait for link training to complete. Exit after timeout. */
++ end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT;
++ do {
++ lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA);
++ if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
++ break;
++ usleep_range(0, 1000);
++ } while (time_before(jiffies, end_jiffies));
++
++ if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
++ return 0;
++
++ return -ETIMEDOUT;
++}
++
+ static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
+ {
+ struct device *dev = pcie->dev;
+@@ -118,6 +141,10 @@ static int cdns_pcie_retrain(struct cdns_pcie *pcie)
+ cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL,
+ lnk_ctl);
+
++ ret = cdns_pcie_host_training_complete(pcie);
++ if (ret)
++ return ret;
++
+ ret = cdns_pcie_host_wait_for_link(pcie);
+ }
+ return ret;
+--
+2.39.2
+
--- /dev/null
+From fc9aac608f999abd777950c065cefd0417fafac0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 19:38:32 +0900
+Subject: PCI: endpoint: Fix a Kconfig prompt of vNTB driver
+
+From: Shunsuke Mie <mie@igel.co.jp>
+
+[ Upstream commit 37587673cda963ec950e4983db5023802f9b5ff2 ]
+
+vNTB driver and NTB driver have same Kconfig prompt. Changed to make it
+distinguishable.
+
+Link: https://lore.kernel.org/r/20230202103832.2038286-1-mie@igel.co.jp
+Fixes: e35f56bb0330 ("PCI: endpoint: Support NTB transfer between RC and EP")
+Signed-off-by: Shunsuke Mie <mie@igel.co.jp>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/endpoint/functions/Kconfig b/drivers/pci/endpoint/functions/Kconfig
+index 9fd5608868718..8efb6a869e7ce 100644
+--- a/drivers/pci/endpoint/functions/Kconfig
++++ b/drivers/pci/endpoint/functions/Kconfig
+@@ -27,7 +27,7 @@ config PCI_EPF_NTB
+ If in doubt, say "N" to disable Endpoint NTB driver.
+
+ config PCI_EPF_VNTB
+- tristate "PCI Endpoint NTB driver"
++ tristate "PCI Endpoint Virtual NTB driver"
+ depends on PCI_ENDPOINT
+ depends on NTB
+ select CONFIGFS_FS
+--
+2.39.2
+
--- /dev/null
+From a5fcfe0d1fefeb31af0be74b60281a5d86c8076f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Apr 2023 15:34:47 +0900
+Subject: PCI: endpoint: functions/pci-epf-test: Fix dma_chan direction
+
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+[ Upstream commit 880d51c729a3fa944794feb19f605eefe55916fc ]
+
+In pci_epf_test_init_dma_chan() epf_test->dma_chan_rx is assigned from
+dma_request_channel() with DMA_DEV_TO_MEM as filter.dma_mask.
+
+However, in pci_epf_test_data_transfer() if the dir is DMA_DEV_TO_MEM,
+epf->dma_chan_rx should be used but instead we are using
+epf_test->dma_chan_tx.
+
+Fix it.
+
+Link: https://lore.kernel.org/r/20230412063447.2841177-1-yoshihiro.shimoda.uh@renesas.com
+Fixes: 8353813c88ef ("PCI: endpoint: Enable DMA tests for endpoints with DMA capabilities")
+Tested-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index 0f9d2ec822ac6..172e5ac0bd96c 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -112,7 +112,7 @@ static int pci_epf_test_data_transfer(struct pci_epf_test *epf_test,
+ size_t len, dma_addr_t dma_remote,
+ enum dma_transfer_direction dir)
+ {
+- struct dma_chan *chan = (dir == DMA_DEV_TO_MEM) ?
++ struct dma_chan *chan = (dir == DMA_MEM_TO_DEV) ?
+ epf_test->dma_chan_tx : epf_test->dma_chan_rx;
+ dma_addr_t dma_local = (dir == DMA_MEM_TO_DEV) ? dma_src : dma_dst;
+ enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
+--
+2.39.2
+
--- /dev/null
+From 0ddb88269c35d7d4e2a7a2db8649f972c589d1f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 May 2023 12:36:41 +0800
+Subject: PCI: ftpci100: Release the clock resources
+
+From: Junyan Ye <yejunyan@hust.edu.cn>
+
+[ Upstream commit c60738de85f40b0b9f5cb23c21f9246e5a47908c ]
+
+Smatch reported:
+1. drivers/pci/controller/pci-ftpci100.c:526 faraday_pci_probe() warn:
+'clk' from clk_prepare_enable() not released on lines: 442,451,462,478,512,517.
+2. drivers/pci/controller/pci-ftpci100.c:526 faraday_pci_probe() warn:
+'p->bus_clk' from clk_prepare_enable() not released on lines: 451,462,478,512,517.
+
+The clock resource is obtained by devm_clk_get(), and then
+clk_prepare_enable() makes the clock resource ready for use. After that,
+clk_disable_unprepare() should be called to release the clock resource
+when it is no longer needed. However, while doing some error handling
+in faraday_pci_probe(), clk_disable_unprepare() is not called to release
+clk and p->bus_clk before returning. These return lines are exactly 442,
+451, 462, 478, 512, 517.
+
+Fix this warning by replacing devm_clk_get() with devm_clk_get_enabled(),
+which is equivalent to devm_clk_get() + clk_prepare_enable(). And with
+devm_clk_get_enabled(), the clock will automatically be disabled,
+unprepared and freed when the device is unbound from the bus.
+
+Link: https://lore.kernel.org/r/20230508043641.23807-1-yejunyan@hust.edu.cn
+Fixes: b3c433efb8a3 ("PCI: faraday: Fix wrong pointer passed to PTR_ERR()")
+Fixes: 2eeb02b28579 ("PCI: faraday: Add clock handling")
+Fixes: 783a862563f7 ("PCI: faraday: Use pci_parse_request_of_pci_ranges()")
+Fixes: d3c68e0a7e34 ("PCI: faraday: Add Faraday Technology FTPCI100 PCI Host Bridge driver")
+Fixes: f1e8bd21e39e ("PCI: faraday: Convert IRQ masking to raw PCI config accessors")
+Signed-off-by: Junyan Ye <yejunyan@hust.edu.cn>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pci-ftpci100.c | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/pci/controller/pci-ftpci100.c b/drivers/pci/controller/pci-ftpci100.c
+index ecd3009df586d..6e7981d2ed5e1 100644
+--- a/drivers/pci/controller/pci-ftpci100.c
++++ b/drivers/pci/controller/pci-ftpci100.c
+@@ -429,22 +429,12 @@ static int faraday_pci_probe(struct platform_device *pdev)
+ p->dev = dev;
+
+ /* Retrieve and enable optional clocks */
+- clk = devm_clk_get(dev, "PCLK");
++ clk = devm_clk_get_enabled(dev, "PCLK");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+- ret = clk_prepare_enable(clk);
+- if (ret) {
+- dev_err(dev, "could not prepare PCLK\n");
+- return ret;
+- }
+- p->bus_clk = devm_clk_get(dev, "PCICLK");
++ p->bus_clk = devm_clk_get_enabled(dev, "PCICLK");
+ if (IS_ERR(p->bus_clk))
+ return PTR_ERR(p->bus_clk);
+- ret = clk_prepare_enable(p->bus_clk);
+- if (ret) {
+- dev_err(dev, "could not prepare PCICLK\n");
+- return ret;
+- }
+
+ p->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(p->base))
+--
+2.39.2
+
--- /dev/null
+From 0a83c9551b933544077a1eb4c909a2a032e95ffa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 10:15:18 +0800
+Subject: PCI: pciehp: Cancel bringup sequence if card is not present
+
+From: Rongguang Wei <weirongguang@kylinos.cn>
+
+[ Upstream commit e8afd0d9fccc27c8ad263db5cf5952cfcf72d6fe ]
+
+If a PCIe hotplug slot has an Attention Button, the normal hot-add flow is:
+
+ - Slot is empty and slot power is off
+ - User inserts card in slot and presses Attention Button
+ - OS blinks Power Indicator for 5 seconds
+ - After 5 seconds, OS turns on Power Indicator, turns on slot power, and
+ enumerates the device
+
+Previously, if a user pressed the Attention Button on an *empty* slot,
+pciehp logged the following messages and blinked the Power Indicator
+until a second button press:
+
+ [0.000] pciehp: Button press: will power on in 5 sec
+ [0.001] # Power Indicator starts blinking
+ [5.001] # 5 second timeout; slot is empty, so we should cancel the
+ request to power on and turn off Power Indicator
+
+ [7.000] # Power Indicator still blinking
+ [8.000] # possible card insertion
+ [9.000] pciehp: Button press: canceling request to power on
+
+The first button press incorrectly left the slot in BLINKINGON_STATE, so
+the second was interpreted as a "cancel power on" event regardless of
+whether a card was present.
+
+If the slot is empty, turn off the Power Indicator and return from
+BLINKINGON_STATE to OFF_STATE after 5 seconds, effectively canceling the
+request to power on. Putting the slot in OFF_STATE also means the second
+button press will correctly request a slot power on if the slot is
+occupied.
+
+[bhelgaas: commit log]
+Link: https://lore.kernel.org/r/20230512021518.336460-1-clementwei90@163.com
+Fixes: d331710ea78f ("PCI: pciehp: Become resilient to missed events")
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Rongguang Wei <weirongguang@kylinos.cn>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/hotplug/pciehp_ctrl.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
+index 529c348084401..32baba1b7f131 100644
+--- a/drivers/pci/hotplug/pciehp_ctrl.c
++++ b/drivers/pci/hotplug/pciehp_ctrl.c
+@@ -256,6 +256,14 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
+ present = pciehp_card_present(ctrl);
+ link_active = pciehp_check_link_active(ctrl);
+ if (present <= 0 && link_active <= 0) {
++ if (ctrl->state == BLINKINGON_STATE) {
++ ctrl->state = OFF_STATE;
++ cancel_delayed_work(&ctrl->button_work);
++ pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
++ INDICATOR_NOOP);
++ ctrl_info(ctrl, "Slot(%s): Card not present\n",
++ slot_name(ctrl));
++ }
+ mutex_unlock(&ctrl->state_lock);
+ return;
+ }
+--
+2.39.2
+
--- /dev/null
+From 918f61737370c61c927e8d724b1bf25fedac8259 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 20:34:02 +0530
+Subject: PCI: qcom: Disable write access to read only registers for IP v2.9.0
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 200b8f85f2021362adcc8efb575652a2aa44c099 ]
+
+In the post init sequence of v2.9.0, write access to read only registers
+are not disabled after updating the registers. Fix it by disabling the
+access after register update.
+
+While at it, let's also add a newline after existing dw_pcie_dbi_ro_wr_en()
+guard function to align with rest of the driver.
+
+Link: https://lore.kernel.org/r/20230619150408.8468-4-manivannan.sadhasivam@linaro.org
+Fixes: 0cf7c2efe8ac ("PCI: qcom: Add IPQ60xx support")
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-qcom.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index dcad29c860525..70e75f6eb3ece 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -1406,6 +1406,7 @@ static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
+ writel(0, pcie->parf + PARF_Q2A_FLUSH);
+
+ dw_pcie_dbi_ro_wr_en(pci);
++
+ writel(PCIE_CAP_SLOT_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
+
+ val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
+@@ -1415,6 +1416,8 @@ static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
+ writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
+ PCI_EXP_DEVCTL2);
+
++ dw_pcie_dbi_ro_wr_dis(pci);
++
+ for (i = 0; i < 256; i++)
+ writel(0, pcie->parf + PARF_BDF_TO_SID_TABLE_N + (4 * i));
+
+--
+2.39.2
+
--- /dev/null
+From a8a83829f40b590383967a77fc80bf49682982d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Mar 2023 13:41:00 +0530
+Subject: PCI: qcom: Remove PCIE20_ prefix from register definitions
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 39171b33f6523f28c1c1256427e5f50c74b69639 ]
+
+The PCIE part is redundant and 20 doesn't represent anything across the
+SoCs supported now. So let's get rid of the prefix.
+
+This involves adding the IP version suffix to one definition of
+PARF_SLV_ADDR_SPACE_SIZE that defines offset specific to that version.
+The other definition is generic for the rest of the versions.
+
+Also, the register PCIE20_LNK_CONTROL2_LINK_STATUS2 is not used anywhere,
+hence removed.
+
+Link: https://lore.kernel.org/r/20230316081117.14288-3-manivannan.sadhasivam@linaro.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Stable-dep-of: 60f0072d7fb7 ("PCI: qcom: Use DWC helpers for modifying the read-only DBI registers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-qcom.c | 184 ++++++++++++-------------
+ 1 file changed, 91 insertions(+), 93 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index 89d748cc4b8a3..5855ad8e9c1cf 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -33,7 +33,7 @@
+ #include "../../pci.h"
+ #include "pcie-designware.h"
+
+-#define PCIE20_PARF_SYS_CTRL 0x00
++#define PARF_SYS_CTRL 0x00
+ #define MST_WAKEUP_EN BIT(13)
+ #define SLV_WAKEUP_EN BIT(12)
+ #define MSTR_ACLK_CGC_DIS BIT(10)
+@@ -43,39 +43,39 @@
+ #define L23_CLK_RMV_DIS BIT(2)
+ #define L1_CLK_RMV_DIS BIT(1)
+
+-#define PCIE20_PARF_PM_CTRL 0x20
++#define PARF_PM_CTRL 0x20
+ #define REQ_NOT_ENTR_L1 BIT(5)
+
+-#define PCIE20_PARF_PHY_CTRL 0x40
++#define PARF_PHY_CTRL 0x40
+ #define PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK GENMASK(20, 16)
+ #define PHY_CTRL_PHY_TX0_TERM_OFFSET(x) ((x) << 16)
+
+-#define PCIE20_PARF_PHY_REFCLK 0x4C
++#define PARF_PHY_REFCLK 0x4C
+ #define PHY_REFCLK_SSP_EN BIT(16)
+ #define PHY_REFCLK_USE_PAD BIT(12)
+
+-#define PCIE20_PARF_DBI_BASE_ADDR 0x168
+-#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x16C
+-#define PCIE20_PARF_MHI_CLOCK_RESET_CTRL 0x174
++#define PARF_DBI_BASE_ADDR 0x168
++#define PARF_SLV_ADDR_SPACE_SIZE_2_3_3 0x16C /* Register offset specific to IP rev 2.3.3 */
++#define PARF_MHI_CLOCK_RESET_CTRL 0x174
+ #define AHB_CLK_EN BIT(0)
+ #define MSTR_AXI_CLK_EN BIT(1)
+ #define BYPASS BIT(4)
+
+-#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT 0x178
+-#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1A8
+-#define PCIE20_PARF_LTSSM 0x1B0
+-#define PCIE20_PARF_SID_OFFSET 0x234
+-#define PCIE20_PARF_BDF_TRANSLATE_CFG 0x24C
+-#define PCIE20_PARF_DEVICE_TYPE 0x1000
+-#define PCIE20_PARF_BDF_TO_SID_TABLE_N 0x2000
++#define PARF_AXI_MSTR_WR_ADDR_HALT 0x178
++#define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1A8
++#define PARF_LTSSM 0x1B0
++#define PARF_SID_OFFSET 0x234
++#define PARF_BDF_TRANSLATE_CFG 0x24C
++#define PARF_DEVICE_TYPE 0x1000
++#define PARF_BDF_TO_SID_TABLE_N 0x2000
+
+-#define PCIE20_ELBI_SYS_CTRL 0x04
+-#define PCIE20_ELBI_SYS_CTRL_LT_ENABLE BIT(0)
++#define ELBI_SYS_CTRL 0x04
++#define ELBI_SYS_CTRL_LT_ENABLE BIT(0)
+
+-#define PCIE20_AXI_MSTR_RESP_COMP_CTRL0 0x818
++#define AXI_MSTR_RESP_COMP_CTRL0 0x818
+ #define CFG_REMOTE_RD_REQ_BRIDGE_SIZE_2K 0x4
+ #define CFG_REMOTE_RD_REQ_BRIDGE_SIZE_4K 0x5
+-#define PCIE20_AXI_MSTR_RESP_COMP_CTRL1 0x81c
++#define AXI_MSTR_RESP_COMP_CTRL1 0x81c
+ #define CFG_BRIDGE_SB_INIT BIT(0)
+
+ #define PCIE_CAP_SLOT_POWER_LIMIT_VAL FIELD_PREP(PCI_EXP_SLTCAP_SPLV, \
+@@ -93,30 +93,28 @@
+ PCIE_CAP_SLOT_POWER_LIMIT_VAL | \
+ PCIE_CAP_SLOT_POWER_LIMIT_SCALE)
+
+-#define PCIE20_PARF_Q2A_FLUSH 0x1AC
++#define PARF_Q2A_FLUSH 0x1AC
+
+-#define PCIE20_MISC_CONTROL_1_REG 0x8BC
++#define MISC_CONTROL_1_REG 0x8BC
+ #define DBI_RO_WR_EN 1
+
+ #define PERST_DELAY_US 1000
+ /* PARF registers */
+-#define PCIE20_PARF_PCS_DEEMPH 0x34
++#define PARF_PCS_DEEMPH 0x34
+ #define PCS_DEEMPH_TX_DEEMPH_GEN1(x) ((x) << 16)
+ #define PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) ((x) << 8)
+ #define PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x) ((x) << 0)
+
+-#define PCIE20_PARF_PCS_SWING 0x38
++#define PARF_PCS_SWING 0x38
+ #define PCS_SWING_TX_SWING_FULL(x) ((x) << 8)
+ #define PCS_SWING_TX_SWING_LOW(x) ((x) << 0)
+
+-#define PCIE20_PARF_CONFIG_BITS 0x50
++#define PARF_CONFIG_BITS 0x50
+ #define PHY_RX0_EQ(x) ((x) << 24)
+
+-#define PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE 0x358
++#define PARF_SLV_ADDR_SPACE_SIZE 0x358
+ #define SLV_ADDR_SPACE_SZ 0x10000000
+
+-#define PCIE20_LNK_CONTROL2_LINK_STATUS2 0xa0
+-
+ #define DEVICE_TYPE_RC 0x4
+
+ #define QCOM_PCIE_2_1_0_MAX_SUPPLY 3
+@@ -261,9 +259,9 @@ static void qcom_pcie_2_1_0_ltssm_enable(struct qcom_pcie *pcie)
+ u32 val;
+
+ /* enable link training */
+- val = readl(pcie->elbi + PCIE20_ELBI_SYS_CTRL);
+- val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE;
+- writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL);
++ val = readl(pcie->elbi + ELBI_SYS_CTRL);
++ val |= ELBI_SYS_CTRL_LT_ENABLE;
++ writel(val, pcie->elbi + ELBI_SYS_CTRL);
+ }
+
+ static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie)
+@@ -333,7 +331,7 @@ static void qcom_pcie_deinit_2_1_0(struct qcom_pcie *pcie)
+ reset_control_assert(res->ext_reset);
+ reset_control_assert(res->phy_reset);
+
+- writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL);
++ writel(1, pcie->parf + PARF_PHY_CTRL);
+
+ regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
+ }
+@@ -423,9 +421,9 @@ static int qcom_pcie_post_init_2_1_0(struct qcom_pcie *pcie)
+ int ret;
+
+ /* enable PCIe clocks and resets */
+- val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
++ val = readl(pcie->parf + PARF_PHY_CTRL);
+ val &= ~BIT(0);
+- writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
++ writel(val, pcie->parf + PARF_PHY_CTRL);
+
+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+ if (ret)
+@@ -436,37 +434,37 @@ static int qcom_pcie_post_init_2_1_0(struct qcom_pcie *pcie)
+ writel(PCS_DEEMPH_TX_DEEMPH_GEN1(24) |
+ PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(24) |
+ PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(34),
+- pcie->parf + PCIE20_PARF_PCS_DEEMPH);
++ pcie->parf + PARF_PCS_DEEMPH);
+ writel(PCS_SWING_TX_SWING_FULL(120) |
+ PCS_SWING_TX_SWING_LOW(120),
+- pcie->parf + PCIE20_PARF_PCS_SWING);
+- writel(PHY_RX0_EQ(4), pcie->parf + PCIE20_PARF_CONFIG_BITS);
++ pcie->parf + PARF_PCS_SWING);
++ writel(PHY_RX0_EQ(4), pcie->parf + PARF_CONFIG_BITS);
+ }
+
+ if (of_device_is_compatible(node, "qcom,pcie-ipq8064")) {
+ /* set TX termination offset */
+- val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
++ val = readl(pcie->parf + PARF_PHY_CTRL);
+ val &= ~PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK;
+ val |= PHY_CTRL_PHY_TX0_TERM_OFFSET(7);
+- writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
++ writel(val, pcie->parf + PARF_PHY_CTRL);
+ }
+
+ /* enable external reference clock */
+- val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK);
++ val = readl(pcie->parf + PARF_PHY_REFCLK);
+ /* USE_PAD is required only for ipq806x */
+ if (!of_device_is_compatible(node, "qcom,pcie-apq8064"))
+ val &= ~PHY_REFCLK_USE_PAD;
+ val |= PHY_REFCLK_SSP_EN;
+- writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK);
++ writel(val, pcie->parf + PARF_PHY_REFCLK);
+
+ /* wait for clock acquisition */
+ usleep_range(1000, 1500);
+
+ /* Set the Max TLP size to 2K, instead of using default of 4K */
+ writel(CFG_REMOTE_RD_REQ_BRIDGE_SIZE_2K,
+- pci->dbi_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL0);
++ pci->dbi_base + AXI_MSTR_RESP_COMP_CTRL0);
+ writel(CFG_BRIDGE_SB_INIT,
+- pci->dbi_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL1);
++ pci->dbi_base + AXI_MSTR_RESP_COMP_CTRL1);
+
+ return 0;
+ }
+@@ -574,13 +572,13 @@ static int qcom_pcie_init_1_0_0(struct qcom_pcie *pcie)
+ static int qcom_pcie_post_init_1_0_0(struct qcom_pcie *pcie)
+ {
+ /* change DBI base address */
+- writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
++ writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
+
+ if (IS_ENABLED(CONFIG_PCI_MSI)) {
+- u32 val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
++ u32 val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT);
+
+ val |= BIT(31);
+- writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
++ writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT);
+ }
+
+ return 0;
+@@ -591,9 +589,9 @@ static void qcom_pcie_2_3_2_ltssm_enable(struct qcom_pcie *pcie)
+ u32 val;
+
+ /* enable link training */
+- val = readl(pcie->parf + PCIE20_PARF_LTSSM);
++ val = readl(pcie->parf + PARF_LTSSM);
+ val |= BIT(8);
+- writel(val, pcie->parf + PCIE20_PARF_LTSSM);
++ writel(val, pcie->parf + PARF_LTSSM);
+ }
+
+ static int qcom_pcie_get_resources_2_3_2(struct qcom_pcie *pcie)
+@@ -698,25 +696,25 @@ static int qcom_pcie_post_init_2_3_2(struct qcom_pcie *pcie)
+ u32 val;
+
+ /* enable PCIe clocks and resets */
+- val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
++ val = readl(pcie->parf + PARF_PHY_CTRL);
+ val &= ~BIT(0);
+- writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
++ writel(val, pcie->parf + PARF_PHY_CTRL);
+
+ /* change DBI base address */
+- writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
++ writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
+
+ /* MAC PHY_POWERDOWN MUX DISABLE */
+- val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL);
++ val = readl(pcie->parf + PARF_SYS_CTRL);
+ val &= ~BIT(29);
+- writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL);
++ writel(val, pcie->parf + PARF_SYS_CTRL);
+
+- val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
++ val = readl(pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
+ val |= BIT(4);
+- writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
++ writel(val, pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
+
+- val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
++ val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+ val |= BIT(31);
+- writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
++ writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+
+ return 0;
+ }
+@@ -977,25 +975,25 @@ static int qcom_pcie_post_init_2_4_0(struct qcom_pcie *pcie)
+ u32 val;
+
+ /* enable PCIe clocks and resets */
+- val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
++ val = readl(pcie->parf + PARF_PHY_CTRL);
+ val &= ~BIT(0);
+- writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
++ writel(val, pcie->parf + PARF_PHY_CTRL);
+
+ /* change DBI base address */
+- writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
++ writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
+
+ /* MAC PHY_POWERDOWN MUX DISABLE */
+- val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL);
++ val = readl(pcie->parf + PARF_SYS_CTRL);
+ val &= ~BIT(29);
+- writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL);
++ writel(val, pcie->parf + PARF_SYS_CTRL);
+
+- val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
++ val = readl(pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
+ val |= BIT(4);
+- writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
++ writel(val, pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
+
+- val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
++ val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+ val |= BIT(31);
+- writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
++ writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+
+ return 0;
+ }
+@@ -1140,22 +1138,22 @@ static int qcom_pcie_post_init_2_3_3(struct qcom_pcie *pcie)
+ u32 val;
+
+ writel(SLV_ADDR_SPACE_SZ,
+- pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
++ pcie->parf + PARF_SLV_ADDR_SPACE_SIZE_2_3_3);
+
+- val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
++ val = readl(pcie->parf + PARF_PHY_CTRL);
+ val &= ~BIT(0);
+- writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
++ writel(val, pcie->parf + PARF_PHY_CTRL);
+
+- writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
++ writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
+
+ writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
+ | SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
+ AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
+- pcie->parf + PCIE20_PARF_SYS_CTRL);
+- writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
++ pcie->parf + PARF_SYS_CTRL);
++ writel(0, pcie->parf + PARF_Q2A_FLUSH);
+
+ writel(PCI_COMMAND_MASTER, pci->dbi_base + PCI_COMMAND);
+- writel(DBI_RO_WR_EN, pci->dbi_base + PCIE20_MISC_CONTROL_1_REG);
++ writel(DBI_RO_WR_EN, pci->dbi_base + MISC_CONTROL_1_REG);
+ writel(PCIE_CAP_SLOT_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
+
+ val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
+@@ -1255,33 +1253,33 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
+ usleep_range(1000, 1500);
+
+ /* configure PCIe to RC mode */
+- writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
++ writel(DEVICE_TYPE_RC, pcie->parf + PARF_DEVICE_TYPE);
+
+ /* enable PCIe clocks and resets */
+- val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
++ val = readl(pcie->parf + PARF_PHY_CTRL);
+ val &= ~BIT(0);
+- writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
++ writel(val, pcie->parf + PARF_PHY_CTRL);
+
+ /* change DBI base address */
+- writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
++ writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
+
+ /* MAC PHY_POWERDOWN MUX DISABLE */
+- val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL);
++ val = readl(pcie->parf + PARF_SYS_CTRL);
+ val &= ~BIT(29);
+- writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL);
++ writel(val, pcie->parf + PARF_SYS_CTRL);
+
+- val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
++ val = readl(pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
+ val |= BIT(4);
+- writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
++ writel(val, pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
+
+ /* Enable L1 and L1SS */
+- val = readl(pcie->parf + PCIE20_PARF_PM_CTRL);
++ val = readl(pcie->parf + PARF_PM_CTRL);
+ val &= ~REQ_NOT_ENTR_L1;
+- writel(val, pcie->parf + PCIE20_PARF_PM_CTRL);
++ writel(val, pcie->parf + PARF_PM_CTRL);
+
+- val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
++ val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+ val |= BIT(31);
+- writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
++ writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+
+ return 0;
+ err_disable_clocks:
+@@ -1369,17 +1367,17 @@ static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
+ int i;
+
+ writel(SLV_ADDR_SPACE_SZ,
+- pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
++ pcie->parf + PARF_SLV_ADDR_SPACE_SIZE);
+
+- val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
++ val = readl(pcie->parf + PARF_PHY_CTRL);
+ val &= ~BIT(0);
+- writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
++ writel(val, pcie->parf + PARF_PHY_CTRL);
+
+- writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
++ writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
+
+- writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
++ writel(DEVICE_TYPE_RC, pcie->parf + PARF_DEVICE_TYPE);
+ writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
+- pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
++ pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
+ writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS |
+ GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
+ pci->dbi_base + GEN3_RELATED_OFF);
+@@ -1387,9 +1385,9 @@ static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
+ writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS |
+ SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
+ AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
+- pcie->parf + PCIE20_PARF_SYS_CTRL);
++ pcie->parf + PARF_SYS_CTRL);
+
+- writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
++ writel(0, pcie->parf + PARF_Q2A_FLUSH);
+
+ dw_pcie_dbi_ro_wr_en(pci);
+ writel(PCIE_CAP_SLOT_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
+@@ -1402,7 +1400,7 @@ static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
+ PCI_EXP_DEVCTL2);
+
+ for (i = 0; i < 256; i++)
+- writel(0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N + (4 * i));
++ writel(0, pcie->parf + PARF_BDF_TO_SID_TABLE_N + (4 * i));
+
+ return 0;
+ }
+@@ -1424,7 +1422,7 @@ static int qcom_pcie_config_sid_sm8250(struct qcom_pcie *pcie)
+ u32 smmu_sid;
+ u32 smmu_sid_len;
+ } *map;
+- void __iomem *bdf_to_sid_base = pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N;
++ void __iomem *bdf_to_sid_base = pcie->parf + PARF_BDF_TO_SID_TABLE_N;
+ struct device *dev = pcie->pci->dev;
+ u8 qcom_pcie_crc8_table[CRC8_TABLE_SIZE];
+ int i, nr_map, size = 0;
+--
+2.39.2
+
--- /dev/null
+From f9024040572196905055cdc801f55951e6b5d9b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Mar 2023 13:41:01 +0530
+Subject: PCI: qcom: Sort and group registers and bitfield definitions
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 769e49d87b15c302c9aadd87c7d114cfe7052320 ]
+
+Sorting the registers and their bit definitions will make it easier to add
+more definitions in the future and it also helps in maintenance.
+
+While at it, let's also group the registers and bit definitions separately
+as done in the pcie-qcom-ep driver.
+
+Link: https://lore.kernel.org/r/20230316081117.14288-4-manivannan.sadhasivam@linaro.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Stable-dep-of: 60f0072d7fb7 ("PCI: qcom: Use DWC helpers for modifying the read-only DBI registers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-qcom.c | 108 ++++++++++++++-----------
+ 1 file changed, 63 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index 5855ad8e9c1cf..a33653d576b62 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -33,7 +33,36 @@
+ #include "../../pci.h"
+ #include "pcie-designware.h"
+
++/* PARF registers */
+ #define PARF_SYS_CTRL 0x00
++#define PARF_PM_CTRL 0x20
++#define PARF_PCS_DEEMPH 0x34
++#define PARF_PCS_SWING 0x38
++#define PARF_PHY_CTRL 0x40
++#define PARF_PHY_REFCLK 0x4C
++#define PARF_CONFIG_BITS 0x50
++#define PARF_DBI_BASE_ADDR 0x168
++#define PARF_SLV_ADDR_SPACE_SIZE_2_3_3 0x16C /* Register offset specific to IP ver 2.3.3 */
++#define PARF_MHI_CLOCK_RESET_CTRL 0x174
++#define PARF_AXI_MSTR_WR_ADDR_HALT 0x178
++#define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1A8
++#define PARF_Q2A_FLUSH 0x1AC
++#define PARF_LTSSM 0x1B0
++#define PARF_SID_OFFSET 0x234
++#define PARF_BDF_TRANSLATE_CFG 0x24C
++#define PARF_SLV_ADDR_SPACE_SIZE 0x358
++#define PARF_DEVICE_TYPE 0x1000
++#define PARF_BDF_TO_SID_TABLE_N 0x2000
++
++/* ELBI registers */
++#define ELBI_SYS_CTRL 0x04
++
++/* DBI registers */
++#define AXI_MSTR_RESP_COMP_CTRL0 0x818
++#define AXI_MSTR_RESP_COMP_CTRL1 0x81c
++#define MISC_CONTROL_1_REG 0x8BC
++
++/* PARF_SYS_CTRL register fields */
+ #define MST_WAKEUP_EN BIT(13)
+ #define SLV_WAKEUP_EN BIT(12)
+ #define MSTR_ACLK_CGC_DIS BIT(10)
+@@ -43,45 +72,56 @@
+ #define L23_CLK_RMV_DIS BIT(2)
+ #define L1_CLK_RMV_DIS BIT(1)
+
+-#define PARF_PM_CTRL 0x20
++/* PARF_PM_CTRL register fields */
+ #define REQ_NOT_ENTR_L1 BIT(5)
+
+-#define PARF_PHY_CTRL 0x40
++/* PARF_PCS_DEEMPH register fields */
++#define PCS_DEEMPH_TX_DEEMPH_GEN1(x) ((x) << 16)
++#define PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) ((x) << 8)
++#define PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x) ((x) << 0)
++
++/* PARF_PCS_SWING register fields */
++#define PCS_SWING_TX_SWING_FULL(x) ((x) << 8)
++#define PCS_SWING_TX_SWING_LOW(x) ((x) << 0)
++
++/* PARF_PHY_CTRL register fields */
+ #define PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK GENMASK(20, 16)
+ #define PHY_CTRL_PHY_TX0_TERM_OFFSET(x) ((x) << 16)
+
+-#define PARF_PHY_REFCLK 0x4C
++/* PARF_PHY_REFCLK register fields */
+ #define PHY_REFCLK_SSP_EN BIT(16)
+ #define PHY_REFCLK_USE_PAD BIT(12)
+
+-#define PARF_DBI_BASE_ADDR 0x168
+-#define PARF_SLV_ADDR_SPACE_SIZE_2_3_3 0x16C /* Register offset specific to IP rev 2.3.3 */
+-#define PARF_MHI_CLOCK_RESET_CTRL 0x174
++/* PARF_CONFIG_BITS register fields */
++#define PHY_RX0_EQ(x) ((x) << 24)
++
++/* PARF_SLV_ADDR_SPACE_SIZE register value */
++#define SLV_ADDR_SPACE_SZ 0x10000000
++
++/* PARF_MHI_CLOCK_RESET_CTRL register fields */
+ #define AHB_CLK_EN BIT(0)
+ #define MSTR_AXI_CLK_EN BIT(1)
+ #define BYPASS BIT(4)
+
+-#define PARF_AXI_MSTR_WR_ADDR_HALT 0x178
+-#define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1A8
+-#define PARF_LTSSM 0x1B0
+-#define PARF_SID_OFFSET 0x234
+-#define PARF_BDF_TRANSLATE_CFG 0x24C
+-#define PARF_DEVICE_TYPE 0x1000
+-#define PARF_BDF_TO_SID_TABLE_N 0x2000
++/* PARF_DEVICE_TYPE register fields */
++#define DEVICE_TYPE_RC 0x4
+
+-#define ELBI_SYS_CTRL 0x04
++/* ELBI_SYS_CTRL register fields */
+ #define ELBI_SYS_CTRL_LT_ENABLE BIT(0)
+
+-#define AXI_MSTR_RESP_COMP_CTRL0 0x818
++/* AXI_MSTR_RESP_COMP_CTRL0 register fields */
+ #define CFG_REMOTE_RD_REQ_BRIDGE_SIZE_2K 0x4
+ #define CFG_REMOTE_RD_REQ_BRIDGE_SIZE_4K 0x5
+-#define AXI_MSTR_RESP_COMP_CTRL1 0x81c
++
++/* AXI_MSTR_RESP_COMP_CTRL1 register fields */
+ #define CFG_BRIDGE_SB_INIT BIT(0)
+
+-#define PCIE_CAP_SLOT_POWER_LIMIT_VAL FIELD_PREP(PCI_EXP_SLTCAP_SPLV, \
+- 250)
+-#define PCIE_CAP_SLOT_POWER_LIMIT_SCALE FIELD_PREP(PCI_EXP_SLTCAP_SPLS, \
+- 1)
++/* MISC_CONTROL_1_REG register fields */
++#define DBI_RO_WR_EN 1
++
++/* PCI_EXP_SLTCAP register fields */
++#define PCIE_CAP_SLOT_POWER_LIMIT_VAL FIELD_PREP(PCI_EXP_SLTCAP_SPLV, 250)
++#define PCIE_CAP_SLOT_POWER_LIMIT_SCALE FIELD_PREP(PCI_EXP_SLTCAP_SPLS, 1)
+ #define PCIE_CAP_SLOT_VAL (PCI_EXP_SLTCAP_ABP | \
+ PCI_EXP_SLTCAP_PCP | \
+ PCI_EXP_SLTCAP_MRLSP | \
+@@ -93,34 +133,12 @@
+ PCIE_CAP_SLOT_POWER_LIMIT_VAL | \
+ PCIE_CAP_SLOT_POWER_LIMIT_SCALE)
+
+-#define PARF_Q2A_FLUSH 0x1AC
+-
+-#define MISC_CONTROL_1_REG 0x8BC
+-#define DBI_RO_WR_EN 1
+-
+ #define PERST_DELAY_US 1000
+-/* PARF registers */
+-#define PARF_PCS_DEEMPH 0x34
+-#define PCS_DEEMPH_TX_DEEMPH_GEN1(x) ((x) << 16)
+-#define PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) ((x) << 8)
+-#define PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x) ((x) << 0)
+-
+-#define PARF_PCS_SWING 0x38
+-#define PCS_SWING_TX_SWING_FULL(x) ((x) << 8)
+-#define PCS_SWING_TX_SWING_LOW(x) ((x) << 0)
+-
+-#define PARF_CONFIG_BITS 0x50
+-#define PHY_RX0_EQ(x) ((x) << 24)
+-
+-#define PARF_SLV_ADDR_SPACE_SIZE 0x358
+-#define SLV_ADDR_SPACE_SZ 0x10000000
+-
+-#define DEVICE_TYPE_RC 0x4
+
+-#define QCOM_PCIE_2_1_0_MAX_SUPPLY 3
+-#define QCOM_PCIE_2_1_0_MAX_CLOCKS 5
++#define QCOM_PCIE_2_1_0_MAX_SUPPLY 3
++#define QCOM_PCIE_2_1_0_MAX_CLOCKS 5
+
+-#define QCOM_PCIE_CRC8_POLYNOMIAL (BIT(2) | BIT(1) | BIT(0))
++#define QCOM_PCIE_CRC8_POLYNOMIAL (BIT(2) | BIT(1) | BIT(0))
+
+ struct qcom_pcie_resources_2_1_0 {
+ struct clk_bulk_data clks[QCOM_PCIE_2_1_0_MAX_CLOCKS];
+--
+2.39.2
+
--- /dev/null
+From 3790d7574f10698b8bbdbef04156b74cab70e271 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 20:34:01 +0530
+Subject: PCI: qcom: Use DWC helpers for modifying the read-only DBI registers
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 60f0072d7fb7996b9a524ef0d152e21205473192 ]
+
+DWC core already exposes dw_pcie_dbi_ro_wr_{en/dis} helper APIs for
+enabling and disabling the write access to read only DBI registers. So
+let's use them instead of doing it manually.
+
+Also, the existing code doesn't disable the write access when it's done.
+This is also fixed now.
+
+Link: https://lore.kernel.org/r/20230619150408.8468-3-manivannan.sadhasivam@linaro.org
+Fixes: 5d76117f070d ("PCI: qcom: Add support for IPQ8074 PCIe controller")
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-qcom.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index e14d1a8d8f5b3..dcad29c860525 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -60,7 +60,6 @@
+ /* DBI registers */
+ #define AXI_MSTR_RESP_COMP_CTRL0 0x818
+ #define AXI_MSTR_RESP_COMP_CTRL1 0x81c
+-#define MISC_CONTROL_1_REG 0x8bc
+
+ /* PARF_SYS_CTRL register fields */
+ #define MST_WAKEUP_EN BIT(13)
+@@ -116,9 +115,6 @@
+ /* AXI_MSTR_RESP_COMP_CTRL1 register fields */
+ #define CFG_BRIDGE_SB_INIT BIT(0)
+
+-/* MISC_CONTROL_1_REG register fields */
+-#define DBI_RO_WR_EN 1
+-
+ /* PCI_EXP_SLTCAP register fields */
+ #define PCIE_CAP_SLOT_POWER_LIMIT_VAL FIELD_PREP(PCI_EXP_SLTCAP_SPLV, 250)
+ #define PCIE_CAP_SLOT_POWER_LIMIT_SCALE FIELD_PREP(PCI_EXP_SLTCAP_SPLS, 1)
+@@ -1171,7 +1167,9 @@ static int qcom_pcie_post_init_2_3_3(struct qcom_pcie *pcie)
+ writel(0, pcie->parf + PARF_Q2A_FLUSH);
+
+ writel(PCI_COMMAND_MASTER, pci->dbi_base + PCI_COMMAND);
+- writel(DBI_RO_WR_EN, pci->dbi_base + MISC_CONTROL_1_REG);
++
++ dw_pcie_dbi_ro_wr_en(pci);
++
+ writel(PCIE_CAP_SLOT_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
+
+ val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
+--
+2.39.2
+
--- /dev/null
+From 38b3e63c31d7b481cc1f2c4ceb3a6231bbe9c976 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Mar 2023 13:41:04 +0530
+Subject: PCI: qcom: Use lower case for hex
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 94ebd232dbc84dfdfbf0c406137a8b2aa8b37a01 ]
+
+To maintain uniformity, let's use lower case for representing hexadecimal
+numbers.
+
+Link: https://lore.kernel.org/r/20230316081117.14288-7-manivannan.sadhasivam@linaro.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Stable-dep-of: 60f0072d7fb7 ("PCI: qcom: Use DWC helpers for modifying the read-only DBI registers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-qcom.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index a33653d576b62..e14d1a8d8f5b3 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -39,17 +39,17 @@
+ #define PARF_PCS_DEEMPH 0x34
+ #define PARF_PCS_SWING 0x38
+ #define PARF_PHY_CTRL 0x40
+-#define PARF_PHY_REFCLK 0x4C
++#define PARF_PHY_REFCLK 0x4c
+ #define PARF_CONFIG_BITS 0x50
+ #define PARF_DBI_BASE_ADDR 0x168
+-#define PARF_SLV_ADDR_SPACE_SIZE_2_3_3 0x16C /* Register offset specific to IP ver 2.3.3 */
++#define PARF_SLV_ADDR_SPACE_SIZE_2_3_3 0x16c /* Register offset specific to IP ver 2.3.3 */
+ #define PARF_MHI_CLOCK_RESET_CTRL 0x174
+ #define PARF_AXI_MSTR_WR_ADDR_HALT 0x178
+-#define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1A8
+-#define PARF_Q2A_FLUSH 0x1AC
+-#define PARF_LTSSM 0x1B0
++#define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1a8
++#define PARF_Q2A_FLUSH 0x1ac
++#define PARF_LTSSM 0x1b0
+ #define PARF_SID_OFFSET 0x234
+-#define PARF_BDF_TRANSLATE_CFG 0x24C
++#define PARF_BDF_TRANSLATE_CFG 0x24c
+ #define PARF_SLV_ADDR_SPACE_SIZE 0x358
+ #define PARF_DEVICE_TYPE 0x1000
+ #define PARF_BDF_TO_SID_TABLE_N 0x2000
+@@ -60,7 +60,7 @@
+ /* DBI registers */
+ #define AXI_MSTR_RESP_COMP_CTRL0 0x818
+ #define AXI_MSTR_RESP_COMP_CTRL1 0x81c
+-#define MISC_CONTROL_1_REG 0x8BC
++#define MISC_CONTROL_1_REG 0x8bc
+
+ /* PARF_SYS_CTRL register fields */
+ #define MST_WAKEUP_EN BIT(13)
+--
+2.39.2
+
--- /dev/null
+From bc1d7bb51d3f2ba6b35ee52e58a0cf9198986e0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Apr 2023 17:43:31 +0800
+Subject: PCI: vmd: Fix uninitialized variable usage in vmd_enable_domain()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xinghui Li <korantli@tencent.com>
+
+[ Upstream commit 0c0206dc4f5ba2d18b15e24d2047487d6f73916b ]
+
+The ret variable in the vmd_enable_domain() function was used
+uninitialized when printing a warning message upon failure of
+the pci_reset_bus() function.
+
+Thus, fix the issue by assigning ret with the value returned from
+pci_reset_bus() before referencing it in the warning message.
+
+This was detected by Smatch:
+
+ drivers/pci/controller/vmd.c:931 vmd_enable_domain() error: uninitialized symbol 'ret'.
+
+[kwilczynski: drop the second patch from the series, add missing reported
+by tag, commit log]
+Fixes: 0a584655ef89 ("PCI: vmd: Fix secondary bus reset for Intel bridges")
+Link: https://lore.kernel.org/all/202305270219.B96IiIfv-lkp@intel.com
+Link: https://lore.kernel.org/linux-pci/20230420094332.1507900-2-korantwork@gmail.com
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Xinghui Li <korantli@tencent.com>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Nirmal Patel <nirmal.patel@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/vmd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
+index 30ec18283aaf4..e718a816d4814 100644
+--- a/drivers/pci/controller/vmd.c
++++ b/drivers/pci/controller/vmd.c
+@@ -927,7 +927,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
+ if (!list_empty(&child->devices)) {
+ dev = list_first_entry(&child->devices,
+ struct pci_dev, bus_list);
+- if (pci_reset_bus(dev))
++ ret = pci_reset_bus(dev);
++ if (ret)
+ pci_warn(dev, "can't reset device: %d\n", ret);
+
+ break;
+--
+2.39.2
+
--- /dev/null
+From 91dee0faea636d6964897b60f6559e5aeee063ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Feb 2023 13:28:11 -0700
+Subject: PCI: vmd: Reset VMD config register between soft reboots
+
+From: Nirmal Patel <nirmal.patel@linux.intel.com>
+
+[ Upstream commit b61cf04c49c3dfa70a0d6725d3eb40bf9b35cf71 ]
+
+VMD driver can disable or enable MSI remapping by changing
+VMCONFIG_MSI_REMAP register. This register needs to be set to the
+default value during soft reboots. Drives failed to enumerate
+when Windows boots after performing a soft reboot from Linux.
+Windows doesn't support MSI remapping disable feature and stale
+register value hinders Windows VMD driver initialization process.
+Adding vmd_shutdown function to make sure to set the VMCONFIG
+register to the default value.
+
+Link: https://lore.kernel.org/r/20230224202811.644370-1-nirmal.patel@linux.intel.com
+Fixes: ee81ee84f873 ("PCI: vmd: Disable MSI-X remapping when possible")
+Signed-off-by: Nirmal Patel <nirmal.patel@linux.intel.com>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Reviewed-by: Jon Derrick <jonathan.derrick@linux.dev>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/vmd.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
+index 990630ec57c6a..30ec18283aaf4 100644
+--- a/drivers/pci/controller/vmd.c
++++ b/drivers/pci/controller/vmd.c
+@@ -1036,6 +1036,13 @@ static void vmd_remove(struct pci_dev *dev)
+ ida_simple_remove(&vmd_instance_ida, vmd->instance);
+ }
+
++static void vmd_shutdown(struct pci_dev *dev)
++{
++ struct vmd_dev *vmd = pci_get_drvdata(dev);
++
++ vmd_remove_irq_domain(vmd);
++}
++
+ #ifdef CONFIG_PM_SLEEP
+ static int vmd_suspend(struct device *dev)
+ {
+@@ -1101,6 +1108,7 @@ static struct pci_driver vmd_drv = {
+ .id_table = vmd_ids,
+ .probe = vmd_probe,
+ .remove = vmd_remove,
++ .shutdown = vmd_shutdown,
+ .driver = {
+ .pm = &vmd_dev_pm_ops,
+ },
+--
+2.39.2
+
--- /dev/null
+From 40f06b8bd08261861db051c2efcd3ade9790aa4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 May 2023 17:44:32 +0100
+Subject: perf/arm-cmn: Fix DTC reset
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+[ Upstream commit 71746c995cac92fcf6a65661b51211cf2009d7f0 ]
+
+It turns out that my naive DTC reset logic fails to work as intended,
+since, after checking with the hardware designers, the PMU actually
+needs to be fully enabled in order to correctly clear any pending
+overflows. Therefore, invert the sequence to start with turning on both
+enables so that we can reliably get the DTCs into a known state, then
+moving to our normal counters-stopped state from there. Since all the
+DTM counters have already been unpaired during the initial discovery
+pass, we just need to additionally reset the cycle counters to ensure
+that no other unexpected overflows occur during this period.
+
+Fixes: 0ba64770a2f2 ("perf: Add Arm CMN-600 PMU driver")
+Reported-by: Geoff Blake <blakgeof@amazon.com>
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/0ea4559261ea394f827c9aee5168c77a60aaee03.1684946389.git.robin.murphy@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/arm-cmn.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
+index 44b719f39c3b3..4f86b7fd9823f 100644
+--- a/drivers/perf/arm-cmn.c
++++ b/drivers/perf/arm-cmn.c
+@@ -1899,9 +1899,10 @@ static int arm_cmn_init_dtc(struct arm_cmn *cmn, struct arm_cmn_node *dn, int id
+ if (dtc->irq < 0)
+ return dtc->irq;
+
+- writel_relaxed(0, dtc->base + CMN_DT_PMCR);
++ writel_relaxed(CMN_DT_DTC_CTL_DT_EN, dtc->base + CMN_DT_DTC_CTL);
++ writel_relaxed(CMN_DT_PMCR_PMU_EN | CMN_DT_PMCR_OVFL_INTR_EN, dtc->base + CMN_DT_PMCR);
++ writeq_relaxed(0, dtc->base + CMN_DT_PMCCNTR);
+ writel_relaxed(0x1ff, dtc->base + CMN_DT_PMOVSR_CLR);
+- writel_relaxed(CMN_DT_PMCR_OVFL_INTR_EN, dtc->base + CMN_DT_PMCR);
+
+ return 0;
+ }
+@@ -1961,7 +1962,7 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
+ dn->type = CMN_TYPE_CCLA;
+ }
+
+- writel_relaxed(CMN_DT_DTC_CTL_DT_EN, cmn->dtc[0].base + CMN_DT_DTC_CTL);
++ arm_cmn_set_state(cmn, CMN_STATE_DISABLED);
+
+ return 0;
+ }
+--
+2.39.2
+
--- /dev/null
+From 28ce429b55c0ac4638d63da925aba26bfddef77b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 18:01:31 +0100
+Subject: perf/arm_cspmu: Fix event attribute type
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+[ Upstream commit 71e0cb32d5fc61468e83ed962379af71bba8237e ]
+
+ARM_CSPMU_EVENT_ATTR() defines a struct perf_pmu_events_attr, so
+arm_cspmu_sysfs_event_show() should not be interpreting it as struct
+dev_ext_attribute.
+
+Fixes: e37dfd65731d ("perf: arm_cspmu: Add support for ARM CoreSight PMU driver")
+Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Reviewed-and-tested-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/27c0804af64007b2400abbc40278f642ee6a0a29.1685983270.git.robin.murphy@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/arm_cspmu/arm_cspmu.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
+index c1b6f4bdb04af..35d2fe33a7b6f 100644
+--- a/drivers/perf/arm_cspmu/arm_cspmu.c
++++ b/drivers/perf/arm_cspmu/arm_cspmu.c
+@@ -189,10 +189,10 @@ static inline bool use_64b_counter_reg(const struct arm_cspmu *cspmu)
+ ssize_t arm_cspmu_sysfs_event_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+- struct dev_ext_attribute *eattr =
+- container_of(attr, struct dev_ext_attribute, attr);
+- return sysfs_emit(buf, "event=0x%llx\n",
+- (unsigned long long)eattr->var);
++ struct perf_pmu_events_attr *pmu_attr;
++
++ pmu_attr = container_of(attr, typeof(*pmu_attr), attr);
++ return sysfs_emit(buf, "event=0x%llx\n", pmu_attr->id);
+ }
+ EXPORT_SYMBOL_GPL(arm_cspmu_sysfs_event_show);
+
+--
+2.39.2
+
--- /dev/null
+From 97f9a956c4c84fc8ad406ab0f249d5350a78e2dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Jun 2023 13:37:42 -0700
+Subject: perf: arm_cspmu: Set irq affinitiy only if overflow interrupt is used
+
+From: Ilkka Koskinen <ilkka@os.amperecomputing.com>
+
+[ Upstream commit 225d757012e0afa673d8c862e6fb39ed2f429b4d ]
+
+Don't try to set irq affinity if PMU doesn't have an overflow interrupt.
+
+Fixes: e37dfd65731d ("perf: arm_cspmu: Add support for ARM CoreSight PMU driver")
+Signed-off-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>
+Link: https://lore.kernel.org/r/20230608203742.3503486-1-ilkka@os.amperecomputing.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/arm_cspmu/arm_cspmu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
+index e31302ab7e37c..c1b6f4bdb04af 100644
+--- a/drivers/perf/arm_cspmu/arm_cspmu.c
++++ b/drivers/perf/arm_cspmu/arm_cspmu.c
+@@ -1230,7 +1230,8 @@ static struct platform_driver arm_cspmu_driver = {
+ static void arm_cspmu_set_active_cpu(int cpu, struct arm_cspmu *cspmu)
+ {
+ cpumask_set_cpu(cpu, &cspmu->active_cpu);
+- WARN_ON(irq_set_affinity(cspmu->irq, &cspmu->active_cpu));
++ if (cspmu->irq)
++ WARN_ON(irq_set_affinity(cspmu->irq, &cspmu->active_cpu));
+ }
+
+ static int arm_cspmu_cpu_online(unsigned int cpu, struct hlist_node *node)
+--
+2.39.2
+
--- /dev/null
+From 13fb449f4ab5647ca23a55f746a0aa5c98c5e930 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 15:38:25 -0300
+Subject: perf bench: Add missing setlocale() call to allow usage of %'d style
+ formatting
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit 16203e9cd01896b4244100a8e3fb9f6e612ab2b1 ]
+
+Without this we were not getting the thousands separator for big
+numbers.
+
+Noticed while developing 'perf bench uprobe', but the use of %' predates
+that, for instance 'perf bench syscall' uses it.
+
+Before:
+
+ # perf bench uprobe all
+ # Running uprobe/baseline benchmark...
+ # Executed 1000 usleep(1000) calls
+ Total time: 1054082243ns
+
+ 1054082.243000 nsecs/op
+
+ #
+
+After:
+
+ # perf bench uprobe all
+ # Running uprobe/baseline benchmark...
+ # Executed 1,000 usleep(1000) calls
+ Total time: 1,053,715,144ns
+
+ 1,053,715.144000 nsecs/op
+
+ #
+
+Fixes: c2a08203052f8975 ("perf bench: Add basic syscall benchmark")
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Andre Fredette <anfredet@redhat.com>
+Cc: Clark Williams <williams@redhat.com>
+Cc: Dave Tucker <datucker@redhat.com>
+Cc: Davidlohr Bueso <dave@stgolabs.net>
+Cc: Derek Barbosa <debarbos@redhat.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
+Link: https://lore.kernel.org/lkml/ZH3lcepZ4tBYr1jv@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-bench.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
+index 814e9afc86f6e..5efb29a7564af 100644
+--- a/tools/perf/builtin-bench.c
++++ b/tools/perf/builtin-bench.c
+@@ -21,6 +21,7 @@
+ #include "builtin.h"
+ #include "bench/bench.h"
+
++#include <locale.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -258,6 +259,7 @@ int cmd_bench(int argc, const char **argv)
+
+ /* Unbuffered output */
+ setvbuf(stdout, NULL, _IONBF, 0);
++ setlocale(LC_ALL, "");
+
+ if (argc < 2) {
+ /* No collection specified. */
+--
+2.39.2
+
--- /dev/null
+From dc7e554ee88988776b8d16659aafcade488702bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 16:41:01 -0700
+Subject: perf dwarf-aux: Fix off-by-one in die_get_varname()
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit 3abfcfd847717d232e36963f31a361747c388fe7 ]
+
+The die_get_varname() returns "(unknown_type)" string if it failed to
+find a type for the variable. But it had a space before the opening
+parenthesis and it made the closing parenthesis cut off due to the
+off-by-one in the string length (14).
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Fixes: 88fd633cdfa19060 ("perf probe: No need to use formatting strbuf method")
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20230612234102.3909116-1-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/dwarf-aux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
+index b074144097710..3bff678745635 100644
+--- a/tools/perf/util/dwarf-aux.c
++++ b/tools/perf/util/dwarf-aux.c
+@@ -1103,7 +1103,7 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf)
+ ret = die_get_typename(vr_die, buf);
+ if (ret < 0) {
+ pr_debug("Failed to get type, make it unknown.\n");
+- ret = strbuf_add(buf, " (unknown_type)", 14);
++ ret = strbuf_add(buf, "(unknown_type)", 14);
+ }
+
+ return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
+--
+2.39.2
+
--- /dev/null
+From 9c516c69f845ebb46bc3f633e11350ae71c8d4c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 May 2023 12:44:42 -0700
+Subject: perf evsel: Don't let for_each_group() treat the head of the list as
+ one of its nodes
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 797b9ec8c4bc9ec89f633a9b2c710b7b64753ca4 ]
+
+Address/memory sanitizer was reporting issues in evsel__group_pmu_name
+because the for_each_group_evsel loop didn't terminate when the head
+was reached, the head would then be cast and accessed as an evsel
+leading to invalid memory accesses.
+
+Fix for_each_group_member and for_each_group_evsel to terminate at the
+list head. Note, evsel__group_pmu_name no longer iterates the group, but
+the problem is present regardless.
+
+Fixes: 717e263fc354d53d ("perf report: Show group description when event group is enabled")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Changbin Du <changbin.du@huawei.com>
+Cc: Dmitrii Dolgov <9erthalion6@gmail.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung.kim@lge.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Rob Herring <robh@kernel.org>
+Cc: Sandipan Das <sandipan.das@amd.com>
+Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
+Link: https://lore.kernel.org/r/20230526194442.2355872-3-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/evsel.h | 24 ++++++++++++++++--------
+ tools/perf/util/evsel_fprintf.c | 1 +
+ 2 files changed, 17 insertions(+), 8 deletions(-)
+
+diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
+index 1a7358b46ad4e..72549fd79992b 100644
+--- a/tools/perf/util/evsel.h
++++ b/tools/perf/util/evsel.h
+@@ -457,16 +457,24 @@ static inline int evsel__group_idx(struct evsel *evsel)
+ }
+
+ /* Iterates group WITHOUT the leader. */
+-#define for_each_group_member(_evsel, _leader) \
+-for ((_evsel) = list_entry((_leader)->core.node.next, struct evsel, core.node); \
+- (_evsel) && (_evsel)->core.leader == (&_leader->core); \
+- (_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node))
++#define for_each_group_member_head(_evsel, _leader, _head) \
++for ((_evsel) = list_entry((_leader)->core.node.next, struct evsel, core.node); \
++ (_evsel) && &(_evsel)->core.node != (_head) && \
++ (_evsel)->core.leader == &(_leader)->core; \
++ (_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node))
++
++#define for_each_group_member(_evsel, _leader) \
++ for_each_group_member_head(_evsel, _leader, &(_leader)->evlist->core.entries)
+
+ /* Iterates group WITH the leader. */
+-#define for_each_group_evsel(_evsel, _leader) \
+-for ((_evsel) = _leader; \
+- (_evsel) && (_evsel)->core.leader == (&_leader->core); \
+- (_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node))
++#define for_each_group_evsel_head(_evsel, _leader, _head) \
++for ((_evsel) = _leader; \
++ (_evsel) && &(_evsel)->core.node != (_head) && \
++ (_evsel)->core.leader == &(_leader)->core; \
++ (_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node))
++
++#define for_each_group_evsel(_evsel, _leader) \
++ for_each_group_evsel_head(_evsel, _leader, &(_leader)->evlist->core.entries)
+
+ static inline bool evsel__has_branch_callstack(const struct evsel *evsel)
+ {
+diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c
+index bd22c4932d10e..6fa3a306f301d 100644
+--- a/tools/perf/util/evsel_fprintf.c
++++ b/tools/perf/util/evsel_fprintf.c
+@@ -2,6 +2,7 @@
+ #include <inttypes.h>
+ #include <stdio.h>
+ #include <stdbool.h>
++#include "util/evlist.h"
+ #include "evsel.h"
+ #include "util/evsel_fprintf.h"
+ #include "util/event.h"
+--
+2.39.2
+
--- /dev/null
+From 5725e459ee20e70d7366874c4181b4eeed3cc42e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 May 2023 16:30:01 +0530
+Subject: perf/ibs: Fix interface via core pmu events
+
+From: Ravi Bangoria <ravi.bangoria@amd.com>
+
+[ Upstream commit 2fad201fe38ff9a692acedb1990ece2c52a29f95 ]
+
+Although, IBS pmus can be invoked via their own interface, indirect
+IBS invocation via core pmu events is also supported with fixed set
+of events: cpu-cycles:p, r076:p (same as cpu-cycles:p) and r0C1:p
+(micro-ops) for user convenience.
+
+This indirect IBS invocation is broken since commit 66d258c5b048
+("perf/core: Optimize perf_init_event()"), which added RAW pmu under
+'pmu_idr' list and thus if event_init() fails with RAW pmu, it started
+returning error instead of trying other pmus.
+
+Forward precise events from core pmu to IBS by overwriting 'type' and
+'config' in the kernel copy of perf_event_attr. Overwriting will cause
+perf_init_event() to retry with updated 'type' and 'config', which will
+automatically forward event to IBS pmu.
+
+Without patch:
+ $ sudo ./perf record -C 0 -e r076:p -- sleep 1
+ Error:
+ The r076:p event is not supported.
+
+With patch:
+ $ sudo ./perf record -C 0 -e r076:p -- sleep 1
+ [ perf record: Woken up 1 times to write data ]
+ [ perf record: Captured and wrote 0.341 MB perf.data (37 samples) ]
+
+Fixes: 66d258c5b048 ("perf/core: Optimize perf_init_event()")
+Reported-by: Stephane Eranian <eranian@google.com>
+Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20230504110003.2548-3-ravi.bangoria@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/amd/core.c | 2 +-
+ arch/x86/events/amd/ibs.c | 53 +++++++++++++++----------------
+ arch/x86/include/asm/perf_event.h | 2 ++
+ 3 files changed, 29 insertions(+), 28 deletions(-)
+
+diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
+index bccea57dee81e..abadd5f234254 100644
+--- a/arch/x86/events/amd/core.c
++++ b/arch/x86/events/amd/core.c
+@@ -374,7 +374,7 @@ static int amd_pmu_hw_config(struct perf_event *event)
+
+ /* pass precise event sampling to ibs: */
+ if (event->attr.precise_ip && get_ibs_caps())
+- return -ENOENT;
++ return forward_event_to_ibs(event);
+
+ if (has_branch_stack(event) && !x86_pmu.lbr_nr)
+ return -EOPNOTSUPP;
+diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
+index 64582954b5f67..3710148021916 100644
+--- a/arch/x86/events/amd/ibs.c
++++ b/arch/x86/events/amd/ibs.c
+@@ -190,7 +190,7 @@ static struct perf_ibs *get_ibs_pmu(int type)
+ }
+
+ /*
+- * Use IBS for precise event sampling:
++ * core pmu config -> IBS config
+ *
+ * perf record -a -e cpu-cycles:p ... # use ibs op counting cycle count
+ * perf record -a -e r076:p ... # same as -e cpu-cycles:p
+@@ -199,25 +199,9 @@ static struct perf_ibs *get_ibs_pmu(int type)
+ * IbsOpCntCtl (bit 19) of IBS Execution Control Register (IbsOpCtl,
+ * MSRC001_1033) is used to select either cycle or micro-ops counting
+ * mode.
+- *
+- * The rip of IBS samples has skid 0. Thus, IBS supports precise
+- * levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the
+- * rip is invalid when IBS was not able to record the rip correctly.
+- * We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then.
+- *
+ */
+-static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
++static int core_pmu_ibs_config(struct perf_event *event, u64 *config)
+ {
+- switch (event->attr.precise_ip) {
+- case 0:
+- return -ENOENT;
+- case 1:
+- case 2:
+- break;
+- default:
+- return -EOPNOTSUPP;
+- }
+-
+ switch (event->attr.type) {
+ case PERF_TYPE_HARDWARE:
+ switch (event->attr.config) {
+@@ -243,22 +227,37 @@ static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
+ return -EOPNOTSUPP;
+ }
+
++/*
++ * The rip of IBS samples has skid 0. Thus, IBS supports precise
++ * levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the
++ * rip is invalid when IBS was not able to record the rip correctly.
++ * We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then.
++ */
++int forward_event_to_ibs(struct perf_event *event)
++{
++ u64 config = 0;
++
++ if (!event->attr.precise_ip || event->attr.precise_ip > 2)
++ return -EOPNOTSUPP;
++
++ if (!core_pmu_ibs_config(event, &config)) {
++ event->attr.type = perf_ibs_op.pmu.type;
++ event->attr.config = config;
++ }
++ return -ENOENT;
++}
++
+ static int perf_ibs_init(struct perf_event *event)
+ {
+ struct hw_perf_event *hwc = &event->hw;
+ struct perf_ibs *perf_ibs;
+ u64 max_cnt, config;
+- int ret;
+
+ perf_ibs = get_ibs_pmu(event->attr.type);
+- if (perf_ibs) {
+- config = event->attr.config;
+- } else {
+- perf_ibs = &perf_ibs_op;
+- ret = perf_ibs_precise_event(event, &config);
+- if (ret)
+- return ret;
+- }
++ if (!perf_ibs)
++ return -ENOENT;
++
++ config = event->attr.config;
+
+ if (event->pmu != &perf_ibs->pmu)
+ return -ENOENT;
+diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
+index abf09882f58b6..f1a46500a2753 100644
+--- a/arch/x86/include/asm/perf_event.h
++++ b/arch/x86/include/asm/perf_event.h
+@@ -478,8 +478,10 @@ struct pebs_xmm {
+
+ #ifdef CONFIG_X86_LOCAL_APIC
+ extern u32 get_ibs_caps(void);
++extern int forward_event_to_ibs(struct perf_event *event);
+ #else
+ static inline u32 get_ibs_caps(void) { return 0; }
++static inline int forward_event_to_ibs(struct perf_event *event) { return -ENOENT; }
+ #endif
+
+ #ifdef CONFIG_PERF_EVENTS
+--
+2.39.2
+
--- /dev/null
+From 53f3b89dc683422cbc4638a9af57e87543ae6e54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 16:11:10 -0300
+Subject: perf script: Fix allocation of evsel->priv related to per-event dump
+ files
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit 36d3e4138e1b6cc9ab179f3f397b5548f8b1eaae ]
+
+When printing output we may want to generate per event files, where the
+--per-event-dump option should be used, creating perf.data.EVENT.dump
+files instead of printing to stdout.
+
+The callback thar processes event thus expects that evsel->priv->fp
+should point to either the per-event FILE descriptor or to stdout.
+
+The a3af66f51bd0bca7 ("perf script: Fix crash because of missing
+evsel->priv") changeset fixed a case where evsel->priv wasn't setup,
+thus set to NULL, causing a segfault when trying to access
+evsel->priv->fp.
+
+But it did it for the non --per-event-dump case by allocating a 'struct
+perf_evsel_script' just to set its ->fp to stdout.
+
+Since evsel->priv is only freed when --per-event-dump is used, we ended
+up with a memory leak, detected using ASAN.
+
+Fix it by using the same method as perf_script__setup_per_event_dump(),
+and reuse that static 'struct perf_evsel_script'.
+
+Also check if evsel_script__new() failed.
+
+Fixes: a3af66f51bd0bca7 ("perf script: Fix crash because of missing evsel->priv")
+Reported-by: Ian Rogers <irogers@google.com>
+Tested-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
+Link: https://lore.kernel.org/lkml/ZH+F0wGAWV14zvMP@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-script.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
+index d8c174a719383..72a3faa28c394 100644
+--- a/tools/perf/builtin-script.c
++++ b/tools/perf/builtin-script.c
+@@ -2425,6 +2425,9 @@ static int process_sample_event(struct perf_tool *tool,
+ return ret;
+ }
+
++// Used when scr->per_event_dump is not set
++static struct evsel_script es_stdout;
++
+ static int process_attr(struct perf_tool *tool, union perf_event *event,
+ struct evlist **pevlist)
+ {
+@@ -2433,7 +2436,6 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
+ struct evsel *evsel, *pos;
+ u64 sample_type;
+ int err;
+- static struct evsel_script *es;
+
+ err = perf_event__process_attr(tool, event, pevlist);
+ if (err)
+@@ -2443,14 +2445,13 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
+ evsel = evlist__last(*pevlist);
+
+ if (!evsel->priv) {
+- if (scr->per_event_dump) {
++ if (scr->per_event_dump) {
+ evsel->priv = evsel_script__new(evsel, scr->session->data);
+- } else {
+- es = zalloc(sizeof(*es));
+- if (!es)
++ if (!evsel->priv)
+ return -ENOMEM;
+- es->fp = stdout;
+- evsel->priv = es;
++ } else { // Replicate what is done in perf_script__setup_per_event_dump()
++ es_stdout.fp = stdout;
++ evsel->priv = &es_stdout;
+ }
+ }
+
+@@ -2756,7 +2757,6 @@ static int perf_script__fopen_per_event_dump(struct perf_script *script)
+ static int perf_script__setup_per_event_dump(struct perf_script *script)
+ {
+ struct evsel *evsel;
+- static struct evsel_script es_stdout;
+
+ if (script->per_event_dump)
+ return perf_script__fopen_per_event_dump(script);
+--
+2.39.2
+
--- /dev/null
+From bb5ebf5dc2e433b5311fec320a667393373a8505 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 00:32:10 -0700
+Subject: perf stat: Reset aggr stats for each run
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit ed4090a22c123b9b33368741253edddc6ff8d18f ]
+
+When it runs multiple times with -r option, it missed to reset the
+aggregation counters and the values were added up. The aggregation
+count has the values to be printed in the end. It should reset the
+counters at the beginning of each run. But the current code does that
+only when -I/--interval-print option is given.
+
+Fixes: 91f85f98da7ab8c3 ("perf stat: Display event stats using aggr counts")
+Reported-by: Jiri Olsa <jolsa@kernel.org>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20230616073211.1057936-1-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-stat.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
+index eeba93ae3b584..f5a6d08cf07f6 100644
+--- a/tools/perf/builtin-stat.c
++++ b/tools/perf/builtin-stat.c
+@@ -777,6 +777,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
+ all_counters_use_bpf = false;
+ }
+
++ evlist__reset_aggr_stats(evsel_list);
++
+ evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) {
+ counter = evlist_cpu_itr.evsel;
+
+--
+2.39.2
+
--- /dev/null
+From a70f8519acd4a6388165ea550418e7f3075feb49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 16:53:57 -0700
+Subject: perf test: Set PERF_EXEC_PATH for script execution
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit e4ef3ef1bc0a3d2535427da78b8095ef657eb474 ]
+
+The task-analyzer.py script (actually every other scripts too) requires
+PERF_EXEC_PATH env to find dependent libraries and scripts. For scripts
+test to run correctly, it needs to set PERF_EXEC_PATH to the perf tool
+source directory.
+
+Instead of blindly update the env, let's check the directory structure
+to make sure it points to the correct location.
+
+Fixes: e8478b84d6ba ("perf test: add new task-analyzer tests")
+Cc: Petar Gligoric <petar.gligoric@rohde-schwarz.com>
+Cc: Hagen Paul Pfeifer <hagen@jauu.net>
+Cc: Aditya Gupta <adityag@linux.ibm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Ingo Molnar <mingo@kernel.org>
+Acked-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/shell/test_task_analyzer.sh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/tools/perf/tests/shell/test_task_analyzer.sh b/tools/perf/tests/shell/test_task_analyzer.sh
+index 1b7f3c1ec218b..365b61aea519a 100755
+--- a/tools/perf/tests/shell/test_task_analyzer.sh
++++ b/tools/perf/tests/shell/test_task_analyzer.sh
+@@ -5,6 +5,12 @@
+ tmpdir=$(mktemp -d /tmp/perf-script-task-analyzer-XXXXX)
+ err=0
+
++# set PERF_EXEC_PATH to find scripts in the source directory
++perfdir=$(dirname "$0")/../..
++if [ -e "$perfdir/scripts/python/Perf-Trace-Util" ]; then
++ export PERF_EXEC_PATH=$perfdir
++fi
++
+ cleanup() {
+ rm -f perf.data
+ rm -f perf.data.old
+--
+2.39.2
+
--- /dev/null
+From 71b0754fbf47c071574f9e139c42f7b39b2d3ada Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 22:11:43 +0530
+Subject: perf tests task_analyzer: Fix bad substitution ${$1}
+
+From: Aditya Gupta <adityag@linux.ibm.com>
+
+[ Upstream commit 5c4396efb53ef07d046a2e9456b240880e0c3076 ]
+
+${$1} gives bad substitution error on sh, bash, and zsh. This seems like
+a typo, and this patch modifies it to $1, since that is what it's usage
+looks like from wherever `check_exec_0` is called.
+
+This issue due to ${$1} caused all function calls to give error in
+`find_str_or_fail` line, and so no test runs completely. But
+'perf test "perf script task-analyzer tests"' wrongly reports
+that tests passed with the status OK, which is wrong considering
+the tests didn't even run completely
+
+Fixes: e8478b84d6ba9ccf ("perf test: add new task-analyzer tests")
+Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
+Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
+Cc: Disha Goel <disgoel@linux.vnet.ibm.com>
+Cc: Hagen Paul Pfeifer <hagen@jauu.net>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Garry <john.g.garry@oracle.com>
+Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Petar Gligoric <petar.gligoric@rohde-schwarz.com>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: linuxppc-dev@lists.ozlabs.org
+Link: https://lore.kernel.org/r/20230613164145.50488-16-atrajeev@linux.vnet.ibm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/shell/test_task_analyzer.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/tests/shell/test_task_analyzer.sh b/tools/perf/tests/shell/test_task_analyzer.sh
+index a98e4ab66040e..6b3343234a6b2 100755
+--- a/tools/perf/tests/shell/test_task_analyzer.sh
++++ b/tools/perf/tests/shell/test_task_analyzer.sh
+@@ -31,7 +31,7 @@ report() {
+
+ check_exec_0() {
+ if [ $? != 0 ]; then
+- report 1 "invokation of ${$1} command failed"
++ report 1 "invocation of $1 command failed"
+ fi
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 44b2972519a6ad332683b784c48f8b8ae099d8ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 22:11:45 +0530
+Subject: perf tests task_analyzer: Skip tests if no libtraceevent support
+
+From: Aditya Gupta <adityag@linux.ibm.com>
+
+[ Upstream commit c3ac3b0779770acd3ad7eecb5099ab4419ef2e2e ]
+
+Test "perf script task-analyzer tests" fails in environment with missing
+libtraceevent support, as perf record fails to create the perf.data
+file, which further tests depend on.
+
+Instead, when perf is not compiled with libtraceevent support, skip
+those tests instead of failing them, by checking the output of `perf
+record --dry-run` to see if it prints the error "libtraceevent is
+necessary for tracepoint support"
+
+For the following output, perf compiled with: `make NO_LIBTRACEEVENT=1`
+
+Before the patch:
+
+108: perf script task-analyzer tests :
+test child forked, pid 24105
+failed to open perf.data: No such file or directory (try 'perf record' first)
+FAIL: "invokation of perf script report task-analyzer command failed" Error message: ""
+FAIL: "test_basic" Error message: "Failed to find required string:'Comm'."
+failed to open perf.data: No such file or directory (try 'perf record' first)
+FAIL: "invokation of perf script report task-analyzer --ns --rename-comms-by-tids 0:random command failed" Error message: ""
+FAIL: "test_ns_rename" Error message: "Failed to find required string:'Comm'."
+failed to open perf.data: No such file or directory (try 'perf record' first)
+<...>
+perf script task-analyzer tests: FAILED!
+
+With this patch, the script instead returns 2 signifying SKIP, and after
+the patch:
+
+108: perf script task-analyzer tests :
+test child forked, pid 26010
+libtraceevent is necessary for tracepoint support
+WARN: Skipping tests. No libtraceevent support
+test child finished with -2
+perf script task-analyzer tests: Skip
+
+Fixes: e8478b84d6ba9ccf ("perf test: Add new task-analyzer tests")
+Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
+Cc: Disha Goel <disgoel@linux.vnet.ibm.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Garry <john.g.garry@oracle.com>
+Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Petar Gligoric <petar.gligoric@rohde-schwarz.com>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: linuxppc-dev@lists.ozlabs.org
+Link: https://lore.kernel.org/r/20230613164145.50488-18-atrajeev@linux.vnet.ibm.com
+Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/shell/test_task_analyzer.sh | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/tools/perf/tests/shell/test_task_analyzer.sh b/tools/perf/tests/shell/test_task_analyzer.sh
+index 6b3343234a6b2..1b7f3c1ec218b 100755
+--- a/tools/perf/tests/shell/test_task_analyzer.sh
++++ b/tools/perf/tests/shell/test_task_analyzer.sh
+@@ -44,9 +44,20 @@ find_str_or_fail() {
+ fi
+ }
+
++# check if perf is compiled with libtraceevent support
++skip_no_probe_record_support() {
++ perf record -e "sched:sched_switch" -a -- sleep 1 2>&1 | grep "libtraceevent is necessary for tracepoint support" && return 2
++ return 0
++}
++
+ prepare_perf_data() {
+ # 1s should be sufficient to catch at least some switches
+ perf record -e sched:sched_switch -a -- sleep 1 > /dev/null 2>&1
++ # check if perf data file got created in above step.
++ if [ ! -e "perf.data" ]; then
++ printf "FAIL: perf record failed to create \"perf.data\" \n"
++ return 1
++ fi
+ }
+
+ # check standard inkvokation with no arguments
+@@ -134,6 +145,13 @@ test_csvsummary_extended() {
+ find_str_or_fail "Out-Out;" csvsummary ${FUNCNAME[0]}
+ }
+
++skip_no_probe_record_support
++err=$?
++if [ $err -ne 0 ]; then
++ echo "WARN: Skipping tests. No libtraceevent support"
++ cleanup
++ exit $err
++fi
+ prepare_perf_data
+ test_basic
+ test_ns_rename
+--
+2.39.2
+
--- /dev/null
+From e2c562d23ee72769ca0df876a9640e213aea8531 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 15:25:04 +0530
+Subject: perf tool x86: Consolidate is_amd check into single function
+
+From: Ravi Bangoria <ravi.bangoria@amd.com>
+
+[ Upstream commit 0cd1ca4650c9cf5f318110f67d39cbebae3693b3 ]
+
+There are multiple places where x86 specific code determines AMD vs
+Intel arch and acts based on that. Consolidate those checks into a
+single function.
+
+Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
+Acked-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ali Saidi <alisaidi@amazon.com>
+Cc: Ananth Narayan <ananth.narayan@amd.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Sandipan Das <sandipan.das@amd.com>
+Cc: Santosh Shukla <santosh.shukla@amd.com>
+Link: https://lore.kernel.org/r/20230613095506.547-3-ravi.bangoria@amd.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 99d4850062a8 ("perf tool x86: Fix perf_env memory leak")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/arch/x86/util/Build | 1 +
+ tools/perf/arch/x86/util/env.c | 19 +++++++++++++++++++
+ tools/perf/arch/x86/util/env.h | 7 +++++++
+ tools/perf/arch/x86/util/evsel.c | 16 ++--------------
+ tools/perf/arch/x86/util/mem-events.c | 19 ++-----------------
+ 5 files changed, 31 insertions(+), 31 deletions(-)
+ create mode 100644 tools/perf/arch/x86/util/env.c
+ create mode 100644 tools/perf/arch/x86/util/env.h
+
+diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build
+index 195ccfdef7aa1..005907cb97d8c 100644
+--- a/tools/perf/arch/x86/util/Build
++++ b/tools/perf/arch/x86/util/Build
+@@ -10,6 +10,7 @@ perf-y += evlist.o
+ perf-y += mem-events.o
+ perf-y += evsel.o
+ perf-y += iostat.o
++perf-y += env.o
+
+ perf-$(CONFIG_DWARF) += dwarf-regs.o
+ perf-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o
+diff --git a/tools/perf/arch/x86/util/env.c b/tools/perf/arch/x86/util/env.c
+new file mode 100644
+index 0000000000000..33b87f8ac1cc1
+--- /dev/null
++++ b/tools/perf/arch/x86/util/env.c
+@@ -0,0 +1,19 @@
++// SPDX-License-Identifier: GPL-2.0
++#include "linux/string.h"
++#include "util/env.h"
++#include "env.h"
++
++bool x86__is_amd_cpu(void)
++{
++ struct perf_env env = { .total_mem = 0, };
++ static int is_amd; /* 0: Uninitialized, 1: Yes, -1: No */
++
++ if (is_amd)
++ goto ret;
++
++ perf_env__cpuid(&env);
++ is_amd = env.cpuid && strstarts(env.cpuid, "AuthenticAMD") ? 1 : -1;
++
++ret:
++ return is_amd >= 1 ? true : false;
++}
+diff --git a/tools/perf/arch/x86/util/env.h b/tools/perf/arch/x86/util/env.h
+new file mode 100644
+index 0000000000000..d78f080b6b3f8
+--- /dev/null
++++ b/tools/perf/arch/x86/util/env.h
+@@ -0,0 +1,7 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef _X86_ENV_H
++#define _X86_ENV_H
++
++bool x86__is_amd_cpu(void);
++
++#endif /* _X86_ENV_H */
+diff --git a/tools/perf/arch/x86/util/evsel.c b/tools/perf/arch/x86/util/evsel.c
+index ea3972d785d10..d72390cdf391d 100644
+--- a/tools/perf/arch/x86/util/evsel.c
++++ b/tools/perf/arch/x86/util/evsel.c
+@@ -7,6 +7,7 @@
+ #include "linux/string.h"
+ #include "evsel.h"
+ #include "util/debug.h"
++#include "env.h"
+
+ #define IBS_FETCH_L3MISSONLY (1ULL << 59)
+ #define IBS_OP_L3MISSONLY (1ULL << 16)
+@@ -97,23 +98,10 @@ void arch__post_evsel_config(struct evsel *evsel, struct perf_event_attr *attr)
+ {
+ struct perf_pmu *evsel_pmu, *ibs_fetch_pmu, *ibs_op_pmu;
+ static int warned_once;
+- /* 0: Uninitialized, 1: Yes, -1: No */
+- static int is_amd;
+
+- if (warned_once || is_amd == -1)
++ if (warned_once || !x86__is_amd_cpu())
+ return;
+
+- if (!is_amd) {
+- struct perf_env *env = evsel__env(evsel);
+-
+- if (!perf_env__cpuid(env) || !env->cpuid ||
+- !strstarts(env->cpuid, "AuthenticAMD")) {
+- is_amd = -1;
+- return;
+- }
+- is_amd = 1;
+- }
+-
+ evsel_pmu = evsel__find_pmu(evsel);
+ if (!evsel_pmu)
+ return;
+diff --git a/tools/perf/arch/x86/util/mem-events.c b/tools/perf/arch/x86/util/mem-events.c
+index f683ac702247c..efc0fae9ed0a7 100644
+--- a/tools/perf/arch/x86/util/mem-events.c
++++ b/tools/perf/arch/x86/util/mem-events.c
+@@ -4,6 +4,7 @@
+ #include "map_symbol.h"
+ #include "mem-events.h"
+ #include "linux/string.h"
++#include "env.h"
+
+ static char mem_loads_name[100];
+ static bool mem_loads_name__init;
+@@ -26,28 +27,12 @@ static struct perf_mem_event perf_mem_events_amd[PERF_MEM_EVENTS__MAX] = {
+ E("mem-ldst", "ibs_op//", "ibs_op"),
+ };
+
+-static int perf_mem_is_amd_cpu(void)
+-{
+- struct perf_env env = { .total_mem = 0, };
+-
+- perf_env__cpuid(&env);
+- if (env.cpuid && strstarts(env.cpuid, "AuthenticAMD"))
+- return 1;
+- return -1;
+-}
+-
+ struct perf_mem_event *perf_mem_events__ptr(int i)
+ {
+- /* 0: Uninitialized, 1: Yes, -1: No */
+- static int is_amd;
+-
+ if (i >= PERF_MEM_EVENTS__MAX)
+ return NULL;
+
+- if (!is_amd)
+- is_amd = perf_mem_is_amd_cpu();
+-
+- if (is_amd == 1)
++ if (x86__is_amd_cpu())
+ return &perf_mem_events_amd[i];
+
+ return &perf_mem_events_intel[i];
+--
+2.39.2
+
--- /dev/null
+From dae03beb55dd3de69cf5153f29b9391b6d1ac240 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 16:54:16 -0700
+Subject: perf tool x86: Fix perf_env memory leak
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 99d4850062a84564f36923764bb93935ef2ed108 ]
+
+Found by leak sanitizer:
+```
+==1632594==ERROR: LeakSanitizer: detected memory leaks
+
+Direct leak of 21 byte(s) in 1 object(s) allocated from:
+ #0 0x7f2953a7077b in __interceptor_strdup ../../../../src/libsanitizer/asan/asan_interceptors.cpp:439
+ #1 0x556701d6fbbf in perf_env__read_cpuid util/env.c:369
+ #2 0x556701d70589 in perf_env__cpuid util/env.c:465
+ #3 0x55670204bba2 in x86__is_amd_cpu arch/x86/util/env.c:14
+ #4 0x5567020487a2 in arch__post_evsel_config arch/x86/util/evsel.c:83
+ #5 0x556701d8f78b in evsel__config util/evsel.c:1366
+ #6 0x556701ef5872 in evlist__config util/record.c:108
+ #7 0x556701cd6bcd in test__PERF_RECORD tests/perf-record.c:112
+ #8 0x556701cacd07 in run_test tests/builtin-test.c:236
+ #9 0x556701cacfac in test_and_print tests/builtin-test.c:265
+ #10 0x556701cadddb in __cmd_test tests/builtin-test.c:402
+ #11 0x556701caf2aa in cmd_test tests/builtin-test.c:559
+ #12 0x556701d3b557 in run_builtin tools/perf/perf.c:323
+ #13 0x556701d3bac8 in handle_internal_command tools/perf/perf.c:377
+ #14 0x556701d3be90 in run_argv tools/perf/perf.c:421
+ #15 0x556701d3c3f8 in main tools/perf/perf.c:537
+ #16 0x7f2952a46189 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
+
+SUMMARY: AddressSanitizer: 21 byte(s) leaked in 1 allocation(s).
+```
+
+Fixes: f7b58cbdb3ff36eb ("perf mem/c2c: Add load store event mappings for AMD")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Ravi Bangoria <ravi.bangoria@amd.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Link: https://lore.kernel.org/r/20230613235416.1650755-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/arch/x86/util/env.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/arch/x86/util/env.c b/tools/perf/arch/x86/util/env.c
+index 33b87f8ac1cc1..3e537ffb1353a 100644
+--- a/tools/perf/arch/x86/util/env.c
++++ b/tools/perf/arch/x86/util/env.c
+@@ -13,7 +13,7 @@ bool x86__is_amd_cpu(void)
+
+ perf_env__cpuid(&env);
+ is_amd = env.cpuid && strstarts(env.cpuid, "AuthenticAMD") ? 1 : -1;
+-
++ perf_env__exit(&env);
+ ret:
+ return is_amd >= 1 ? true : false;
+ }
+--
+2.39.2
+
--- /dev/null
+From c32ef4cd41120e7a4eaf3a1779fdabb058b80166 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 15:42:39 +0200
+Subject: pinctrl: at91: Don't mix non-devm calls with devm ones
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 415a099ea55ae716b69beefdcaa654b96087c016 ]
+
+Replace devm_clk_get() by devm_clk_get_enabled() and drop
+unneeded code pieces. This will make sure we keep the ordering
+of the resource allocation correct.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Tested-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230215134242.37618-3-andriy.shevchenko@linux.intel.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: 35216718c9ac ("pinctrl: at91: fix a couple NULL vs IS_ERR() checks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-at91.c | 12 ++----------
+ 1 file changed, 2 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
+index 9fa68ca4a412d..f0b139a1cc3ed 100644
+--- a/drivers/pinctrl/pinctrl-at91.c
++++ b/drivers/pinctrl/pinctrl-at91.c
+@@ -1849,19 +1849,13 @@ static int at91_gpio_probe(struct platform_device *pdev)
+ at91_chip->pioc_virq = irq;
+ at91_chip->pioc_idx = alias_idx;
+
+- at91_chip->clock = devm_clk_get(&pdev->dev, NULL);
++ at91_chip->clock = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(at91_chip->clock)) {
+ dev_err(&pdev->dev, "failed to get clock, ignoring.\n");
+ ret = PTR_ERR(at91_chip->clock);
+ goto err;
+ }
+
+- ret = clk_prepare_enable(at91_chip->clock);
+- if (ret) {
+- dev_err(&pdev->dev, "failed to prepare and enable clock, ignoring.\n");
+- goto clk_enable_err;
+- }
+-
+ at91_chip->chip = at91_gpio_template;
+ at91_chip->id = alias_idx;
+
+@@ -1882,7 +1876,7 @@ static int at91_gpio_probe(struct platform_device *pdev)
+ names = devm_kasprintf_strarray(dev, "pio", chip->ngpio);
+ if (!names) {
+ ret = -ENOMEM;
+- goto clk_enable_err;
++ goto err;
+ }
+
+ for (i = 0; i < chip->ngpio; i++)
+@@ -1915,8 +1909,6 @@ static int at91_gpio_probe(struct platform_device *pdev)
+ return 0;
+
+ gpiochip_add_err:
+-clk_enable_err:
+- clk_disable_unprepare(at91_chip->clock);
+ err:
+ dev_err(&pdev->dev, "Failure %i for GPIO %i\n", ret, alias_idx);
+
+--
+2.39.2
+
--- /dev/null
+From a1f4e84a4634e628c1ae61cf2288345464454f7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 May 2023 10:44:54 +0300
+Subject: pinctrl: at91: fix a couple NULL vs IS_ERR() checks
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 35216718c9ac2aef934ea9cd229572d4996807b2 ]
+
+The devm_kasprintf_strarray() function doesn't return NULL on error,
+it returns error pointers. Update the checks accordingly.
+
+Fixes: f494c1913cbb ("pinctrl: at91: use devm_kasprintf() to avoid potential leaks (part 2)")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Ryan Wanner <ryan.wanner@microchip.com>
+Link: https://lore.kernel.org/r/5697980e-f687-47a7-9db8-2af34ae464bd@kili.mountain
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-at91.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
+index e3664aafccef9..9184d457edf8d 100644
+--- a/drivers/pinctrl/pinctrl-at91.c
++++ b/drivers/pinctrl/pinctrl-at91.c
+@@ -1399,8 +1399,8 @@ static int at91_pinctrl_probe(struct platform_device *pdev)
+ char **names;
+
+ names = devm_kasprintf_strarray(dev, "pio", MAX_NB_GPIO_PER_BANK);
+- if (!names)
+- return -ENOMEM;
++ if (IS_ERR(names))
++ return PTR_ERR(names);
+
+ for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) {
+ char *name = names[j];
+@@ -1860,8 +1860,8 @@ static int at91_gpio_probe(struct platform_device *pdev)
+ }
+
+ names = devm_kasprintf_strarray(dev, "pio", chip->ngpio);
+- if (!names)
+- return -ENOMEM;
++ if (IS_ERR(names))
++ return PTR_ERR(names);
+
+ for (i = 0; i < chip->ngpio; i++)
+ strreplace(names[i], '-', alias_idx + 'A');
+--
+2.39.2
+
--- /dev/null
+From 492521f30f0e1b774e2118125e4cdfd6fd31a853 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 13:53:33 +0300
+Subject: pinctrl: at91-pio4: check return value of devm_kasprintf()
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit f6fd5d4ff8ca0b24cee1af4130bcb1fa96b61aa0 ]
+
+devm_kasprintf() returns a pointer to dynamically allocated memory.
+Pointer could be NULL in case allocation fails. Check pointer validity.
+Identified with coccinelle (kmerr.cocci script).
+
+Fixes: 776180848b57 ("pinctrl: introduce driver for Atmel PIO4 controller")
+Depends-on: 1c4e5c470a56 ("pinctrl: at91: use devm_kasprintf() to avoid potential leaks")
+Depends-on: 5a8f9cf269e8 ("pinctrl: at91-pio4: use proper format specifier for unsigned int")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20230615105333.585304-4-claudiu.beznea@microchip.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-at91-pio4.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
+index c775d239444a6..20433c1745805 100644
+--- a/drivers/pinctrl/pinctrl-at91-pio4.c
++++ b/drivers/pinctrl/pinctrl-at91-pio4.c
+@@ -1151,6 +1151,8 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
+ /* Pin naming convention: P(bank_name)(bank_pin_number). */
+ pin_desc[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "P%c%d",
+ bank + 'A', line);
++ if (!pin_desc[i].name)
++ return -ENOMEM;
+
+ group->name = group_names[i] = pin_desc[i].name;
+ group->pin = pin_desc[i].number;
+--
+2.39.2
+
--- /dev/null
+From 8a5850a0f14a08483a2bb84b83c929123e232248 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 15:42:41 +0200
+Subject: pinctrl: at91: Use dev_err_probe() instead of custom messaging
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 472bbb2cfd6384fe4c4b956af2170c1225fe2a92 ]
+
+The custom message has no value except printing the error code,
+the same does dev_err_probe(). Let's use the latter for the sake
+of unification.
+
+Note that some APIs already have messaging in them and some simply
+do not require the current noise.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Tested-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230215134242.37618-5-andriy.shevchenko@linux.intel.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: 35216718c9ac ("pinctrl: at91: fix a couple NULL vs IS_ERR() checks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-at91.c | 64 +++++++++++-----------------------
+ 1 file changed, 21 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
+index f0b139a1cc3ed..e3664aafccef9 100644
+--- a/drivers/pinctrl/pinctrl-at91.c
++++ b/drivers/pinctrl/pinctrl-at91.c
+@@ -1294,10 +1294,11 @@ static const struct of_device_id at91_pinctrl_of_match[] = {
+ static int at91_pinctrl_probe_dt(struct platform_device *pdev,
+ struct at91_pinctrl *info)
+ {
++ struct device *dev = &pdev->dev;
+ int ret = 0;
+ int i, j, ngpio_chips_enabled = 0;
+ uint32_t *tmp;
+- struct device_node *np = pdev->dev.of_node;
++ struct device_node *np = dev->of_node;
+ struct device_node *child;
+
+ if (!np)
+@@ -1361,9 +1362,8 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev,
+ continue;
+ ret = at91_pinctrl_parse_functions(child, info, i++);
+ if (ret) {
+- dev_err(&pdev->dev, "failed to parse function\n");
+ of_node_put(child);
+- return ret;
++ return dev_err_probe(dev, ret, "failed to parse function\n");
+ }
+ }
+
+@@ -1416,11 +1416,8 @@ static int at91_pinctrl_probe(struct platform_device *pdev)
+ platform_set_drvdata(pdev, info);
+ info->pctl = devm_pinctrl_register(&pdev->dev, &at91_pinctrl_desc,
+ info);
+-
+- if (IS_ERR(info->pctl)) {
+- dev_err(&pdev->dev, "could not register AT91 pinctrl driver\n");
+- return PTR_ERR(info->pctl);
+- }
++ if (IS_ERR(info->pctl))
++ return dev_err_probe(dev, PTR_ERR(info->pctl), "could not register AT91 pinctrl driver\n");
+
+ /* We will handle a range of GPIO pins */
+ for (i = 0; i < gpio_banks; i++)
+@@ -1821,28 +1818,20 @@ static int at91_gpio_probe(struct platform_device *pdev)
+ char **names;
+
+ BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips));
+- if (gpio_chips[alias_idx]) {
+- ret = -EBUSY;
+- goto err;
+- }
++ if (gpio_chips[alias_idx])
++ return dev_err_probe(dev, -EBUSY, "%d slot is occupied.\n", alias_idx);
+
+ irq = platform_get_irq(pdev, 0);
+- if (irq < 0) {
+- ret = irq;
+- goto err;
+- }
++ if (irq < 0)
++ return irq;
+
+ at91_chip = devm_kzalloc(&pdev->dev, sizeof(*at91_chip), GFP_KERNEL);
+- if (!at91_chip) {
+- ret = -ENOMEM;
+- goto err;
+- }
++ if (!at91_chip)
++ return -ENOMEM;
+
+ at91_chip->regbase = devm_platform_ioremap_resource(pdev, 0);
+- if (IS_ERR(at91_chip->regbase)) {
+- ret = PTR_ERR(at91_chip->regbase);
+- goto err;
+- }
++ if (IS_ERR(at91_chip->regbase))
++ return PTR_ERR(at91_chip->regbase);
+
+ at91_chip->ops = (const struct at91_pinctrl_mux_ops *)
+ of_match_device(at91_gpio_of_match, &pdev->dev)->data;
+@@ -1850,11 +1839,8 @@ static int at91_gpio_probe(struct platform_device *pdev)
+ at91_chip->pioc_idx = alias_idx;
+
+ at91_chip->clock = devm_clk_get_enabled(&pdev->dev, NULL);
+- if (IS_ERR(at91_chip->clock)) {
+- dev_err(&pdev->dev, "failed to get clock, ignoring.\n");
+- ret = PTR_ERR(at91_chip->clock);
+- goto err;
+- }
++ if (IS_ERR(at91_chip->clock))
++ return dev_err_probe(dev, PTR_ERR(at91_chip->clock), "failed to get clock, ignoring.\n");
+
+ at91_chip->chip = at91_gpio_template;
+ at91_chip->id = alias_idx;
+@@ -1867,17 +1853,15 @@ static int at91_gpio_probe(struct platform_device *pdev)
+
+ if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) {
+ if (ngpio >= MAX_NB_GPIO_PER_BANK)
+- pr_err("at91_gpio.%d, gpio-nb >= %d failback to %d\n",
+- alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK);
++ dev_err(dev, "at91_gpio.%d, gpio-nb >= %d failback to %d\n",
++ alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK);
+ else
+ chip->ngpio = ngpio;
+ }
+
+ names = devm_kasprintf_strarray(dev, "pio", chip->ngpio);
+- if (!names) {
+- ret = -ENOMEM;
+- goto err;
+- }
++ if (!names)
++ return -ENOMEM;
+
+ for (i = 0; i < chip->ngpio; i++)
+ strreplace(names[i], '-', alias_idx + 'A');
+@@ -1894,11 +1878,11 @@ static int at91_gpio_probe(struct platform_device *pdev)
+
+ ret = at91_gpio_of_irq_setup(pdev, at91_chip);
+ if (ret)
+- goto gpiochip_add_err;
++ return ret;
+
+ ret = gpiochip_add_data(chip, at91_chip);
+ if (ret)
+- goto gpiochip_add_err;
++ return ret;
+
+ gpio_chips[alias_idx] = at91_chip;
+ platform_set_drvdata(pdev, at91_chip);
+@@ -1907,12 +1891,6 @@ static int at91_gpio_probe(struct platform_device *pdev)
+ dev_info(&pdev->dev, "at address %p\n", at91_chip->regbase);
+
+ return 0;
+-
+-gpiochip_add_err:
+-err:
+- dev_err(&pdev->dev, "Failure %i for GPIO %i\n", ret, alias_idx);
+-
+- return ret;
+ }
+
+ static const struct dev_pm_ops at91_gpio_pm_ops = {
+--
+2.39.2
+
--- /dev/null
+From 38e69144849ebb6e5ec046933dc23fa8ad79ac11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Apr 2023 23:43:41 +0200
+Subject: pinctrl: bcm2835: Handle gpiochip_add_pin_range() errors
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit cdf7e616120065007687fe1df0412154f259daec ]
+
+gpiochip_add_pin_range() can fail, so better return its error code than
+a hard coded '0'.
+
+Fixes: d2b67744fd99 ("pinctrl: bcm2835: implement hook for missing gpio-ranges")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/98c3b5890bb72415145c9fe4e1d974711edae376.1681681402.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/bcm/pinctrl-bcm2835.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+index 7435173e10f43..1489191a213fe 100644
+--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+@@ -376,10 +376,8 @@ static int bcm2835_add_pin_ranges_fallback(struct gpio_chip *gc)
+ if (!pctldev)
+ return 0;
+
+- gpiochip_add_pin_range(gc, pinctrl_dev_get_devname(pctldev), 0, 0,
+- gc->ngpio);
+-
+- return 0;
++ return gpiochip_add_pin_range(gc, pinctrl_dev_get_devname(pctldev), 0, 0,
++ gc->ngpio);
+ }
+
+ static const struct gpio_chip bcm2835_gpio_chip = {
+--
+2.39.2
+
--- /dev/null
+From a7409165d0a596c5afdc6b9ef243b4a8d244ce03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 17:37:34 +0300
+Subject: pinctrl: cherryview: Return correct value if pin in push-pull mode
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 5835196a17be5cfdcad0b617f90cf4abe16951a4 ]
+
+Currently the getter returns ENOTSUPP on pin configured in
+the push-pull mode. Fix this by adding the missed switch case.
+
+Fixes: ccdf81d08dbe ("pinctrl: cherryview: add option to set open-drain pin config")
+Fixes: 6e08d6bbebeb ("pinctrl: Add Intel Cherryview/Braswell pin controller support")
+Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/intel/pinctrl-cherryview.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c
+index 722990e278361..87cf1e7403979 100644
+--- a/drivers/pinctrl/intel/pinctrl-cherryview.c
++++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
+@@ -949,11 +949,6 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
+
+ break;
+
+- case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+- if (!(ctrl1 & CHV_PADCTRL1_ODEN))
+- return -EINVAL;
+- break;
+-
+ case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: {
+ u32 cfg;
+
+@@ -963,6 +958,16 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
+ return -EINVAL;
+
+ break;
++
++ case PIN_CONFIG_DRIVE_PUSH_PULL:
++ if (ctrl1 & CHV_PADCTRL1_ODEN)
++ return -EINVAL;
++ break;
++
++ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
++ if (!(ctrl1 & CHV_PADCTRL1_ODEN))
++ return -EINVAL;
++ break;
+ }
+
+ default:
+--
+2.39.2
+
--- /dev/null
+From a83e9e9d7563ccfd0d17fea08aed028c9ce9fe13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 May 2023 07:37:36 +0800
+Subject: pinctrl: freescale: Fix a memory out of bounds when num_configs is 1
+
+From: Xiaolei Wang <xiaolei.wang@windriver.com>
+
+[ Upstream commit 9063777ca1e2e895c5fdd493ee0c3f18fa710ed4 ]
+
+The config passed in by pad wakeup is 1, when num_configs is 1,
+Configuration [1] should not be fetched, which will be detected
+by KASAN as a memory out of bounds condition. Modify to get
+configs[1] when num_configs is 2.
+
+Fixes: f60c9eac54af ("gpio: mxc: enable pad wakeup on i.MX8x platforms")
+Signed-off-by: Xiaolei Wang <xiaolei.wang@windriver.com>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20230504233736.3766296-1-xiaolei.wang@windriver.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/freescale/pinctrl-scu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/freescale/pinctrl-scu.c b/drivers/pinctrl/freescale/pinctrl-scu.c
+index ea261b6e74581..3b252d684d723 100644
+--- a/drivers/pinctrl/freescale/pinctrl-scu.c
++++ b/drivers/pinctrl/freescale/pinctrl-scu.c
+@@ -90,7 +90,7 @@ int imx_pinconf_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id,
+ struct imx_sc_msg_req_pad_set msg;
+ struct imx_sc_rpc_msg *hdr = &msg.hdr;
+ unsigned int mux = configs[0];
+- unsigned int conf = configs[1];
++ unsigned int conf;
+ unsigned int val;
+ int ret;
+
+@@ -115,6 +115,7 @@ int imx_pinconf_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id,
+ * Set mux and conf together in one IPC call
+ */
+ WARN_ON(num_configs != 2);
++ conf = configs[1];
+
+ val = conf | BM_PAD_CTL_IFMUX_ENABLE | BM_PAD_CTL_GP_ENABLE;
+ val |= mux << BP_PAD_CTL_IFMUX;
+--
+2.39.2
+
--- /dev/null
+From 9606e384f3257ff375b559dc7dd52ce9677860f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 13:53:32 +0300
+Subject: pinctrl: microchip-sgpio: check return value of devm_kasprintf()
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit 310cd4c206cd04696ccbfd1927b5ab6973e8cc8e ]
+
+devm_kasprintf() returns a pointer to dynamically allocated memory.
+Pointer could be NULL in case allocation fails. Check pointer validity.
+Identified with coccinelle (kmerr.cocci script).
+
+Fixes: 7e5ea974e61c ("pinctrl: pinctrl-microchip-sgpio: Add pinctrl driver for Microsemi Serial GPIO")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20230615105333.585304-3-claudiu.beznea@microchip.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-microchip-sgpio.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c
+index 4794602316e7d..666d8b7cdbad3 100644
+--- a/drivers/pinctrl/pinctrl-microchip-sgpio.c
++++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c
+@@ -818,6 +818,9 @@ static int microchip_sgpio_register_bank(struct device *dev,
+ pctl_desc->name = devm_kasprintf(dev, GFP_KERNEL, "%s-%sput",
+ dev_name(dev),
+ bank->is_input ? "in" : "out");
++ if (!pctl_desc->name)
++ return -ENOMEM;
++
+ pctl_desc->pctlops = &sgpio_pctl_ops;
+ pctl_desc->pmxops = &sgpio_pmx_ops;
+ pctl_desc->confops = &sgpio_confops;
+--
+2.39.2
+
--- /dev/null
+From eb1bbcbecdca218895f0894f33ee0bc1c6bf40e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jun 2023 17:58:29 +0800
+Subject: pinctrl: npcm7xx: Add missing check for ioremap
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit ad64639417161e90b30dda00486570eb150aeee5 ]
+
+Add check for ioremap() and return the error if it fails in order to
+guarantee the success of ioremap().
+
+Fixes: 3b588e43ee5c ("pinctrl: nuvoton: add NPCM7xx pinctrl and GPIO driver")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20230607095829.1345-1-jiasheng@iscas.ac.cn
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
+index ff5bcea172e84..071bdfd570f94 100644
+--- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
++++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
+@@ -1881,6 +1881,8 @@ static int npcm7xx_gpio_of(struct npcm7xx_pinctrl *pctrl)
+ }
+
+ pctrl->gpio_bank[id].base = ioremap(res.start, resource_size(&res));
++ if (!pctrl->gpio_bank[id].base)
++ return -EINVAL;
+
+ ret = bgpio_init(&pctrl->gpio_bank[id].gc, dev, 4,
+ pctrl->gpio_bank[id].base + NPCM7XX_GP_N_DIN,
+--
+2.39.2
+
--- /dev/null
+From 6512775740a394989f3190b7968f859e56547f3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 May 2023 20:34:37 +0800
+Subject: pinctrl: sunplus: Add check for kmalloc
+
+From: Wells Lu <wellslutw@gmail.com>
+
+[ Upstream commit a5961bed5429cf1134d7f539b4ed60317012f84d ]
+
+Fix Smatch static checker warning:
+potential null dereference 'configs'. (kmalloc returns null)
+
+Fixes: aa74c44be19c ("pinctrl: Add driver for Sunplus SP7021")
+Signed-off-by: Wells Lu <wellslutw@gmail.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/1685277277-12209-1-git-send-email-wellslutw@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/sunplus/sppctl.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pinctrl/sunplus/sppctl.c b/drivers/pinctrl/sunplus/sppctl.c
+index 6bbbab3a6fdf3..e91ce5b5d5598 100644
+--- a/drivers/pinctrl/sunplus/sppctl.c
++++ b/drivers/pinctrl/sunplus/sppctl.c
+@@ -834,11 +834,6 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node
+ int i, size = 0;
+
+ list = of_get_property(np_config, "sunplus,pins", &size);
+-
+- if (nmG <= 0)
+- nmG = 0;
+-
+- parent = of_get_parent(np_config);
+ *num_maps = size / sizeof(*list);
+
+ /*
+@@ -866,10 +861,14 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node
+ }
+ }
+
++ if (nmG <= 0)
++ nmG = 0;
++
+ *map = kcalloc(*num_maps + nmG, sizeof(**map), GFP_KERNEL);
+- if (*map == NULL)
++ if (!(*map))
+ return -ENOMEM;
+
++ parent = of_get_parent(np_config);
+ for (i = 0; i < (*num_maps); i++) {
+ dt_pin = be32_to_cpu(list[i]);
+ pin_num = FIELD_GET(GENMASK(31, 24), dt_pin);
+@@ -883,6 +882,8 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node
+ (*map)[i].data.configs.num_configs = 1;
+ (*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, pin_num);
+ configs = kmalloc(sizeof(*configs), GFP_KERNEL);
++ if (!configs)
++ goto sppctl_map_err;
+ *configs = FIELD_GET(GENMASK(7, 0), dt_pin);
+ (*map)[i].data.configs.configs = configs;
+
+@@ -896,6 +897,8 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node
+ (*map)[i].data.configs.num_configs = 1;
+ (*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, pin_num);
+ configs = kmalloc(sizeof(*configs), GFP_KERNEL);
++ if (!configs)
++ goto sppctl_map_err;
+ *configs = SPPCTL_IOP_CONFIGS;
+ (*map)[i].data.configs.configs = configs;
+
+@@ -965,6 +968,15 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node
+ of_node_put(parent);
+ dev_dbg(pctldev->dev, "%d pins mapped\n", *num_maps);
+ return 0;
++
++sppctl_map_err:
++ for (i = 0; i < (*num_maps); i++)
++ if (((*map)[i].type == PIN_MAP_TYPE_CONFIGS_PIN) &&
++ (*map)[i].data.configs.configs)
++ kfree((*map)[i].data.configs.configs);
++ kfree(*map);
++ of_node_put(parent);
++ return -ENOMEM;
+ }
+
+ static const struct pinctrl_ops sppctl_pctl_ops = {
+--
+2.39.2
+
--- /dev/null
+From 41116bd723e42e3cd01425c110b5309c3e5f0d6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 May 2023 20:34:37 +0800
+Subject: pinctrl:sunplus: Add check for kmalloc
+
+From: Wells Lu <wellslutw@gmail.com>
+
+[ Upstream commit 73f8ce7f961afcb3be49352efeb7c26cc1c00cc4 ]
+
+Fix Smatch static checker warning:
+potential null dereference 'configs'. (kmalloc returns null)
+
+Changes in v2:
+1. Add free allocated memory before returned -ENOMEM.
+2. Add call of_node_put() before returned -ENOMEM.
+
+Fixes: aa74c44be19c ("pinctrl: Add driver for Sunplus SP7021")
+Signed-off-by: Wells Lu <wellslutw@gmail.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/1685277277-12209-1-git-send-email-wellslutw@gmail.com
+[Rebased on the patch from Lu Hongfei]
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/sunplus/sppctl.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/pinctrl/sunplus/sppctl.c b/drivers/pinctrl/sunplus/sppctl.c
+index e91ce5b5d5598..150996949ede7 100644
+--- a/drivers/pinctrl/sunplus/sppctl.c
++++ b/drivers/pinctrl/sunplus/sppctl.c
+@@ -971,8 +971,7 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node
+
+ sppctl_map_err:
+ for (i = 0; i < (*num_maps); i++)
+- if (((*map)[i].type == PIN_MAP_TYPE_CONFIGS_PIN) &&
+- (*map)[i].data.configs.configs)
++ if ((*map)[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
+ kfree((*map)[i].data.configs.configs);
+ kfree(*map);
+ of_node_put(parent);
+--
+2.39.2
+
--- /dev/null
+From a8190c92a3ce53c2a2c3411fbffaa1666120a7f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 12:53:07 +0200
+Subject: pinctrl: tegra: Duplicate pinmux functions table
+
+From: Thierry Reding <treding@nvidia.com>
+
+[ Upstream commit fad57233501beb5bd25f037cb9128a533e710600 ]
+
+The function table is filled with group information based on other
+instance-specific data at runtime. However, the function table can be
+shared between multiple instances, causing the ->probe() function for
+one instance to overwrite the table of a previously probed instance.
+
+Fix this by sharing only the function names and allocating a separate
+function table for each instance.
+
+Fixes: 5a0047360743 ("pinctrl: tegra: Separate Tegra194 instances")
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://lore.kernel.org/r/20230530105308.1292852-1-thierry.reding@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/tegra/pinctrl-tegra.c | 15 +++++++++++----
+ drivers/pinctrl/tegra/pinctrl-tegra.h | 3 ++-
+ drivers/pinctrl/tegra/pinctrl-tegra114.c | 7 ++-----
+ drivers/pinctrl/tegra/pinctrl-tegra124.c | 7 ++-----
+ drivers/pinctrl/tegra/pinctrl-tegra194.c | 7 ++-----
+ drivers/pinctrl/tegra/pinctrl-tegra20.c | 7 ++-----
+ drivers/pinctrl/tegra/pinctrl-tegra210.c | 7 ++-----
+ drivers/pinctrl/tegra/pinctrl-tegra30.c | 7 ++-----
+ 8 files changed, 25 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c
+index 1729b7ddfa946..21e08fbd1df0e 100644
+--- a/drivers/pinctrl/tegra/pinctrl-tegra.c
++++ b/drivers/pinctrl/tegra/pinctrl-tegra.c
+@@ -232,7 +232,7 @@ static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+ {
+ struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+- return pmx->soc->functions[function].name;
++ return pmx->functions[function].name;
+ }
+
+ static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+@@ -242,8 +242,8 @@ static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+ {
+ struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+- *groups = pmx->soc->functions[function].groups;
+- *num_groups = pmx->soc->functions[function].ngroups;
++ *groups = pmx->functions[function].groups;
++ *num_groups = pmx->functions[function].ngroups;
+
+ return 0;
+ }
+@@ -795,10 +795,17 @@ int tegra_pinctrl_probe(struct platform_device *pdev,
+ if (!pmx->group_pins)
+ return -ENOMEM;
+
++ pmx->functions = devm_kcalloc(&pdev->dev, pmx->soc->nfunctions,
++ sizeof(*pmx->functions), GFP_KERNEL);
++ if (!pmx->functions)
++ return -ENOMEM;
++
+ group_pins = pmx->group_pins;
++
+ for (fn = 0; fn < soc_data->nfunctions; fn++) {
+- struct tegra_function *func = &soc_data->functions[fn];
++ struct tegra_function *func = &pmx->functions[fn];
+
++ func->name = pmx->soc->functions[fn];
+ func->groups = group_pins;
+
+ for (gn = 0; gn < soc_data->ngroups; gn++) {
+diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.h b/drivers/pinctrl/tegra/pinctrl-tegra.h
+index 6130cba7cce54..b3289bdf727d8 100644
+--- a/drivers/pinctrl/tegra/pinctrl-tegra.h
++++ b/drivers/pinctrl/tegra/pinctrl-tegra.h
+@@ -13,6 +13,7 @@ struct tegra_pmx {
+ struct pinctrl_dev *pctl;
+
+ const struct tegra_pinctrl_soc_data *soc;
++ struct tegra_function *functions;
+ const char **group_pins;
+
+ struct pinctrl_gpio_range gpio_range;
+@@ -191,7 +192,7 @@ struct tegra_pinctrl_soc_data {
+ const char *gpio_compatible;
+ const struct pinctrl_pin_desc *pins;
+ unsigned npins;
+- struct tegra_function *functions;
++ const char * const *functions;
+ unsigned nfunctions;
+ const struct tegra_pingroup *groups;
+ unsigned ngroups;
+diff --git a/drivers/pinctrl/tegra/pinctrl-tegra114.c b/drivers/pinctrl/tegra/pinctrl-tegra114.c
+index e72ab1eb23983..3d425b2018e78 100644
+--- a/drivers/pinctrl/tegra/pinctrl-tegra114.c
++++ b/drivers/pinctrl/tegra/pinctrl-tegra114.c
+@@ -1452,12 +1452,9 @@ enum tegra_mux {
+ TEGRA_MUX_VI_ALT3,
+ };
+
+-#define FUNCTION(fname) \
+- { \
+- .name = #fname, \
+- }
++#define FUNCTION(fname) #fname
+
+-static struct tegra_function tegra114_functions[] = {
++static const char * const tegra114_functions[] = {
+ FUNCTION(blink),
+ FUNCTION(cec),
+ FUNCTION(cldvfs),
+diff --git a/drivers/pinctrl/tegra/pinctrl-tegra124.c b/drivers/pinctrl/tegra/pinctrl-tegra124.c
+index 26096c6b967e2..2a50c5c7516c3 100644
+--- a/drivers/pinctrl/tegra/pinctrl-tegra124.c
++++ b/drivers/pinctrl/tegra/pinctrl-tegra124.c
+@@ -1611,12 +1611,9 @@ enum tegra_mux {
+ TEGRA_MUX_VIMCLK2_ALT,
+ };
+
+-#define FUNCTION(fname) \
+- { \
+- .name = #fname, \
+- }
++#define FUNCTION(fname) #fname
+
+-static struct tegra_function tegra124_functions[] = {
++static const char * const tegra124_functions[] = {
+ FUNCTION(blink),
+ FUNCTION(ccla),
+ FUNCTION(cec),
+diff --git a/drivers/pinctrl/tegra/pinctrl-tegra194.c b/drivers/pinctrl/tegra/pinctrl-tegra194.c
+index 277973c884344..69f58df628977 100644
+--- a/drivers/pinctrl/tegra/pinctrl-tegra194.c
++++ b/drivers/pinctrl/tegra/pinctrl-tegra194.c
+@@ -1189,12 +1189,9 @@ enum tegra_mux_dt {
+ };
+
+ /* Make list of each function name */
+-#define TEGRA_PIN_FUNCTION(lid) \
+- { \
+- .name = #lid, \
+- }
++#define TEGRA_PIN_FUNCTION(lid) #lid
+
+-static struct tegra_function tegra194_functions[] = {
++static const char * const tegra194_functions[] = {
+ TEGRA_PIN_FUNCTION(rsvd0),
+ TEGRA_PIN_FUNCTION(rsvd1),
+ TEGRA_PIN_FUNCTION(rsvd2),
+diff --git a/drivers/pinctrl/tegra/pinctrl-tegra20.c b/drivers/pinctrl/tegra/pinctrl-tegra20.c
+index 0dc2cf0d05b1e..737fc2000f66b 100644
+--- a/drivers/pinctrl/tegra/pinctrl-tegra20.c
++++ b/drivers/pinctrl/tegra/pinctrl-tegra20.c
+@@ -1889,12 +1889,9 @@ enum tegra_mux {
+ TEGRA_MUX_XIO,
+ };
+
+-#define FUNCTION(fname) \
+- { \
+- .name = #fname, \
+- }
++#define FUNCTION(fname) #fname
+
+-static struct tegra_function tegra20_functions[] = {
++static const char * const tegra20_functions[] = {
+ FUNCTION(ahb_clk),
+ FUNCTION(apb_clk),
+ FUNCTION(audio_sync),
+diff --git a/drivers/pinctrl/tegra/pinctrl-tegra210.c b/drivers/pinctrl/tegra/pinctrl-tegra210.c
+index b480f607fa16f..9bb29146dfff7 100644
+--- a/drivers/pinctrl/tegra/pinctrl-tegra210.c
++++ b/drivers/pinctrl/tegra/pinctrl-tegra210.c
+@@ -1185,12 +1185,9 @@ enum tegra_mux {
+ TEGRA_MUX_VIMCLK2,
+ };
+
+-#define FUNCTION(fname) \
+- { \
+- .name = #fname, \
+- }
++#define FUNCTION(fname) #fname
+
+-static struct tegra_function tegra210_functions[] = {
++static const char * const tegra210_functions[] = {
+ FUNCTION(aud),
+ FUNCTION(bcl),
+ FUNCTION(blink),
+diff --git a/drivers/pinctrl/tegra/pinctrl-tegra30.c b/drivers/pinctrl/tegra/pinctrl-tegra30.c
+index 7299a371827f1..de5aa2d4d28d3 100644
+--- a/drivers/pinctrl/tegra/pinctrl-tegra30.c
++++ b/drivers/pinctrl/tegra/pinctrl-tegra30.c
+@@ -2010,12 +2010,9 @@ enum tegra_mux {
+ TEGRA_MUX_VI_ALT3,
+ };
+
+-#define FUNCTION(fname) \
+- { \
+- .name = #fname, \
+- }
++#define FUNCTION(fname) #fname
+
+-static struct tegra_function tegra30_functions[] = {
++static const char * const tegra30_functions[] = {
+ FUNCTION(blink),
+ FUNCTION(cec),
+ FUNCTION(clk_12m_out),
+--
+2.39.2
+
--- /dev/null
+From 7066eba089ecf89d06330ad0c875d939c9201cd8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 11:43:10 +0300
+Subject: platform/x86/dell/dell-rbtn: Fix resources leaking on error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michal Wilczynski <michal.wilczynski@intel.com>
+
+[ Upstream commit 966cca72ab20289083521a385fa56035d85a222d ]
+
+Currently rbtn_add() in case of failure is leaking resources. Fix this
+by adding a proper rollback. Move devm_kzalloc() before rbtn_acquire(),
+so it doesn't require rollback in case of failure. While at it, remove
+unnecessary assignment of NULL to device->driver_data and unnecessary
+whitespace, plus add a break for the default case in a switch.
+
+Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Suggested-by: Pali Rohár <pali@kernel.org>
+Fixes: 817a5cdb40c8 ("dell-rbtn: Dell Airplane Mode Switch driver")
+Signed-off-by: Michal Wilczynski <michal.wilczynski@intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Rafael J. Wysocki <rafael@kernel.org>
+Reviewed-by: Pali Rohár <pali@kernel.org>
+Link: https://lore.kernel.org/r/20230613084310.2775896-1-michal.wilczynski@intel.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/dell/dell-rbtn.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/platform/x86/dell/dell-rbtn.c b/drivers/platform/x86/dell/dell-rbtn.c
+index aa0e6c9074942..c8fcb537fd65d 100644
+--- a/drivers/platform/x86/dell/dell-rbtn.c
++++ b/drivers/platform/x86/dell/dell-rbtn.c
+@@ -395,16 +395,16 @@ static int rbtn_add(struct acpi_device *device)
+ return -EINVAL;
+ }
+
++ rbtn_data = devm_kzalloc(&device->dev, sizeof(*rbtn_data), GFP_KERNEL);
++ if (!rbtn_data)
++ return -ENOMEM;
++
+ ret = rbtn_acquire(device, true);
+ if (ret < 0) {
+ dev_err(&device->dev, "Cannot enable device\n");
+ return ret;
+ }
+
+- rbtn_data = devm_kzalloc(&device->dev, sizeof(*rbtn_data), GFP_KERNEL);
+- if (!rbtn_data)
+- return -ENOMEM;
+-
+ rbtn_data->type = type;
+ device->driver_data = rbtn_data;
+
+@@ -420,10 +420,12 @@ static int rbtn_add(struct acpi_device *device)
+ break;
+ default:
+ ret = -EINVAL;
++ break;
+ }
++ if (ret)
++ rbtn_acquire(device, false);
+
+ return ret;
+-
+ }
+
+ static void rbtn_remove(struct acpi_device *device)
+@@ -442,7 +444,6 @@ static void rbtn_remove(struct acpi_device *device)
+ }
+
+ rbtn_acquire(device, false);
+- device->driver_data = NULL;
+ }
+
+ static void rbtn_notify(struct acpi_device *device, u32 event)
+--
+2.39.2
+
--- /dev/null
+From 881881f4559abd68e63bfef474c272dff576adaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 May 2023 17:47:06 -0700
+Subject: platform/x86:intel/pmc: Remove Meteor Lake S platform support
+
+From: Xi Pardee <xi.pardee@intel.com>
+
+[ Upstream commit 416a87c972b978d71ab828442d1d48e3bd194855 ]
+
+commit c5ad454a12c6 ("platform/x86: intel/pmc/core: Add Meteor Lake
+support to pmc core driver") was supposed to add support for Meter
+Lake P/M and mistakenly added support for Meteor Lake S instead. Meteor
+Lake P/M support was added later and MTL-S support needs to be removed
+since its currently assigned to the wrong register maps.
+
+Fixes: c5ad454a12c6 ("platform/x86: intel/pmc/core: Add Meteor Lake support to pmc core driver")
+Signed-off-by: Xi Pardee <xi.pardee@intel.com>
+Signed-off-by: David E. Box <david.e.box@linux.intel.com>
+Link: https://lore.kernel.org/r/20230601004706.871528-1-xi.pardee@intel.com
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel/pmc/core.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
+index b9591969e0fa1..bed083525fbe7 100644
+--- a/drivers/platform/x86/intel/pmc/core.c
++++ b/drivers/platform/x86/intel/pmc/core.c
+@@ -1039,7 +1039,6 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
+ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, tgl_core_init),
+ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, adl_core_init),
+ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, adl_core_init),
+- X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE, mtl_core_init),
+ X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, mtl_core_init),
+ {}
+ };
+--
+2.39.2
+
--- /dev/null
+From 24ca71d37c5b047c41f8dc43eafea0d03e94a5c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 15:53:40 -0700
+Subject: platform/x86:intel/pmc: Update maps for Meteor Lake P/M platforms
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xi Pardee <xi.pardee@intel.com>
+
+[ Upstream commit 9682cfd1973d01e43c2764c662e6d3291ddf770d ]
+
+Fix the IP name errors in the register maps used by the following
+debugfs attributes in the Meteor Lake SOC-M PMC.
+
+pfear_sts
+lpm_sts
+ltr_show
+
+Fixes: c5ad454a12c6 ("platform/x86: intel/pmc/core: Add Meteor Lake support to pmc core driver")
+Signed-off-by: Xi Pardee <xi.pardee@intel.com>
+Signed-off-by: Rajvi Jingar <rajvi.jingar@linux.intel.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://lore.kernel.org/r/20230613225347.2720665-2-rajvi.jingar@linux.intel.com
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel/pmc/core.h | 28 +-
+ drivers/platform/x86/intel/pmc/mtl.c | 448 +++++++++++++++++++++++++-
+ 2 files changed, 466 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
+index 810204d758ab3..d1c29fcd07ae9 100644
+--- a/drivers/platform/x86/intel/pmc/core.h
++++ b/drivers/platform/x86/intel/pmc/core.h
+@@ -247,6 +247,14 @@ enum ppfear_regs {
+ #define MTL_LPM_STATUS_LATCH_EN_OFFSET 0x16F8
+ #define MTL_LPM_STATUS_OFFSET 0x1700
+ #define MTL_LPM_LIVE_STATUS_OFFSET 0x175C
++#define MTL_PMC_LTR_IOE_PMC 0x1C0C
++#define MTL_PMC_LTR_ESE 0x1BAC
++#define MTL_SOCM_NUM_IP_IGN_ALLOWED 25
++#define MTL_SOC_PMC_MMIO_REG_LEN 0x2708
++#define MTL_PMC_LTR_SPG 0x1B74
++
++/* Meteor Lake PGD PFET Enable Ack Status */
++#define MTL_SOCM_PPFEAR_NUM_ENTRIES 8
+
+ extern const char *pmc_lpm_modes[];
+
+@@ -393,7 +401,25 @@ extern const struct pmc_bit_map adl_vnn_req_status_3_map[];
+ extern const struct pmc_bit_map adl_vnn_misc_status_map[];
+ extern const struct pmc_bit_map *adl_lpm_maps[];
+ extern const struct pmc_reg_map adl_reg_map;
+-extern const struct pmc_reg_map mtl_reg_map;
++extern const struct pmc_bit_map mtl_socm_pfear_map[];
++extern const struct pmc_bit_map *ext_mtl_socm_pfear_map[];
++extern const struct pmc_bit_map mtl_socm_ltr_show_map[];
++extern const struct pmc_bit_map mtl_socm_clocksource_status_map[];
++extern const struct pmc_bit_map mtl_socm_power_gating_status_0_map[];
++extern const struct pmc_bit_map mtl_socm_power_gating_status_1_map[];
++extern const struct pmc_bit_map mtl_socm_power_gating_status_2_map[];
++extern const struct pmc_bit_map mtl_socm_d3_status_0_map[];
++extern const struct pmc_bit_map mtl_socm_d3_status_1_map[];
++extern const struct pmc_bit_map mtl_socm_d3_status_2_map[];
++extern const struct pmc_bit_map mtl_socm_d3_status_3_map[];
++extern const struct pmc_bit_map mtl_socm_vnn_req_status_0_map[];
++extern const struct pmc_bit_map mtl_socm_vnn_req_status_1_map[];
++extern const struct pmc_bit_map mtl_socm_vnn_req_status_2_map[];
++extern const struct pmc_bit_map mtl_socm_vnn_req_status_3_map[];
++extern const struct pmc_bit_map mtl_socm_vnn_misc_status_map[];
++extern const struct pmc_bit_map mtl_socm_signal_status_map[];
++extern const struct pmc_bit_map *mtl_socm_lpm_maps[];
++extern const struct pmc_reg_map mtl_socm_reg_map;
+
+ extern void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev);
+ extern int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value);
+diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
+index eeb3bd8c2502d..de9348e031003 100644
+--- a/drivers/platform/x86/intel/pmc/mtl.c
++++ b/drivers/platform/x86/intel/pmc/mtl.c
+@@ -10,28 +10,458 @@
+
+ #include "core.h"
+
+-const struct pmc_reg_map mtl_reg_map = {
+- .pfear_sts = ext_tgl_pfear_map,
++/*
++ * Die Mapping to Product.
++ * Product SOCDie IOEDie PCHDie
++ * MTL-M SOC-M IOE-M None
++ * MTL-P SOC-M IOE-P None
++ * MTL-S SOC-S IOE-P PCH-S
++ */
++
++const struct pmc_bit_map mtl_socm_pfear_map[] = {
++ {"PMC", BIT(0)},
++ {"OPI", BIT(1)},
++ {"SPI", BIT(2)},
++ {"XHCI", BIT(3)},
++ {"SPA", BIT(4)},
++ {"SPB", BIT(5)},
++ {"SPC", BIT(6)},
++ {"GBE", BIT(7)},
++
++ {"SATA", BIT(0)},
++ {"DSP0", BIT(1)},
++ {"DSP1", BIT(2)},
++ {"DSP2", BIT(3)},
++ {"DSP3", BIT(4)},
++ {"SPD", BIT(5)},
++ {"LPSS", BIT(6)},
++ {"LPC", BIT(7)},
++
++ {"SMB", BIT(0)},
++ {"ISH", BIT(1)},
++ {"P2SB", BIT(2)},
++ {"NPK_VNN", BIT(3)},
++ {"SDX", BIT(4)},
++ {"SPE", BIT(5)},
++ {"FUSE", BIT(6)},
++ {"SBR8", BIT(7)},
++
++ {"RSVD24", BIT(0)},
++ {"OTG", BIT(1)},
++ {"EXI", BIT(2)},
++ {"CSE", BIT(3)},
++ {"CSME_KVM", BIT(4)},
++ {"CSME_PMT", BIT(5)},
++ {"CSME_CLINK", BIT(6)},
++ {"CSME_PTIO", BIT(7)},
++
++ {"CSME_USBR", BIT(0)},
++ {"CSME_SUSRAM", BIT(1)},
++ {"CSME_SMT1", BIT(2)},
++ {"RSVD35", BIT(3)},
++ {"CSME_SMS2", BIT(4)},
++ {"CSME_SMS", BIT(5)},
++ {"CSME_RTC", BIT(6)},
++ {"CSME_PSF", BIT(7)},
++
++ {"SBR0", BIT(0)},
++ {"SBR1", BIT(1)},
++ {"SBR2", BIT(2)},
++ {"SBR3", BIT(3)},
++ {"SBR4", BIT(4)},
++ {"SBR5", BIT(5)},
++ {"RSVD46", BIT(6)},
++ {"PSF1", BIT(7)},
++
++ {"PSF2", BIT(0)},
++ {"PSF3", BIT(1)},
++ {"PSF4", BIT(2)},
++ {"CNVI", BIT(3)},
++ {"UFSX2", BIT(4)},
++ {"EMMC", BIT(5)},
++ {"SPF", BIT(6)},
++ {"SBR6", BIT(7)},
++
++ {"SBR7", BIT(0)},
++ {"NPK_AON", BIT(1)},
++ {"HDA4", BIT(2)},
++ {"HDA5", BIT(3)},
++ {"HDA6", BIT(4)},
++ {"PSF6", BIT(5)},
++ {"RSVD62", BIT(6)},
++ {"RSVD63", BIT(7)},
++ {}
++};
++
++const struct pmc_bit_map *ext_mtl_socm_pfear_map[] = {
++ mtl_socm_pfear_map,
++ NULL
++};
++
++const struct pmc_bit_map mtl_socm_ltr_show_map[] = {
++ {"SOUTHPORT_A", CNP_PMC_LTR_SPA},
++ {"SOUTHPORT_B", CNP_PMC_LTR_SPB},
++ {"SATA", CNP_PMC_LTR_SATA},
++ {"GIGABIT_ETHERNET", CNP_PMC_LTR_GBE},
++ {"XHCI", CNP_PMC_LTR_XHCI},
++ {"SOUTHPORT_F", ADL_PMC_LTR_SPF},
++ {"ME", CNP_PMC_LTR_ME},
++ {"SATA1", CNP_PMC_LTR_EVA},
++ {"SOUTHPORT_C", CNP_PMC_LTR_SPC},
++ {"HD_AUDIO", CNP_PMC_LTR_AZ},
++ {"CNV", CNP_PMC_LTR_CNV},
++ {"LPSS", CNP_PMC_LTR_LPSS},
++ {"SOUTHPORT_D", CNP_PMC_LTR_SPD},
++ {"SOUTHPORT_E", CNP_PMC_LTR_SPE},
++ {"SATA2", CNP_PMC_LTR_CAM},
++ {"ESPI", CNP_PMC_LTR_ESPI},
++ {"SCC", CNP_PMC_LTR_SCC},
++ {"ISH", CNP_PMC_LTR_ISH},
++ {"UFSX2", CNP_PMC_LTR_UFSX2},
++ {"EMMC", CNP_PMC_LTR_EMMC},
++ {"WIGIG", ICL_PMC_LTR_WIGIG},
++ {"THC0", TGL_PMC_LTR_THC0},
++ {"THC1", TGL_PMC_LTR_THC1},
++ {"SOUTHPORT_G", MTL_PMC_LTR_SPG},
++ {"ESE", MTL_PMC_LTR_ESE},
++ {"IOE_PMC", MTL_PMC_LTR_IOE_PMC},
++
++ /* Below two cannot be used for LTR_IGNORE */
++ {"CURRENT_PLATFORM", CNP_PMC_LTR_CUR_PLT},
++ {"AGGREGATED_SYSTEM", CNP_PMC_LTR_CUR_ASLT},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_clocksource_status_map[] = {
++ {"AON2_OFF_STS", BIT(0)},
++ {"AON3_OFF_STS", BIT(1)},
++ {"AON4_OFF_STS", BIT(2)},
++ {"AON5_OFF_STS", BIT(3)},
++ {"AON1_OFF_STS", BIT(4)},
++ {"XTAL_LVM_OFF_STS", BIT(5)},
++ {"MPFPW1_0_PLL_OFF_STS", BIT(6)},
++ {"MPFPW1_1_PLL_OFF_STS", BIT(7)},
++ {"USB3_PLL_OFF_STS", BIT(8)},
++ {"AON3_SPL_OFF_STS", BIT(9)},
++ {"MPFPW2_0_PLL_OFF_STS", BIT(12)},
++ {"MPFPW3_0_PLL_OFF_STS", BIT(13)},
++ {"XTAL_AGGR_OFF_STS", BIT(17)},
++ {"USB2_PLL_OFF_STS", BIT(18)},
++ {"FILTER_PLL_OFF_STS", BIT(22)},
++ {"ACE_PLL_OFF_STS", BIT(24)},
++ {"FABRIC_PLL_OFF_STS", BIT(25)},
++ {"SOC_PLL_OFF_STS", BIT(26)},
++ {"PCIFAB_PLL_OFF_STS", BIT(27)},
++ {"REF_PLL_OFF_STS", BIT(28)},
++ {"IMG_PLL_OFF_STS", BIT(29)},
++ {"RTC_PLL_OFF_STS", BIT(31)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_power_gating_status_0_map[] = {
++ {"PMC_PGD0_PG_STS", BIT(0)},
++ {"DMI_PGD0_PG_STS", BIT(1)},
++ {"ESPISPI_PGD0_PG_STS", BIT(2)},
++ {"XHCI_PGD0_PG_STS", BIT(3)},
++ {"SPA_PGD0_PG_STS", BIT(4)},
++ {"SPB_PGD0_PG_STS", BIT(5)},
++ {"SPC_PGD0_PG_STS", BIT(6)},
++ {"GBE_PGD0_PG_STS", BIT(7)},
++ {"SATA_PGD0_PG_STS", BIT(8)},
++ {"PSF13_PGD0_PG_STS", BIT(9)},
++ {"SOC_D2D_PGD3_PG_STS", BIT(10)},
++ {"MPFPW3_PGD0_PG_STS", BIT(11)},
++ {"ESE_PGD0_PG_STS", BIT(12)},
++ {"SPD_PGD0_PG_STS", BIT(13)},
++ {"LPSS_PGD0_PG_STS", BIT(14)},
++ {"LPC_PGD0_PG_STS", BIT(15)},
++ {"SMB_PGD0_PG_STS", BIT(16)},
++ {"ISH_PGD0_PG_STS", BIT(17)},
++ {"P2S_PGD0_PG_STS", BIT(18)},
++ {"NPK_PGD0_PG_STS", BIT(19)},
++ {"DBG_SBR_PGD0_PG_STS", BIT(20)},
++ {"SBRG_PGD0_PG_STS", BIT(21)},
++ {"FUSE_PGD0_PG_STS", BIT(22)},
++ {"SBR8_PGD0_PG_STS", BIT(23)},
++ {"SOC_D2D_PGD2_PG_STS", BIT(24)},
++ {"XDCI_PGD0_PG_STS", BIT(25)},
++ {"EXI_PGD0_PG_STS", BIT(26)},
++ {"CSE_PGD0_PG_STS", BIT(27)},
++ {"KVMCC_PGD0_PG_STS", BIT(28)},
++ {"PMT_PGD0_PG_STS", BIT(29)},
++ {"CLINK_PGD0_PG_STS", BIT(30)},
++ {"PTIO_PGD0_PG_STS", BIT(31)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_power_gating_status_1_map[] = {
++ {"USBR0_PGD0_PG_STS", BIT(0)},
++ {"SUSRAM_PGD0_PG_STS", BIT(1)},
++ {"SMT1_PGD0_PG_STS", BIT(2)},
++ {"FIACPCB_U_PGD0_PG_STS", BIT(3)},
++ {"SMS2_PGD0_PG_STS", BIT(4)},
++ {"SMS1_PGD0_PG_STS", BIT(5)},
++ {"CSMERTC_PGD0_PG_STS", BIT(6)},
++ {"CSMEPSF_PGD0_PG_STS", BIT(7)},
++ {"SBR0_PGD0_PG_STS", BIT(8)},
++ {"SBR1_PGD0_PG_STS", BIT(9)},
++ {"SBR2_PGD0_PG_STS", BIT(10)},
++ {"SBR3_PGD0_PG_STS", BIT(11)},
++ {"U3FPW1_PGD0_PG_STS", BIT(12)},
++ {"SBR5_PGD0_PG_STS", BIT(13)},
++ {"MPFPW1_PGD0_PG_STS", BIT(14)},
++ {"UFSPW1_PGD0_PG_STS", BIT(15)},
++ {"FIA_X_PGD0_PG_STS", BIT(16)},
++ {"SOC_D2D_PGD0_PG_STS", BIT(17)},
++ {"MPFPW2_PGD0_PG_STS", BIT(18)},
++ {"CNVI_PGD0_PG_STS", BIT(19)},
++ {"UFSX2_PGD0_PG_STS", BIT(20)},
++ {"ENDBG_PGD0_PG_STS", BIT(21)},
++ {"DBG_PSF_PGD0_PG_STS", BIT(22)},
++ {"SBR6_PGD0_PG_STS", BIT(23)},
++ {"SBR7_PGD0_PG_STS", BIT(24)},
++ {"NPK_PGD1_PG_STS", BIT(25)},
++ {"FIACPCB_X_PGD0_PG_STS", BIT(26)},
++ {"DBC_PGD0_PG_STS", BIT(27)},
++ {"FUSEGPSB_PGD0_PG_STS", BIT(28)},
++ {"PSF6_PGD0_PG_STS", BIT(29)},
++ {"PSF7_PGD0_PG_STS", BIT(30)},
++ {"GBETSN1_PGD0_PG_STS", BIT(31)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_power_gating_status_2_map[] = {
++ {"PSF8_PGD0_PG_STS", BIT(0)},
++ {"FIA_PGD0_PG_STS", BIT(1)},
++ {"SOC_D2D_PGD1_PG_STS", BIT(2)},
++ {"FIA_U_PGD0_PG_STS", BIT(3)},
++ {"TAM_PGD0_PG_STS", BIT(4)},
++ {"GBETSN_PGD0_PG_STS", BIT(5)},
++ {"TBTLSX_PGD0_PG_STS", BIT(6)},
++ {"THC0_PGD0_PG_STS", BIT(7)},
++ {"THC1_PGD0_PG_STS", BIT(8)},
++ {"PMC_PGD1_PG_STS", BIT(9)},
++ {"GNA_PGD0_PG_STS", BIT(10)},
++ {"ACE_PGD0_PG_STS", BIT(11)},
++ {"ACE_PGD1_PG_STS", BIT(12)},
++ {"ACE_PGD2_PG_STS", BIT(13)},
++ {"ACE_PGD3_PG_STS", BIT(14)},
++ {"ACE_PGD4_PG_STS", BIT(15)},
++ {"ACE_PGD5_PG_STS", BIT(16)},
++ {"ACE_PGD6_PG_STS", BIT(17)},
++ {"ACE_PGD7_PG_STS", BIT(18)},
++ {"ACE_PGD8_PG_STS", BIT(19)},
++ {"FIA_PGS_PGD0_PG_STS", BIT(20)},
++ {"FIACPCB_PGS_PGD0_PG_STS", BIT(21)},
++ {"FUSEPMSB_PGD0_PG_STS", BIT(22)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_d3_status_0_map[] = {
++ {"LPSS_D3_STS", BIT(3)},
++ {"XDCI_D3_STS", BIT(4)},
++ {"XHCI_D3_STS", BIT(5)},
++ {"SPA_D3_STS", BIT(12)},
++ {"SPB_D3_STS", BIT(13)},
++ {"SPC_D3_STS", BIT(14)},
++ {"SPD_D3_STS", BIT(15)},
++ {"ESPISPI_D3_STS", BIT(18)},
++ {"SATA_D3_STS", BIT(20)},
++ {"PSTH_D3_STS", BIT(21)},
++ {"DMI_D3_STS", BIT(22)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_d3_status_1_map[] = {
++ {"GBETSN1_D3_STS", BIT(14)},
++ {"GBE_D3_STS", BIT(19)},
++ {"ITSS_D3_STS", BIT(23)},
++ {"P2S_D3_STS", BIT(24)},
++ {"CNVI_D3_STS", BIT(27)},
++ {"UFSX2_D3_STS", BIT(28)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_d3_status_2_map[] = {
++ {"GNA_D3_STS", BIT(0)},
++ {"CSMERTC_D3_STS", BIT(1)},
++ {"SUSRAM_D3_STS", BIT(2)},
++ {"CSE_D3_STS", BIT(4)},
++ {"KVMCC_D3_STS", BIT(5)},
++ {"USBR0_D3_STS", BIT(6)},
++ {"ISH_D3_STS", BIT(7)},
++ {"SMT1_D3_STS", BIT(8)},
++ {"SMT2_D3_STS", BIT(9)},
++ {"SMT3_D3_STS", BIT(10)},
++ {"CLINK_D3_STS", BIT(14)},
++ {"PTIO_D3_STS", BIT(16)},
++ {"PMT_D3_STS", BIT(17)},
++ {"SMS1_D3_STS", BIT(18)},
++ {"SMS2_D3_STS", BIT(19)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_d3_status_3_map[] = {
++ {"ESE_D3_STS", BIT(2)},
++ {"GBETSN_D3_STS", BIT(13)},
++ {"THC0_D3_STS", BIT(14)},
++ {"THC1_D3_STS", BIT(15)},
++ {"ACE_D3_STS", BIT(23)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_vnn_req_status_0_map[] = {
++ {"LPSS_VNN_REQ_STS", BIT(3)},
++ {"FIA_VNN_REQ_STS", BIT(17)},
++ {"ESPISPI_VNN_REQ_STS", BIT(18)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_vnn_req_status_1_map[] = {
++ {"NPK_VNN_REQ_STS", BIT(4)},
++ {"DFXAGG_VNN_REQ_STS", BIT(8)},
++ {"EXI_VNN_REQ_STS", BIT(9)},
++ {"P2D_VNN_REQ_STS", BIT(18)},
++ {"GBE_VNN_REQ_STS", BIT(19)},
++ {"SMB_VNN_REQ_STS", BIT(25)},
++ {"LPC_VNN_REQ_STS", BIT(26)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_vnn_req_status_2_map[] = {
++ {"CSMERTC_VNN_REQ_STS", BIT(1)},
++ {"CSE_VNN_REQ_STS", BIT(4)},
++ {"ISH_VNN_REQ_STS", BIT(7)},
++ {"SMT1_VNN_REQ_STS", BIT(8)},
++ {"CLINK_VNN_REQ_STS", BIT(14)},
++ {"SMS1_VNN_REQ_STS", BIT(18)},
++ {"SMS2_VNN_REQ_STS", BIT(19)},
++ {"GPIOCOM4_VNN_REQ_STS", BIT(20)},
++ {"GPIOCOM3_VNN_REQ_STS", BIT(21)},
++ {"GPIOCOM2_VNN_REQ_STS", BIT(22)},
++ {"GPIOCOM1_VNN_REQ_STS", BIT(23)},
++ {"GPIOCOM0_VNN_REQ_STS", BIT(24)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_vnn_req_status_3_map[] = {
++ {"ESE_VNN_REQ_STS", BIT(2)},
++ {"DTS0_VNN_REQ_STS", BIT(7)},
++ {"GPIOCOM5_VNN_REQ_STS", BIT(11)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_vnn_misc_status_map[] = {
++ {"CPU_C10_REQ_STS", BIT(0)},
++ {"TS_OFF_REQ_STS", BIT(1)},
++ {"PNDE_MET_REQ_STS", BIT(2)},
++ {"PCIE_DEEP_PM_REQ_STS", BIT(3)},
++ {"PMC_CLK_THROTTLE_EN_REQ_STS", BIT(4)},
++ {"NPK_VNNAON_REQ_STS", BIT(5)},
++ {"VNN_SOC_REQ_STS", BIT(6)},
++ {"ISH_VNNAON_REQ_STS", BIT(7)},
++ {"IOE_COND_MET_S02I2_0_REQ_STS", BIT(8)},
++ {"IOE_COND_MET_S02I2_1_REQ_STS", BIT(9)},
++ {"IOE_COND_MET_S02I2_2_REQ_STS", BIT(10)},
++ {"PLT_GREATER_REQ_STS", BIT(11)},
++ {"PCIE_CLKREQ_REQ_STS", BIT(12)},
++ {"PMC_IDLE_FB_OCP_REQ_STS", BIT(13)},
++ {"PM_SYNC_STATES_REQ_STS", BIT(14)},
++ {"EA_REQ_STS", BIT(15)},
++ {"MPHY_CORE_OFF_REQ_STS", BIT(16)},
++ {"BRK_EV_EN_REQ_STS", BIT(17)},
++ {"AUTO_DEMO_EN_REQ_STS", BIT(18)},
++ {"ITSS_CLK_SRC_REQ_STS", BIT(19)},
++ {"LPC_CLK_SRC_REQ_STS", BIT(20)},
++ {"ARC_IDLE_REQ_STS", BIT(21)},
++ {"MPHY_SUS_REQ_STS", BIT(22)},
++ {"FIA_DEEP_PM_REQ_STS", BIT(23)},
++ {"UXD_CONNECTED_REQ_STS", BIT(24)},
++ {"ARC_INTERRUPT_WAKE_REQ_STS", BIT(25)},
++ {"USB2_VNNAON_ACT_REQ_STS", BIT(26)},
++ {"PRE_WAKE0_REQ_STS", BIT(27)},
++ {"PRE_WAKE1_REQ_STS", BIT(28)},
++ {"PRE_WAKE2_EN_REQ_STS", BIT(29)},
++ {"WOV_REQ_STS", BIT(30)},
++ {"CNVI_V1P05_REQ_STS", BIT(31)},
++ {}
++};
++
++const struct pmc_bit_map mtl_socm_signal_status_map[] = {
++ {"LSX_Wake0_En_STS", BIT(0)},
++ {"LSX_Wake0_Pol_STS", BIT(1)},
++ {"LSX_Wake1_En_STS", BIT(2)},
++ {"LSX_Wake1_Pol_STS", BIT(3)},
++ {"LSX_Wake2_En_STS", BIT(4)},
++ {"LSX_Wake2_Pol_STS", BIT(5)},
++ {"LSX_Wake3_En_STS", BIT(6)},
++ {"LSX_Wake3_Pol_STS", BIT(7)},
++ {"LSX_Wake4_En_STS", BIT(8)},
++ {"LSX_Wake4_Pol_STS", BIT(9)},
++ {"LSX_Wake5_En_STS", BIT(10)},
++ {"LSX_Wake5_Pol_STS", BIT(11)},
++ {"LSX_Wake6_En_STS", BIT(12)},
++ {"LSX_Wake6_Pol_STS", BIT(13)},
++ {"LSX_Wake7_En_STS", BIT(14)},
++ {"LSX_Wake7_Pol_STS", BIT(15)},
++ {"LPSS_Wake0_En_STS", BIT(16)},
++ {"LPSS_Wake0_Pol_STS", BIT(17)},
++ {"LPSS_Wake1_En_STS", BIT(18)},
++ {"LPSS_Wake1_Pol_STS", BIT(19)},
++ {"Int_Timer_SS_Wake0_En_STS", BIT(20)},
++ {"Int_Timer_SS_Wake0_Pol_STS", BIT(21)},
++ {"Int_Timer_SS_Wake1_En_STS", BIT(22)},
++ {"Int_Timer_SS_Wake1_Pol_STS", BIT(23)},
++ {"Int_Timer_SS_Wake2_En_STS", BIT(24)},
++ {"Int_Timer_SS_Wake2_Pol_STS", BIT(25)},
++ {"Int_Timer_SS_Wake3_En_STS", BIT(26)},
++ {"Int_Timer_SS_Wake3_Pol_STS", BIT(27)},
++ {"Int_Timer_SS_Wake4_En_STS", BIT(28)},
++ {"Int_Timer_SS_Wake4_Pol_STS", BIT(29)},
++ {"Int_Timer_SS_Wake5_En_STS", BIT(30)},
++ {"Int_Timer_SS_Wake5_Pol_STS", BIT(31)},
++ {}
++};
++
++const struct pmc_bit_map *mtl_socm_lpm_maps[] = {
++ mtl_socm_clocksource_status_map,
++ mtl_socm_power_gating_status_0_map,
++ mtl_socm_power_gating_status_1_map,
++ mtl_socm_power_gating_status_2_map,
++ mtl_socm_d3_status_0_map,
++ mtl_socm_d3_status_1_map,
++ mtl_socm_d3_status_2_map,
++ mtl_socm_d3_status_3_map,
++ mtl_socm_vnn_req_status_0_map,
++ mtl_socm_vnn_req_status_1_map,
++ mtl_socm_vnn_req_status_2_map,
++ mtl_socm_vnn_req_status_3_map,
++ mtl_socm_vnn_misc_status_map,
++ mtl_socm_signal_status_map,
++ NULL
++};
++
++const struct pmc_reg_map mtl_socm_reg_map = {
++ .pfear_sts = ext_mtl_socm_pfear_map,
+ .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
+ .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP,
+- .ltr_show_sts = adl_ltr_show_map,
++ .ltr_show_sts = mtl_socm_ltr_show_map,
+ .msr_sts = msr_map,
+ .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
+- .regmap_length = CNP_PMC_MMIO_REG_LEN,
++ .regmap_length = MTL_SOC_PMC_MMIO_REG_LEN,
+ .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
+- .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES,
++ .ppfear_buckets = MTL_SOCM_PPFEAR_NUM_ENTRIES,
+ .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
+ .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
+- .ltr_ignore_max = ADL_NUM_IP_IGN_ALLOWED,
+- .lpm_num_modes = ADL_LPM_NUM_MODES,
+ .lpm_num_maps = ADL_LPM_NUM_MAPS,
++ .ltr_ignore_max = MTL_SOCM_NUM_IP_IGN_ALLOWED,
+ .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2,
+ .etr3_offset = ETR3_OFFSET,
+ .lpm_sts_latch_en_offset = MTL_LPM_STATUS_LATCH_EN_OFFSET,
+ .lpm_priority_offset = MTL_LPM_PRI_OFFSET,
+ .lpm_en_offset = MTL_LPM_EN_OFFSET,
+ .lpm_residency_offset = MTL_LPM_RESIDENCY_OFFSET,
+- .lpm_sts = adl_lpm_maps,
++ .lpm_sts = mtl_socm_lpm_maps,
+ .lpm_status_offset = MTL_LPM_STATUS_OFFSET,
+ .lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET,
+ };
+@@ -47,6 +477,6 @@ void mtl_core_configure(struct pmc_dev *pmcdev)
+
+ void mtl_core_init(struct pmc_dev *pmcdev)
+ {
+- pmcdev->map = &mtl_reg_map;
++ pmcdev->map = &mtl_socm_reg_map;
+ pmcdev->core_configure = mtl_core_configure;
+ }
+--
+2.39.2
+
--- /dev/null
+From 454fa010bb434b6ac616df9c1b7d6d99367c39e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Apr 2023 18:57:50 +0200
+Subject: platform/x86: lenovo-yogabook: Fix work race on remove()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 9148cd2eb4450a8e9c49c8a14201fb82f651128f ]
+
+When yogabook_wmi_remove() runs yogabook_wmi_work might still be running
+and using the devices which yogabook_wmi_remove() puts.
+
+To avoid this move to explicitly cancelling the work rather then using
+devm_work_autocancel().
+
+This requires also making the yogabook_backside_hall_irq handler non
+devm managed, so that it cannot re-queue the work while
+yogabook_wmi_remove() runs.
+
+Fixes: c0549b72d99d ("platform/x86: lenovo-yogabook-wmi: Add driver for Lenovo Yoga Book")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20230430165807.472798-3-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/lenovo-yogabook-wmi.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/platform/x86/lenovo-yogabook-wmi.c b/drivers/platform/x86/lenovo-yogabook-wmi.c
+index 5f4bd1eec38a9..3a6de4ab74a41 100644
+--- a/drivers/platform/x86/lenovo-yogabook-wmi.c
++++ b/drivers/platform/x86/lenovo-yogabook-wmi.c
+@@ -2,7 +2,6 @@
+ /* WMI driver for Lenovo Yoga Book YB1-X90* / -X91* tablets */
+
+ #include <linux/acpi.h>
+-#include <linux/devm-helpers.h>
+ #include <linux/gpio/consumer.h>
+ #include <linux/gpio/machine.h>
+ #include <linux/interrupt.h>
+@@ -248,10 +247,7 @@ static int yogabook_wmi_probe(struct wmi_device *wdev, const void *context)
+ data->brightness = YB_KBD_BL_DEFAULT;
+ set_bit(YB_KBD_IS_ON, &data->flags);
+ set_bit(YB_DIGITIZER_IS_ON, &data->flags);
+-
+- r = devm_work_autocancel(&wdev->dev, &data->work, yogabook_wmi_work);
+- if (r)
+- return r;
++ INIT_WORK(&data->work, yogabook_wmi_work);
+
+ data->kbd_adev = acpi_dev_get_first_match_dev("GDIX1001", NULL, -1);
+ if (!data->kbd_adev) {
+@@ -299,10 +295,9 @@ static int yogabook_wmi_probe(struct wmi_device *wdev, const void *context)
+ }
+ data->backside_hall_irq = r;
+
+- r = devm_request_irq(&wdev->dev, data->backside_hall_irq,
+- yogabook_backside_hall_irq,
+- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+- "backside_hall_sw", data);
++ r = request_irq(data->backside_hall_irq, yogabook_backside_hall_irq,
++ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++ "backside_hall_sw", data);
+ if (r) {
+ dev_err_probe(&wdev->dev, r, "Requesting backside_hall_sw IRQ\n");
+ goto error_put_devs;
+@@ -318,11 +313,14 @@ static int yogabook_wmi_probe(struct wmi_device *wdev, const void *context)
+ r = devm_led_classdev_register(&wdev->dev, &data->kbd_bl_led);
+ if (r < 0) {
+ dev_err_probe(&wdev->dev, r, "Registering backlight LED device\n");
+- goto error_put_devs;
++ goto error_free_irq;
+ }
+
+ return 0;
+
++error_free_irq:
++ free_irq(data->backside_hall_irq, data);
++ cancel_work_sync(&data->work);
+ error_put_devs:
+ put_device(data->dig_dev);
+ put_device(data->kbd_dev);
+@@ -335,6 +333,8 @@ static void yogabook_wmi_remove(struct wmi_device *wdev)
+ {
+ struct yogabook_wmi *data = dev_get_drvdata(&wdev->dev);
+
++ free_irq(data->backside_hall_irq, data);
++ cancel_work_sync(&data->work);
+ put_device(data->dig_dev);
+ put_device(data->kbd_dev);
+ acpi_dev_put(data->dig_adev);
+--
+2.39.2
+
--- /dev/null
+From a3d625d05e2780952bae96ee147fc77d94ff174a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Apr 2023 18:57:51 +0200
+Subject: platform/x86: lenovo-yogabook: Reprobe devices on remove()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 711bcc0cb34e96a60e88d7b0260862781de3e530 ]
+
+Ensure that both the keyboard touchscreen and the digitizer have their
+driver bound after remove(). Without this modprobing lenovo-yogabook-wmi
+after a rmmod fails because lenovo-yogabook-wmi defers probing until
+both devices have their driver bound.
+
+Fixes: c0549b72d99d ("platform/x86: lenovo-yogabook-wmi: Add driver for Lenovo Yoga Book")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20230430165807.472798-4-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/lenovo-yogabook-wmi.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/platform/x86/lenovo-yogabook-wmi.c b/drivers/platform/x86/lenovo-yogabook-wmi.c
+index 3a6de4ab74a41..5948ffa74acd5 100644
+--- a/drivers/platform/x86/lenovo-yogabook-wmi.c
++++ b/drivers/platform/x86/lenovo-yogabook-wmi.c
+@@ -332,9 +332,20 @@ static int yogabook_wmi_probe(struct wmi_device *wdev, const void *context)
+ static void yogabook_wmi_remove(struct wmi_device *wdev)
+ {
+ struct yogabook_wmi *data = dev_get_drvdata(&wdev->dev);
++ int r = 0;
+
+ free_irq(data->backside_hall_irq, data);
+ cancel_work_sync(&data->work);
++
++ if (!test_bit(YB_KBD_IS_ON, &data->flags))
++ r |= device_reprobe(data->kbd_dev);
++
++ if (!test_bit(YB_DIGITIZER_IS_ON, &data->flags))
++ r |= device_reprobe(data->dig_dev);
++
++ if (r)
++ dev_warn(&wdev->dev, "Reprobe of devices failed\n");
++
+ put_device(data->dig_dev);
+ put_device(data->kbd_dev);
+ acpi_dev_put(data->dig_adev);
+--
+2.39.2
+
--- /dev/null
+From aafa1c8793746ec2a8047f9b937b169f4bc4640a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Apr 2023 18:57:52 +0200
+Subject: platform/x86: lenovo-yogabook: Set default keyboard backligh
+ brightness on probe()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 9e6380d6573181c555ca1b5019b08d19a9ee581c ]
+
+Set default keyboard backlight brightness on probe(), this fixes
+the backlight being off after a rmmod + modprobe.
+
+Fixes: c0549b72d99d ("platform/x86: lenovo-yogabook-wmi: Add driver for Lenovo Yoga Book")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20230430165807.472798-5-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/lenovo-yogabook-wmi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/platform/x86/lenovo-yogabook-wmi.c b/drivers/platform/x86/lenovo-yogabook-wmi.c
+index 5948ffa74acd5..d57fcc8388519 100644
+--- a/drivers/platform/x86/lenovo-yogabook-wmi.c
++++ b/drivers/platform/x86/lenovo-yogabook-wmi.c
+@@ -295,6 +295,9 @@ static int yogabook_wmi_probe(struct wmi_device *wdev, const void *context)
+ }
+ data->backside_hall_irq = r;
+
++ /* Set default brightness before enabling the IRQ */
++ yogabook_wmi_set_kbd_backlight(data->wdev, YB_KBD_BL_DEFAULT);
++
+ r = request_irq(data->backside_hall_irq, yogabook_backside_hall_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "backside_hall_sw", data);
+--
+2.39.2
+
--- /dev/null
+From b503bb982ecabe46dd8cd88712c39b51e774318b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 16:05:50 -0400
+Subject: platform/x86: think-lmi: Correct NVME password handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mark Pearson <mpearson-lenovo@squebb.ca>
+
+[ Upstream commit 4cebb42412248d28df6de01420cfac5654428d41 ]
+
+NVME passwords identifier have been standardised across the Lenovo
+systems and now use udrp and adrp (user and admin level) instead of
+unvp and mnvp.
+
+This should apparently be backwards compatible.
+
+Fixes: 640a5fa50a42 ("platform/x86: think-lmi: Opcode support")
+Signed-off-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20230601200552.4396-6-mpearson-lenovo@squebb.ca
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/think-lmi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c
+index cd755ef48ce40..4b7f2a969dfec 100644
+--- a/drivers/platform/x86/think-lmi.c
++++ b/drivers/platform/x86/think-lmi.c
+@@ -461,9 +461,9 @@ static ssize_t new_password_store(struct kobject *kobj,
+ sprintf(pwd_type, "mhdp%d", setting->index);
+ } else if (setting == tlmi_priv.pwd_nvme) {
+ if (setting->level == TLMI_LEVEL_USER)
+- sprintf(pwd_type, "unvp%d", setting->index);
++ sprintf(pwd_type, "udrp%d", setting->index);
+ else
+- sprintf(pwd_type, "mnvp%d", setting->index);
++ sprintf(pwd_type, "adrp%d", setting->index);
+ } else {
+ sprintf(pwd_type, "%s", setting->pwd_type);
+ }
+--
+2.39.2
+
--- /dev/null
+From ebbacc5b36e450622640c98ef87e26f9ef6a5e3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 16:05:47 -0400
+Subject: platform/x86: think-lmi: Correct System password interface
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mark Pearson <mpearson-lenovo@squebb.ca>
+
+[ Upstream commit 97eef5983372d7aee6549d644d788fd0c10d2b6e ]
+
+The system password identification was incorrect. This means that if
+the password was enabled it wouldn't be detected correctly; and setting
+it would not work.
+Also updated code to use TLMI_SMP_PWD instead of TLMI_SYS_PWD to be in
+sync with Lenovo documentation.
+
+Fixes: 640a5fa50a42 ("platform/x86: think-lmi: Opcode support")
+Signed-off-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20230601200552.4396-3-mpearson-lenovo@squebb.ca
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/think-lmi.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c
+index 7a145f578ef49..cd755ef48ce40 100644
+--- a/drivers/platform/x86/think-lmi.c
++++ b/drivers/platform/x86/think-lmi.c
+@@ -172,7 +172,7 @@ MODULE_PARM_DESC(debug_support, "Enable debug command support");
+ #define TLMI_POP_PWD (1 << 0)
+ #define TLMI_PAP_PWD (1 << 1)
+ #define TLMI_HDD_PWD (1 << 2)
+-#define TLMI_SYS_PWD (1 << 3)
++#define TLMI_SMP_PWD (1 << 6) /* System Management */
+ #define TLMI_CERT (1 << 7)
+
+ #define to_tlmi_pwd_setting(kobj) container_of(kobj, struct tlmi_pwd_setting, kobj)
+@@ -1522,11 +1522,11 @@ static int tlmi_analyze(void)
+ tlmi_priv.pwd_power->valid = true;
+
+ if (tlmi_priv.opcode_support) {
+- tlmi_priv.pwd_system = tlmi_create_auth("sys", "system");
++ tlmi_priv.pwd_system = tlmi_create_auth("smp", "system");
+ if (!tlmi_priv.pwd_system)
+ goto fail_clear_attr;
+
+- if (tlmi_priv.pwdcfg.core.password_state & TLMI_SYS_PWD)
++ if (tlmi_priv.pwdcfg.core.password_state & TLMI_SMP_PWD)
+ tlmi_priv.pwd_system->valid = true;
+
+ tlmi_priv.pwd_hdd = tlmi_create_auth("hdd", "hdd");
+--
+2.39.2
+
--- /dev/null
+From 70c84cef734243eab5f2648102971e2e878f1b90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 16:05:45 -0400
+Subject: platform/x86: think-lmi: mutex protection around multiple WMI calls
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mark Pearson <mpearson-lenovo@squebb.ca>
+
+[ Upstream commit c41e0121a1221894a1a9c4666156db9e1def4d6c ]
+
+When an attribute is being changed if the Admin account is enabled, or if
+a password is being updated then multiple WMI calls are needed.
+Add mutex protection to ensure no race conditions are introduced.
+
+Fixes: b49f72e7f96d ("platform/x86: think-lmi: Certificate authentication support")
+Signed-off-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20230601200552.4396-1-mpearson-lenovo@squebb.ca
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/think-lmi.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c
+index 78dc82bda4dde..7a145f578ef49 100644
+--- a/drivers/platform/x86/think-lmi.c
++++ b/drivers/platform/x86/think-lmi.c
+@@ -14,6 +14,7 @@
+ #include <linux/acpi.h>
+ #include <linux/errno.h>
+ #include <linux/fs.h>
++#include <linux/mutex.h>
+ #include <linux/string.h>
+ #include <linux/types.h>
+ #include <linux/dmi.h>
+@@ -195,6 +196,7 @@ static const char * const level_options[] = {
+ };
+ static struct think_lmi tlmi_priv;
+ static struct class *fw_attr_class;
++static DEFINE_MUTEX(tlmi_mutex);
+
+ /* ------ Utility functions ------------*/
+ /* Strip out CR if one is present */
+@@ -437,6 +439,9 @@ static ssize_t new_password_store(struct kobject *kobj,
+ /* Strip out CR if one is present, setting password won't work if it is present */
+ strip_cr(new_pwd);
+
++ /* Use lock in case multiple WMI operations needed */
++ mutex_lock(&tlmi_mutex);
++
+ pwdlen = strlen(new_pwd);
+ /* pwdlen == 0 is allowed to clear the password */
+ if (pwdlen && ((pwdlen < setting->minlen) || (pwdlen > setting->maxlen))) {
+@@ -493,6 +498,7 @@ static ssize_t new_password_store(struct kobject *kobj,
+ kfree(auth_str);
+ }
+ out:
++ mutex_unlock(&tlmi_mutex);
+ kfree(new_pwd);
+ return ret ?: count;
+ }
+@@ -982,6 +988,9 @@ static ssize_t current_value_store(struct kobject *kobj,
+ /* Strip out CR if one is present */
+ strip_cr(new_setting);
+
++ /* Use lock in case multiple WMI operations needed */
++ mutex_lock(&tlmi_mutex);
++
+ /* Check if certificate authentication is enabled and active */
+ if (tlmi_priv.certificate_support && tlmi_priv.pwd_admin->cert_installed) {
+ if (!tlmi_priv.pwd_admin->signature || !tlmi_priv.pwd_admin->save_signature) {
+@@ -1040,6 +1049,7 @@ static ssize_t current_value_store(struct kobject *kobj,
+ kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE);
+ }
+ out:
++ mutex_unlock(&tlmi_mutex);
+ kfree(auth_str);
+ kfree(set_str);
+ kfree(new_setting);
+--
+2.39.2
+
--- /dev/null
+From 8ddd578b0bdc061ee784e08e21cbfcf3d4080433 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 11:18:04 -0400
+Subject: platform/x86: thinkpad_acpi: Fix lkp-tests warnings for platform
+ profiles
+
+From: Mark Pearson <mpearson-lenovo@squebb.ca>
+
+[ Upstream commit f999e23ce66c1555d7b653fba171a88ecee53704 ]
+
+Fix issues identified in dytc_profile_refresh identified by lkp-tests.
+drivers/platform/x86/thinkpad_acpi.c:10538
+ dytc_profile_refresh() error: uninitialized symbol 'funcmode'.
+drivers/platform/x86/thinkpad_acpi.c:10531
+ dytc_profile_refresh() error: uninitialized symbol 'output'.
+drivers/platform/x86/thinkpad_acpi.c:10537
+ dytc_profile_refresh() error: uninitialized symbol 'output'.
+
+These issues should not lead to real problems in the field as the refresh
+function should only be called if MMC or PSC mode enabled. But good to fix.
+
+Thanks to Dan Carpenter and the lkp-tests project for flagging these.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <error27@gmail.com>
+Closes: https://lore.kernel.org/r/202306011202.1hbgLRD4-lkp@intel.com/
+Fixes: 1bc5d819f0b9 ("platform/x86: thinkpad_acpi: Fix profile modes on Intel platforms")
+Signed-off-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Link: https://lore.kernel.org/r/20230606151804.8819-1-mpearson-lenovo@squebb.ca
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/thinkpad_acpi.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index e40cbe81b12c1..97c6ec12d0829 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -10524,8 +10524,8 @@ static int dytc_profile_set(struct platform_profile_handler *pprof,
+ static void dytc_profile_refresh(void)
+ {
+ enum platform_profile_option profile;
+- int output, err = 0;
+- int perfmode, funcmode;
++ int output = 0, err = 0;
++ int perfmode, funcmode = 0;
+
+ mutex_lock(&dytc_mutex);
+ if (dytc_capabilities & BIT(DYTC_FC_MMC)) {
+@@ -10538,6 +10538,8 @@ static void dytc_profile_refresh(void)
+ err = dytc_command(DYTC_CMD_GET, &output);
+ /* Check if we are PSC mode, or have AMT enabled */
+ funcmode = (output >> DYTC_GET_FUNCTION_BIT) & 0xF;
++ } else { /* Unknown profile mode */
++ err = -ENODEV;
+ }
+ mutex_unlock(&dytc_mutex);
+ if (err)
+--
+2.39.2
+
--- /dev/null
+From a3cf478ea7f4e5a3185fe306a69c2ddd2f522e7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Apr 2023 06:07:43 -0700
+Subject: PM: domains: fix integer overflow issues in genpd_parse_state()
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit e5d1c8722083f0332dcd3c85fa1273d85fb6bed8 ]
+
+Currently, while calculating residency and latency values, right
+operands may overflow if resulting values are big enough.
+
+To prevent this, albeit unlikely case, play it safe and convert
+right operands to left ones' type s64.
+
+Found by Linux Verification Center (linuxtesting.org) with static
+analysis tool SVACE.
+
+Fixes: 30f604283e05 ("PM / Domains: Allow domain power states to be read from DT")
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/domain.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
+index 32084e38b73d0..51b9d4eaab5ea 100644
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -2939,10 +2939,10 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
+
+ err = of_property_read_u32(state_node, "min-residency-us", &residency);
+ if (!err)
+- genpd_state->residency_ns = 1000 * residency;
++ genpd_state->residency_ns = 1000LL * residency;
+
+- genpd_state->power_on_latency_ns = 1000 * exit_latency;
+- genpd_state->power_off_latency_ns = 1000 * entry_latency;
++ genpd_state->power_on_latency_ns = 1000LL * exit_latency;
++ genpd_state->power_off_latency_ns = 1000LL * entry_latency;
+ genpd_state->fwnode = &state_node->fwnode;
+
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From 15644f49082e44d0370d31ef0a3476c7572c743f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 11:55:36 +0200
+Subject: PM: domains: Move the verification of in-params from
+ genpd_add_device()
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit 4384a70c8813e8573d1841fd94eee873f80a7e1a ]
+
+Commit f38d1a6d0025 ("PM: domains: Allocate governor data dynamically
+based on a genpd governor") started to use the in-parameters in
+genpd_add_device(), without first doing a verification of them.
+
+This isn't really a big problem, as most callers do a verification already.
+
+Therefore, let's drop the verification from genpd_add_device() and make
+sure all the callers take care of it instead.
+
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Fixes: f38d1a6d0025 ("PM: domains: Allocate governor data dynamically based on a genpd governor")
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/domain.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
+index 51b9d4eaab5ea..5cb2023581d4d 100644
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -1632,9 +1632,6 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
+
+ dev_dbg(dev, "%s()\n", __func__);
+
+- if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
+- return -EINVAL;
+-
+ gpd_data = genpd_alloc_dev_data(dev, gd);
+ if (IS_ERR(gpd_data))
+ return PTR_ERR(gpd_data);
+@@ -1676,6 +1673,9 @@ int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev)
+ {
+ int ret;
+
++ if (!genpd || !dev)
++ return -EINVAL;
++
+ mutex_lock(&gpd_list_lock);
+ ret = genpd_add_device(genpd, dev, dev);
+ mutex_unlock(&gpd_list_lock);
+@@ -2523,6 +2523,9 @@ int of_genpd_add_device(struct of_phandle_args *genpdspec, struct device *dev)
+ struct generic_pm_domain *genpd;
+ int ret;
+
++ if (!dev)
++ return -EINVAL;
++
+ mutex_lock(&gpd_list_lock);
+
+ genpd = genpd_get_from_provider(genpdspec);
+--
+2.39.2
+
--- /dev/null
+From 6dab54d5ba6b4106d2147b5ee8f95aa010ed308c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jun 2023 22:16:34 +0200
+Subject: posix-timers: Prevent RT livelock in itimer_delete()
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 9d9e522010eb5685d8b53e8a24320653d9d4cbbf ]
+
+itimer_delete() has a retry loop when the timer is concurrently expired. On
+non-RT kernels this just spin-waits until the timer callback has completed,
+except for posix CPU timers which have HAVE_POSIX_CPU_TIMERS_TASK_WORK
+enabled.
+
+In that case and on RT kernels the existing task could live lock when
+preempting the task which does the timer delivery.
+
+Replace spin_unlock() with an invocation of timer_wait_running() to handle
+it the same way as the other retry loops in the posix timer code.
+
+Fixes: ec8f954a40da ("posix-timers: Use a callback for cancel synchronization on PREEMPT_RT")
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
+Link: https://lore.kernel.org/r/87v8g7c50d.ffs@tglx
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/posix-timers.c | 43 +++++++++++++++++++++++++++++++-------
+ 1 file changed, 35 insertions(+), 8 deletions(-)
+
+diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
+index 808a247205a9a..ed3c4a9543982 100644
+--- a/kernel/time/posix-timers.c
++++ b/kernel/time/posix-timers.c
+@@ -1037,27 +1037,52 @@ SYSCALL_DEFINE1(timer_delete, timer_t, timer_id)
+ }
+
+ /*
+- * return timer owned by the process, used by exit_itimers
++ * Delete a timer if it is armed, remove it from the hash and schedule it
++ * for RCU freeing.
+ */
+ static void itimer_delete(struct k_itimer *timer)
+ {
+-retry_delete:
+- spin_lock_irq(&timer->it_lock);
++ unsigned long flags;
++
++ /*
++ * irqsave is required to make timer_wait_running() work.
++ */
++ spin_lock_irqsave(&timer->it_lock, flags);
+
++retry_delete:
++ /*
++ * Even if the timer is not longer accessible from other tasks
++ * it still might be armed and queued in the underlying timer
++ * mechanism. Worse, that timer mechanism might run the expiry
++ * function concurrently.
++ */
+ if (timer_delete_hook(timer) == TIMER_RETRY) {
+- spin_unlock_irq(&timer->it_lock);
++ /*
++ * Timer is expired concurrently, prevent livelocks
++ * and pointless spinning on RT.
++ *
++ * timer_wait_running() drops timer::it_lock, which opens
++ * the possibility for another task to delete the timer.
++ *
++ * That's not possible here because this is invoked from
++ * do_exit() only for the last thread of the thread group.
++ * So no other task can access and delete that timer.
++ */
++ if (WARN_ON_ONCE(timer_wait_running(timer, &flags) != timer))
++ return;
++
+ goto retry_delete;
+ }
+ list_del(&timer->list);
+
+- spin_unlock_irq(&timer->it_lock);
++ spin_unlock_irqrestore(&timer->it_lock, flags);
+ release_posix_timer(timer, IT_ID_SET);
+ }
+
+ /*
+- * This is called by do_exit or de_thread, only when nobody else can
+- * modify the signal->posix_timers list. Yet we need sighand->siglock
+- * to prevent the race with /proc/pid/timers.
++ * Invoked from do_exit() when the last thread of a thread group exits.
++ * At that point no other task can access the timers of the dying
++ * task anymore.
+ */
+ void exit_itimers(struct task_struct *tsk)
+ {
+@@ -1067,10 +1092,12 @@ void exit_itimers(struct task_struct *tsk)
+ if (list_empty(&tsk->signal->posix_timers))
+ return;
+
++ /* Protect against concurrent read via /proc/$PID/timers */
+ spin_lock_irq(&tsk->sighand->siglock);
+ list_replace_init(&tsk->signal->posix_timers, &timers);
+ spin_unlock_irq(&tsk->sighand->siglock);
+
++ /* The timers are not longer accessible via tsk::signal */
+ while (!list_empty(&timers)) {
+ tmr = list_first_entry(&timers, struct k_itimer, list);
+ itimer_delete(tmr);
+--
+2.39.2
+
--- /dev/null
+From b47174732c234c0c4ca90c52750eff4d20fc79cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 22:00:00 +0800
+Subject: powercap: RAPL: Fix CONFIG_IOSF_MBI dependency
+
+From: Zhang Rui <rui.zhang@intel.com>
+
+[ Upstream commit 4658fe81b3f8afe8adf37734ec5fe595d90415c6 ]
+
+After commit 3382388d7148 ("intel_rapl: abstract RAPL common code"),
+accessing to IOSF_MBI interface is done in the RAPL common code.
+
+Thus it is the CONFIG_INTEL_RAPL_CORE that has dependency of
+CONFIG_IOSF_MBI, while CONFIG_INTEL_RAPL_MSR does not.
+
+This problem was not exposed previously because all the previous RAPL
+common code users, aka, the RAPL MSR and MMIO I/F drivers, have
+CONFIG_IOSF_MBI selected.
+
+Fix the CONFIG_IOSF_MBI dependency in RAPL code. This also fixes a build
+time failure when the RAPL TPMI I/F driver is introduced without
+selecting CONFIG_IOSF_MBI.
+
+x86_64-linux-ld: vmlinux.o: in function `set_floor_freq_atom':
+intel_rapl_common.c:(.text+0x2dac9b8): undefined reference to `iosf_mbi_write'
+x86_64-linux-ld: intel_rapl_common.c:(.text+0x2daca66): undefined reference to `iosf_mbi_read'
+
+Reference to iosf_mbi.h is also removed from the RAPL MSR I/F driver.
+
+Fixes: 3382388d7148 ("intel_rapl: abstract RAPL common code")
+Reported-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/all/20230601213246.3271412-1-arnd@kernel.org
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/powercap/Kconfig | 4 +++-
+ drivers/powercap/intel_rapl_msr.c | 1 -
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/powercap/Kconfig b/drivers/powercap/Kconfig
+index 90d33cd1b670a..b063f75117738 100644
+--- a/drivers/powercap/Kconfig
++++ b/drivers/powercap/Kconfig
+@@ -18,10 +18,12 @@ if POWERCAP
+ # Client driver configurations go here.
+ config INTEL_RAPL_CORE
+ tristate
++ depends on PCI
++ select IOSF_MBI
+
+ config INTEL_RAPL
+ tristate "Intel RAPL Support via MSR Interface"
+- depends on X86 && IOSF_MBI
++ depends on X86 && PCI
+ select INTEL_RAPL_CORE
+ help
+ This enables support for the Intel Running Average Power Limit (RAPL)
+diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c
+index 7be7561f5ad64..9ea4797d70b44 100644
+--- a/drivers/powercap/intel_rapl_msr.c
++++ b/drivers/powercap/intel_rapl_msr.c
+@@ -22,7 +22,6 @@
+ #include <linux/processor.h>
+ #include <linux/platform_device.h>
+
+-#include <asm/iosf_mbi.h>
+ #include <asm/cpu_device_id.h>
+ #include <asm/intel-family.h>
+
+--
+2.39.2
+
--- /dev/null
+From bbaaa73ee59f5e71ca99e7c789849c31f62ea22c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Jun 2023 08:00:06 +0530
+Subject: powercap: RAPL: fix invalid initialization for pl4_supported field
+
+From: Sumeet Pawnikar <sumeet.r.pawnikar@intel.com>
+
+[ Upstream commit d05b5e0baf424c8c4b4709ac11f66ab726c8deaf ]
+
+The current initialization of the struct x86_cpu_id via
+pl4_support_ids[] is partial and wrong. It is initializing
+"stepping" field with "X86_FEATURE_ANY" instead of "feature" field.
+
+Use X86_MATCH_INTEL_FAM6_MODEL macro instead of initializing
+each field of the struct x86_cpu_id for pl4_supported list of CPUs.
+This X86_MATCH_INTEL_FAM6_MODEL macro internally uses another macro
+X86_MATCH_VENDOR_FAM_MODEL_FEATURE for X86 based CPU matching with
+appropriate initialized values.
+
+Reported-by: Dave Hansen <dave.hansen@intel.com>
+Link: https://lore.kernel.org/lkml/28ead36b-2d9e-1a36-6f4e-04684e420260@intel.com
+Fixes: eb52bc2ae5b8 ("powercap: RAPL: Add Power Limit4 support for Meteor Lake SoC")
+Fixes: b08b95cf30f5 ("powercap: RAPL: Add Power Limit4 support for Alder Lake-N and Raptor Lake-P")
+Fixes: 515755906921 ("powercap: RAPL: Add Power Limit4 support for RaptorLake")
+Fixes: 1cc5b9a411e4 ("powercap: Add Power Limit4 support for Alder Lake SoC")
+Fixes: 8365a898fe53 ("powercap: Add Power Limit4 support")
+Signed-off-by: Sumeet Pawnikar <sumeet.r.pawnikar@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/powercap/intel_rapl_msr.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c
+index a27673706c3d6..7be7561f5ad64 100644
+--- a/drivers/powercap/intel_rapl_msr.c
++++ b/drivers/powercap/intel_rapl_msr.c
+@@ -137,14 +137,14 @@ static int rapl_msr_write_raw(int cpu, struct reg_action *ra)
+
+ /* List of verified CPUs. */
+ static const struct x86_cpu_id pl4_support_ids[] = {
+- { X86_VENDOR_INTEL, 6, INTEL_FAM6_TIGERLAKE_L, X86_FEATURE_ANY },
+- { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE, X86_FEATURE_ANY },
+- { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE_L, X86_FEATURE_ANY },
+- { X86_VENDOR_INTEL, 6, INTEL_FAM6_ALDERLAKE_N, X86_FEATURE_ANY },
+- { X86_VENDOR_INTEL, 6, INTEL_FAM6_RAPTORLAKE, X86_FEATURE_ANY },
+- { X86_VENDOR_INTEL, 6, INTEL_FAM6_RAPTORLAKE_P, X86_FEATURE_ANY },
+- { X86_VENDOR_INTEL, 6, INTEL_FAM6_METEORLAKE, X86_FEATURE_ANY },
+- { X86_VENDOR_INTEL, 6, INTEL_FAM6_METEORLAKE_L, X86_FEATURE_ANY },
++ X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, NULL),
++ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, NULL),
++ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, NULL),
++ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, NULL),
++ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, NULL),
++ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, NULL),
++ X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE, NULL),
++ X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, NULL),
+ {}
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 3e3b2bc23f5ec53baa1cfd1d30983b88936811e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jun 2023 20:10:24 +1000
+Subject: powerpc/64s: Fix VAS mm use after free
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit b4bda59b47879cce38a6ec5a01cd3cac702b5331 ]
+
+The refcount on mm is dropped before the coprocessor is detached.
+
+Reported-by: Sachin Sant <sachinp@linux.ibm.com>
+Fixes: 7bc6f71bdff5f ("powerpc/vas: Define and use common vas_window struct")
+Fixes: b22f2d88e435c ("powerpc/pseries/vas: Integrate API with open/close windows")
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Tested-by: Sachin Sant <sachinp@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230607101024.14559-1-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/powernv/vas-window.c | 2 +-
+ arch/powerpc/platforms/pseries/vas.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c
+index 0072682531d80..b664838008c12 100644
+--- a/arch/powerpc/platforms/powernv/vas-window.c
++++ b/arch/powerpc/platforms/powernv/vas-window.c
+@@ -1310,8 +1310,8 @@ int vas_win_close(struct vas_window *vwin)
+ /* if send window, drop reference to matching receive window */
+ if (window->tx_win) {
+ if (window->user_win) {
+- put_vas_user_win_ref(&vwin->task_ref);
+ mm_context_remove_vas_window(vwin->task_ref.mm);
++ put_vas_user_win_ref(&vwin->task_ref);
+ }
+ put_rx_win(window->rxwin);
+ }
+diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c
+index 513180467562b..9a44a98ba3420 100644
+--- a/arch/powerpc/platforms/pseries/vas.c
++++ b/arch/powerpc/platforms/pseries/vas.c
+@@ -507,8 +507,8 @@ static int vas_deallocate_window(struct vas_window *vwin)
+ vascaps[win->win_type].nr_open_windows--;
+ mutex_unlock(&vas_pseries_mutex);
+
+- put_vas_user_win_ref(&vwin->task_ref);
+ mm_context_remove_vas_window(vwin->task_ref.mm);
++ put_vas_user_win_ref(&vwin->task_ref);
+
+ kfree(win);
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From 3995a4e9aeeb0b2446300170104493bc581c4435 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 16:38:13 +0530
+Subject: powerpc/book3s64/mm: Fix DirectMap stats in /proc/meminfo
+
+From: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+
+[ Upstream commit 0da90af431abc3f497a38ec9ef6e43b0d0dabe80 ]
+
+On memory unplug reduce DirectMap page count correctly.
+root@ubuntu-guest:# grep Direct /proc/meminfo
+DirectMap4k: 0 kB
+DirectMap64k: 0 kB
+DirectMap2M: 115343360 kB
+DirectMap1G: 0 kB
+
+Before fix:
+root@ubuntu-guest:# ndctl disable-namespace all
+disabled 1 namespace
+root@ubuntu-guest:# grep Direct /proc/meminfo
+DirectMap4k: 0 kB
+DirectMap64k: 0 kB
+DirectMap2M: 115343360 kB
+DirectMap1G: 0 kB
+
+After fix:
+root@ubuntu-guest:# ndctl disable-namespace all
+disabled 1 namespace
+root@ubuntu-guest:# grep Direct /proc/meminfo
+DirectMap4k: 0 kB
+DirectMap64k: 0 kB
+DirectMap2M: 104857600 kB
+DirectMap1G: 0 kB
+
+Fixes: a2dc009afa9a ("powerpc/mm/book3s/radix: Add mapping statistics")
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Tested-by: Sachin Sant <sachinp@linux.ibm.com <mailto:sachinp@linux.ibm.com>>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230616110826.344417-4-aneesh.kumar@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/book3s64/radix_pgtable.c | 34 +++++++++++++++---------
+ 1 file changed, 22 insertions(+), 12 deletions(-)
+
+diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
+index 2297aa764ecdb..e8db8c8efe359 100644
+--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
++++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
+@@ -745,9 +745,9 @@ static void free_pud_table(pud_t *pud_start, p4d_t *p4d)
+ }
+
+ static void remove_pte_table(pte_t *pte_start, unsigned long addr,
+- unsigned long end)
++ unsigned long end, bool direct)
+ {
+- unsigned long next;
++ unsigned long next, pages = 0;
+ pte_t *pte;
+
+ pte = pte_start + pte_index(addr);
+@@ -769,13 +769,16 @@ static void remove_pte_table(pte_t *pte_start, unsigned long addr,
+ }
+
+ pte_clear(&init_mm, addr, pte);
++ pages++;
+ }
++ if (direct)
++ update_page_count(mmu_virtual_psize, -pages);
+ }
+
+ static void __meminit remove_pmd_table(pmd_t *pmd_start, unsigned long addr,
+- unsigned long end)
++ unsigned long end, bool direct)
+ {
+- unsigned long next;
++ unsigned long next, pages = 0;
+ pte_t *pte_base;
+ pmd_t *pmd;
+
+@@ -793,19 +796,22 @@ static void __meminit remove_pmd_table(pmd_t *pmd_start, unsigned long addr,
+ continue;
+ }
+ pte_clear(&init_mm, addr, (pte_t *)pmd);
++ pages++;
+ continue;
+ }
+
+ pte_base = (pte_t *)pmd_page_vaddr(*pmd);
+- remove_pte_table(pte_base, addr, next);
++ remove_pte_table(pte_base, addr, next, direct);
+ free_pte_table(pte_base, pmd);
+ }
++ if (direct)
++ update_page_count(MMU_PAGE_2M, -pages);
+ }
+
+ static void __meminit remove_pud_table(pud_t *pud_start, unsigned long addr,
+- unsigned long end)
++ unsigned long end, bool direct)
+ {
+- unsigned long next;
++ unsigned long next, pages = 0;
+ pmd_t *pmd_base;
+ pud_t *pud;
+
+@@ -823,16 +829,20 @@ static void __meminit remove_pud_table(pud_t *pud_start, unsigned long addr,
+ continue;
+ }
+ pte_clear(&init_mm, addr, (pte_t *)pud);
++ pages++;
+ continue;
+ }
+
+ pmd_base = pud_pgtable(*pud);
+- remove_pmd_table(pmd_base, addr, next);
++ remove_pmd_table(pmd_base, addr, next, direct);
+ free_pmd_table(pmd_base, pud);
+ }
++ if (direct)
++ update_page_count(MMU_PAGE_1G, -pages);
+ }
+
+-static void __meminit remove_pagetable(unsigned long start, unsigned long end)
++static void __meminit remove_pagetable(unsigned long start, unsigned long end,
++ bool direct)
+ {
+ unsigned long addr, next;
+ pud_t *pud_base;
+@@ -861,7 +871,7 @@ static void __meminit remove_pagetable(unsigned long start, unsigned long end)
+ }
+
+ pud_base = p4d_pgtable(*p4d);
+- remove_pud_table(pud_base, addr, next);
++ remove_pud_table(pud_base, addr, next, direct);
+ free_pud_table(pud_base, p4d);
+ }
+
+@@ -884,7 +894,7 @@ int __meminit radix__create_section_mapping(unsigned long start,
+
+ int __meminit radix__remove_section_mapping(unsigned long start, unsigned long end)
+ {
+- remove_pagetable(start, end);
++ remove_pagetable(start, end, true);
+ return 0;
+ }
+ #endif /* CONFIG_MEMORY_HOTPLUG */
+@@ -920,7 +930,7 @@ int __meminit radix__vmemmap_create_mapping(unsigned long start,
+ #ifdef CONFIG_MEMORY_HOTPLUG
+ void __meminit radix__vmemmap_remove_mapping(unsigned long start, unsigned long page_size)
+ {
+- remove_pagetable(start, start + page_size);
++ remove_pagetable(start, start + page_size, false);
+ }
+ #endif
+ #endif
+--
+2.39.2
+
--- /dev/null
+From 52aa157018e9a44bda2a5d5b0c30f1fe73a74ea8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 10:55:26 +0200
+Subject: powerpc/interrupt: Don't read MSR from
+ interrupt_exit_kernel_prepare()
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 0eb089a72fda3f7969e6277804bde75dc1474a14 ]
+
+A disassembly of interrupt_exit_kernel_prepare() shows a useless read
+of MSR register. This is shown by r9 being re-used immediately without
+doing anything with the value read.
+
+ c000e0e0: 60 00 00 00 nop
+ c000e0e4: 7d 3a c2 a6 mfmd_ap r9
+ c000e0e8: 7d 20 00 a6 mfmsr r9
+ c000e0ec: 7c 51 13 a6 mtspr 81,r2
+ c000e0f0: 81 3f 00 84 lwz r9,132(r31)
+ c000e0f4: 71 29 80 00 andi. r9,r9,32768
+
+This is due to the use of local_irq_save(). The flags read by
+local_irq_save() are never used, use local_irq_disable() instead.
+
+Fixes: 13799748b957 ("powerpc/64: use interrupt restart table to speed up return from interrupt")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/df36c6205ab64326fb1b991993c82057e92ace2f.1685955214.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/interrupt.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
+index 0ec1581619db5..cf770d86c03c6 100644
+--- a/arch/powerpc/kernel/interrupt.c
++++ b/arch/powerpc/kernel/interrupt.c
+@@ -368,7 +368,6 @@ void preempt_schedule_irq(void);
+
+ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
+ {
+- unsigned long flags;
+ unsigned long ret = 0;
+ unsigned long kuap;
+ bool stack_store = read_thread_flags() & _TIF_EMULATE_STACK_STORE;
+@@ -392,7 +391,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
+
+ kuap = kuap_get_and_assert_locked();
+
+- local_irq_save(flags);
++ local_irq_disable();
+
+ if (!arch_irq_disabled_regs(regs)) {
+ /* Returning to a kernel context with local irqs enabled. */
+--
+2.39.2
+
--- /dev/null
+From 6b0472021a7cb28eda52ad84c0a6cd5f3b7dbbad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 16:38:15 +0530
+Subject: powerpc/mm/dax: Fix the condition when checking if altmap vmemap can
+ cross-boundary
+
+From: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+
+[ Upstream commit c8eebc4a99f15280654f23e914e746c40a516e50 ]
+
+Without this fix, the last subsection vmemmap can end up in memory even if
+the namespace is created with -M mem and has sufficient space in the altmap
+area.
+
+Fixes: cf387d9644d8 ("libnvdimm/altmap: Track namespace boundaries in altmap")
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Tested-by: Sachin Sant <sachinp@linux.ibm.com <mailto:sachinp@linux.ibm.com>>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230616110826.344417-6-aneesh.kumar@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/init_64.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
+index 05b0d584e50b8..fe1b83020e0df 100644
+--- a/arch/powerpc/mm/init_64.c
++++ b/arch/powerpc/mm/init_64.c
+@@ -189,7 +189,7 @@ static bool altmap_cross_boundary(struct vmem_altmap *altmap, unsigned long star
+ unsigned long nr_pfn = page_size / sizeof(struct page);
+ unsigned long start_pfn = page_to_pfn((struct page *)start);
+
+- if ((start_pfn + nr_pfn) > altmap->end_pfn)
++ if ((start_pfn + nr_pfn - 1) > altmap->end_pfn)
+ return true;
+
+ if (start_pfn < altmap->base_pfn)
+--
+2.39.2
+
--- /dev/null
+From 3eb139f85f2ab8ec6185b5bf859a4be143566961 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Jun 2023 10:58:49 +0100
+Subject: powerpc/powernv/sriov: perform null check on iov before dereferencing
+ iov
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+[ Upstream commit f4f913c980bc6abe0ccfe88fe3909c125afe4a2d ]
+
+Currently pointer iov is being dereferenced before the null check of iov
+which can lead to null pointer dereference errors. Fix this by moving the
+iov null check before the dereferencing.
+
+Detected using cppcheck static analysis:
+linux/arch/powerpc/platforms/powernv/pci-sriov.c:597:12: warning: Either
+the condition '!iov' is redundant or there is possible null pointer
+dereference: iov. [nullPointerRedundantCheck]
+ num_vfs = iov->num_vfs;
+ ^
+
+Fixes: 052da31d45fc ("powerpc/powernv/sriov: De-indent setup and teardown")
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230608095849.1147969-1-colin.i.king@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/powernv/pci-sriov.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/platforms/powernv/pci-sriov.c b/arch/powerpc/platforms/powernv/pci-sriov.c
+index 7195133b26bb9..59882da3e7425 100644
+--- a/arch/powerpc/platforms/powernv/pci-sriov.c
++++ b/arch/powerpc/platforms/powernv/pci-sriov.c
+@@ -594,12 +594,12 @@ static void pnv_pci_sriov_disable(struct pci_dev *pdev)
+ struct pnv_iov_data *iov;
+
+ iov = pnv_iov_get(pdev);
+- num_vfs = iov->num_vfs;
+- base_pe = iov->vf_pe_arr[0].pe_number;
+-
+ if (WARN_ON(!iov))
+ return;
+
++ num_vfs = iov->num_vfs;
++ base_pe = iov->vf_pe_arr[0].pe_number;
++
+ /* Release VF PEs */
+ pnv_ioda_release_vf_PE(pdev);
+
+--
+2.39.2
+
--- /dev/null
+From fea2d7589636984175d4a1c8b24da52ee44056e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 10:58:35 +0200
+Subject: powerpc/signal32: Force inlining of __unsafe_save_user_regs() and
+ save_tm_user_regs_unsafe()
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit a03b1a0b19398a47489fdcef02ec19c2ba05a15d ]
+
+Looking at generated code for handle_signal32() shows calls to a
+function called __unsafe_save_user_regs.constprop.0 while user access
+is open.
+
+And that __unsafe_save_user_regs.constprop.0 function has two nops at
+the begining, allowing it to be traced, which is unexpected during
+user access open window.
+
+The solution could be to mark __unsafe_save_user_regs() no trace, but
+to be on the safe side the most efficient is to flag it __always_inline
+as already done for function __unsafe_restore_general_regs(). The
+function is relatively small and only called twice, so the size
+increase will remain in the noise.
+
+Do the same with save_tm_user_regs_unsafe() as it may suffer the
+same issue.
+
+Fixes: ef75e7318294 ("powerpc/signal32: Transform save_user_regs() and save_tm_user_regs() in 'unsafe' version")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/7e469c8f01860a69c1ada3ca6a5e2aa65f0f74b2.1685955220.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/signal_32.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
+index c114c7f25645c..7a718ed32b277 100644
+--- a/arch/powerpc/kernel/signal_32.c
++++ b/arch/powerpc/kernel/signal_32.c
+@@ -264,8 +264,9 @@ static void prepare_save_user_regs(int ctx_has_vsx_region)
+ #endif
+ }
+
+-static int __unsafe_save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
+- struct mcontext __user *tm_frame, int ctx_has_vsx_region)
++static __always_inline int
++__unsafe_save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
++ struct mcontext __user *tm_frame, int ctx_has_vsx_region)
+ {
+ unsigned long msr = regs->msr;
+
+@@ -364,8 +365,9 @@ static void prepare_save_tm_user_regs(void)
+ current->thread.ckvrsave = mfspr(SPRN_VRSAVE);
+ }
+
+-static int save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame,
+- struct mcontext __user *tm_frame, unsigned long msr)
++static __always_inline int
++save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame,
++ struct mcontext __user *tm_frame, unsigned long msr)
+ {
+ /* Save both sets of general registers */
+ unsafe_save_general_regs(¤t->thread.ckpt_regs, frame, failed);
+@@ -444,8 +446,9 @@ static int save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user
+ #else
+ static void prepare_save_tm_user_regs(void) { }
+
+-static int save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame,
+- struct mcontext __user *tm_frame, unsigned long msr)
++static __always_inline int
++save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame,
++ struct mcontext __user *tm_frame, unsigned long msr)
+ {
+ return 0;
+ }
+--
+2.39.2
+
--- /dev/null
+From 731e19ec619c21e28dbf000b5c6064524e9e7777 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 14:40:47 +0530
+Subject: powerpc: update ppc_save_regs to save current r1 in pt_regs
+
+From: Aditya Gupta <adityag@linux.ibm.com>
+
+[ Upstream commit b684c09f09e7a6af3794d4233ef785819e72db79 ]
+
+ppc_save_regs() skips one stack frame while saving the CPU register states.
+Instead of saving current R1, it pulls the previous stack frame pointer.
+
+When vmcores caused by direct panic call (such as `echo c >
+/proc/sysrq-trigger`), are debugged with gdb, gdb fails to show the
+backtrace correctly. On further analysis, it was found that it was because
+of mismatch between r1 and NIP.
+
+GDB uses NIP to get current function symbol and uses corresponding debug
+info of that function to unwind previous frames, but due to the
+mismatching r1 and NIP, the unwinding does not work, and it fails to
+unwind to the 2nd frame and hence does not show the backtrace.
+
+GDB backtrace with vmcore of kernel without this patch:
+
+---------
+(gdb) bt
+ #0 0xc0000000002a53e8 in crash_setup_regs (oldregs=<optimized out>,
+ newregs=0xc000000004f8f8d8) at ./arch/powerpc/include/asm/kexec.h:69
+ #1 __crash_kexec (regs=<optimized out>) at kernel/kexec_core.c:974
+ #2 0x0000000000000063 in ?? ()
+ #3 0xc000000003579320 in ?? ()
+---------
+
+Further analysis revealed that the mismatch occurred because
+"ppc_save_regs" was saving the previous stack's SP instead of the current
+r1. This patch fixes this by storing current r1 in the saved pt_regs.
+
+GDB backtrace with vmcore of patched kernel:
+
+--------
+(gdb) bt
+ #0 0xc0000000002a53e8 in crash_setup_regs (oldregs=0x0, newregs=0xc00000000670b8d8)
+ at ./arch/powerpc/include/asm/kexec.h:69
+ #1 __crash_kexec (regs=regs@entry=0x0) at kernel/kexec_core.c:974
+ #2 0xc000000000168918 in panic (fmt=fmt@entry=0xc000000001654a60 "sysrq triggered crash\n")
+ at kernel/panic.c:358
+ #3 0xc000000000b735f8 in sysrq_handle_crash (key=<optimized out>) at drivers/tty/sysrq.c:155
+ #4 0xc000000000b742cc in __handle_sysrq (key=key@entry=99, check_mask=check_mask@entry=false)
+ at drivers/tty/sysrq.c:602
+ #5 0xc000000000b7506c in write_sysrq_trigger (file=<optimized out>, buf=<optimized out>,
+ count=2, ppos=<optimized out>) at drivers/tty/sysrq.c:1163
+ #6 0xc00000000069a7bc in pde_write (ppos=<optimized out>, count=<optimized out>,
+ buf=<optimized out>, file=<optimized out>, pde=0xc00000000362cb40) at fs/proc/inode.c:340
+ #7 proc_reg_write (file=<optimized out>, buf=<optimized out>, count=<optimized out>,
+ ppos=<optimized out>) at fs/proc/inode.c:352
+ #8 0xc0000000005b3bbc in vfs_write (file=file@entry=0xc000000006aa6b00,
+ buf=buf@entry=0x61f498b4f60 <error: Cannot access memory at address 0x61f498b4f60>,
+ count=count@entry=2, pos=pos@entry=0xc00000000670bda0) at fs/read_write.c:582
+ #9 0xc0000000005b4264 in ksys_write (fd=<optimized out>,
+ buf=0x61f498b4f60 <error: Cannot access memory at address 0x61f498b4f60>, count=2)
+ at fs/read_write.c:637
+ #10 0xc00000000002ea2c in system_call_exception (regs=0xc00000000670be80, r0=<optimized out>)
+ at arch/powerpc/kernel/syscall.c:171
+ #11 0xc00000000000c270 in system_call_vectored_common ()
+ at arch/powerpc/kernel/interrupt_64.S:192
+--------
+
+Nick adds:
+ So this now saves regs as though it was an interrupt taken in the
+ caller, at the instruction after the call to ppc_save_regs, whereas
+ previously the NIP was there, but R1 came from the caller's caller and
+ that mismatch is what causes gdb's dwarf unwinder to go haywire.
+
+Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
+Fixes: d16a58f8854b1 ("powerpc: Improve ppc_save_regs()")
+Reivewed-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230615091047.90433-1-adityag@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/ppc_save_regs.S | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/kernel/ppc_save_regs.S b/arch/powerpc/kernel/ppc_save_regs.S
+index 49813f9824681..a9b9c32d0c1ff 100644
+--- a/arch/powerpc/kernel/ppc_save_regs.S
++++ b/arch/powerpc/kernel/ppc_save_regs.S
+@@ -31,10 +31,10 @@ _GLOBAL(ppc_save_regs)
+ lbz r0,PACAIRQSOFTMASK(r13)
+ PPC_STL r0,SOFTE(r3)
+ #endif
+- /* go up one stack frame for SP */
+- PPC_LL r4,0(r1)
+- PPC_STL r4,GPR1(r3)
++ /* store current SP */
++ PPC_STL r1,GPR1(r3)
+ /* get caller's LR */
++ PPC_LL r4,0(r1)
+ PPC_LL r0,LRSAVE(r4)
+ PPC_STL r0,_LINK(r3)
+ mflr r0
+--
+2.39.2
+
--- /dev/null
+From 07b7acb2c1bf7fc8412f4302b376c6613b39ede9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 17:37:33 +0800
+Subject: pstore/ram: Add check for kstrdup
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit d97038d5ec2062733c1e016caf9baaf68cf64ea1 ]
+
+Add check for the return value of kstrdup() and return the error
+if it fails in order to avoid NULL pointer dereference.
+
+Fixes: e163fdb3f7f8 ("pstore/ram: Regularize prz label allocation lifetime")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20230614093733.36048-1-jiasheng@iscas.ac.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/pstore/ram_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
+index 966191d3a5ba2..85aaf0fc6d7d1 100644
+--- a/fs/pstore/ram_core.c
++++ b/fs/pstore/ram_core.c
+@@ -599,6 +599,8 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
+ raw_spin_lock_init(&prz->buffer_lock);
+ prz->flags = flags;
+ prz->label = kstrdup(label, GFP_KERNEL);
++ if (!prz->label)
++ goto err;
+
+ ret = persistent_ram_buffer_map(start, size, prz, memtype);
+ if (ret)
+--
+2.39.2
+
--- /dev/null
+From 934813aa8e4ed0b48eac2683aef2b7dd2f77657e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Apr 2023 08:12:28 -0700
+Subject: radeon: avoid double free in ci_dpm_init()
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 20c3dffdccbd494e0dd631d1660aeecbff6775f2 ]
+
+Several calls to ci_dpm_fini() will attempt to free resources that
+either have been freed before or haven't been allocated yet. This
+may lead to undefined or dangerous behaviour.
+
+For instance, if r600_parse_extended_power_table() fails, it might
+call r600_free_extended_power_table() as will ci_dpm_fini() later
+during error handling.
+
+Fix this by only freeing pointers to objects previously allocated.
+
+Found by Linux Verification Center (linuxtesting.org) with static
+analysis tool SVACE.
+
+Fixes: cc8dbbb4f62a ("drm/radeon: add dpm support for CI dGPUs (v2)")
+Co-developed-by: Natalia Petrova <n.petrova@fintech.ru>
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/ci_dpm.c | 28 ++++++++++++++++++++--------
+ 1 file changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c
+index 8ef25ab305ae7..b8f4dac68d850 100644
+--- a/drivers/gpu/drm/radeon/ci_dpm.c
++++ b/drivers/gpu/drm/radeon/ci_dpm.c
+@@ -5517,6 +5517,7 @@ static int ci_parse_power_table(struct radeon_device *rdev)
+ u8 frev, crev;
+ u8 *power_state_offset;
+ struct ci_ps *ps;
++ int ret;
+
+ if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset))
+@@ -5546,11 +5547,15 @@ static int ci_parse_power_table(struct radeon_device *rdev)
+ non_clock_array_index = power_state->v2.nonClockInfoIndex;
+ non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
+ &non_clock_info_array->nonClockInfo[non_clock_array_index];
+- if (!rdev->pm.power_state[i].clock_info)
+- return -EINVAL;
++ if (!rdev->pm.power_state[i].clock_info) {
++ ret = -EINVAL;
++ goto err_free_ps;
++ }
+ ps = kzalloc(sizeof(struct ci_ps), GFP_KERNEL);
+- if (ps == NULL)
+- return -ENOMEM;
++ if (ps == NULL) {
++ ret = -ENOMEM;
++ goto err_free_ps;
++ }
+ rdev->pm.dpm.ps[i].ps_priv = ps;
+ ci_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
+ non_clock_info,
+@@ -5590,6 +5595,12 @@ static int ci_parse_power_table(struct radeon_device *rdev)
+ }
+
+ return 0;
++
++err_free_ps:
++ for (i = 0; i < rdev->pm.dpm.num_ps; i++)
++ kfree(rdev->pm.dpm.ps[i].ps_priv);
++ kfree(rdev->pm.dpm.ps);
++ return ret;
+ }
+
+ static int ci_get_vbios_boot_values(struct radeon_device *rdev,
+@@ -5678,25 +5689,26 @@ int ci_dpm_init(struct radeon_device *rdev)
+
+ ret = ci_get_vbios_boot_values(rdev, &pi->vbios_boot_state);
+ if (ret) {
+- ci_dpm_fini(rdev);
++ kfree(rdev->pm.dpm.priv);
+ return ret;
+ }
+
+ ret = r600_get_platform_caps(rdev);
+ if (ret) {
+- ci_dpm_fini(rdev);
++ kfree(rdev->pm.dpm.priv);
+ return ret;
+ }
+
+ ret = r600_parse_extended_power_table(rdev);
+ if (ret) {
+- ci_dpm_fini(rdev);
++ kfree(rdev->pm.dpm.priv);
+ return ret;
+ }
+
+ ret = ci_parse_power_table(rdev);
+ if (ret) {
+- ci_dpm_fini(rdev);
++ kfree(rdev->pm.dpm.priv);
++ r600_free_extended_power_table(rdev);
+ return ret;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 75385cb2d82c3857268d1b959982e1d7fa9d6dfe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Apr 2023 10:50:47 -0700
+Subject: rcu: Make rcu_cpu_starting() rely on interrupts being disabled
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit 15d44dfa40305da1648de4bf001e91cc63148725 ]
+
+Currently, rcu_cpu_starting() is written so that it might be invoked
+with interrupts enabled. However, it is always called when interrupts
+are disabled, either by rcu_init(), notify_cpu_starting(), or from a
+call point prior to the call to notify_cpu_starting().
+
+But why bother requiring that interrupts be disabled? The purpose is
+to allow the rcu_data structure's ->beenonline flag to be set after all
+early processing has completed for the incoming CPU, thus allowing this
+flag to be used to determine when workqueues have been set up for the
+incoming CPU, while still allowing this flag to be used as a diagnostic
+within rcu_core().
+
+This commit therefore makes rcu_cpu_starting() rely on interrupts being
+disabled.
+
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Stable-dep-of: 401b0de3ae4f ("rcu-tasks: Stop rcu_tasks_invoke_cbs() from using never-onlined CPUs")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/tree.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index a565dc5c54440..954a91fec912c 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -4364,15 +4364,16 @@ int rcutree_offline_cpu(unsigned int cpu)
+ * Note that this function is special in that it is invoked directly
+ * from the incoming CPU rather than from the cpuhp_step mechanism.
+ * This is because this function must be invoked at a precise location.
++ * This incoming CPU must not have enabled interrupts yet.
+ */
+ void rcu_cpu_starting(unsigned int cpu)
+ {
+- unsigned long flags;
+ unsigned long mask;
+ struct rcu_data *rdp;
+ struct rcu_node *rnp;
+ bool newcpu;
+
++ lockdep_assert_irqs_disabled();
+ rdp = per_cpu_ptr(&rcu_data, cpu);
+ if (rdp->cpu_started)
+ return;
+@@ -4380,7 +4381,6 @@ void rcu_cpu_starting(unsigned int cpu)
+
+ rnp = rdp->mynode;
+ mask = rdp->grpmask;
+- local_irq_save(flags);
+ arch_spin_lock(&rcu_state.ofl_lock);
+ rcu_dynticks_eqs_online();
+ raw_spin_lock(&rcu_state.barrier_lock);
+@@ -4399,17 +4399,16 @@ void rcu_cpu_starting(unsigned int cpu)
+ /* An incoming CPU should never be blocking a grace period. */
+ if (WARN_ON_ONCE(rnp->qsmask & mask)) { /* RCU waiting on incoming CPU? */
+ /* rcu_report_qs_rnp() *really* wants some flags to restore */
+- unsigned long flags2;
++ unsigned long flags;
+
+- local_irq_save(flags2);
++ local_irq_save(flags);
+ rcu_disable_urgency_upon_qs(rdp);
+ /* Report QS -after- changing ->qsmaskinitnext! */
+- rcu_report_qs_rnp(mask, rnp, rnp->gp_seq, flags2);
++ rcu_report_qs_rnp(mask, rnp, rnp->gp_seq, flags);
+ } else {
+ raw_spin_unlock_rcu_node(rnp);
+ }
+ arch_spin_unlock(&rcu_state.ofl_lock);
+- local_irq_restore(flags);
+ smp_mb(); /* Ensure RCU read-side usage follows above initialization. */
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 2242a769ba9657ae28be5833ae4f099ef609544f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Mar 2023 19:42:40 +0800
+Subject: rcu/rcuscale: Move rcu_scale_*() after kfree_scale_cleanup()
+
+From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+
+[ Upstream commit bf5ddd736509a7d9077c0b6793e6f0852214dbea ]
+
+This code-movement-only commit moves the rcu_scale_cleanup() and
+rcu_scale_shutdown() functions to follow kfree_scale_cleanup().
+This is code movement is in preparation for a bug-fix patch that invokes
+kfree_scale_cleanup() from rcu_scale_cleanup().
+
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
+Stable-dep-of: 23fc8df26dea ("rcu/rcuscale: Stop kfree_scale_thread thread(s) after unloading rcuscale")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/rcuscale.c | 194 +++++++++++++++++++++---------------------
+ 1 file changed, 97 insertions(+), 97 deletions(-)
+
+diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c
+index 4120f94030c3c..dd25d306559a5 100644
+--- a/kernel/rcu/rcuscale.c
++++ b/kernel/rcu/rcuscale.c
+@@ -522,89 +522,6 @@ rcu_scale_print_module_parms(struct rcu_scale_ops *cur_ops, const char *tag)
+ scale_type, tag, nrealreaders, nrealwriters, verbose, shutdown);
+ }
+
+-static void
+-rcu_scale_cleanup(void)
+-{
+- int i;
+- int j;
+- int ngps = 0;
+- u64 *wdp;
+- u64 *wdpp;
+-
+- /*
+- * Would like warning at start, but everything is expedited
+- * during the mid-boot phase, so have to wait till the end.
+- */
+- if (rcu_gp_is_expedited() && !rcu_gp_is_normal() && !gp_exp)
+- SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!");
+- if (rcu_gp_is_normal() && gp_exp)
+- SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!");
+- if (gp_exp && gp_async)
+- SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!");
+-
+- if (torture_cleanup_begin())
+- return;
+- if (!cur_ops) {
+- torture_cleanup_end();
+- return;
+- }
+-
+- if (reader_tasks) {
+- for (i = 0; i < nrealreaders; i++)
+- torture_stop_kthread(rcu_scale_reader,
+- reader_tasks[i]);
+- kfree(reader_tasks);
+- }
+-
+- if (writer_tasks) {
+- for (i = 0; i < nrealwriters; i++) {
+- torture_stop_kthread(rcu_scale_writer,
+- writer_tasks[i]);
+- if (!writer_n_durations)
+- continue;
+- j = writer_n_durations[i];
+- pr_alert("%s%s writer %d gps: %d\n",
+- scale_type, SCALE_FLAG, i, j);
+- ngps += j;
+- }
+- pr_alert("%s%s start: %llu end: %llu duration: %llu gps: %d batches: %ld\n",
+- scale_type, SCALE_FLAG,
+- t_rcu_scale_writer_started, t_rcu_scale_writer_finished,
+- t_rcu_scale_writer_finished -
+- t_rcu_scale_writer_started,
+- ngps,
+- rcuscale_seq_diff(b_rcu_gp_test_finished,
+- b_rcu_gp_test_started));
+- for (i = 0; i < nrealwriters; i++) {
+- if (!writer_durations)
+- break;
+- if (!writer_n_durations)
+- continue;
+- wdpp = writer_durations[i];
+- if (!wdpp)
+- continue;
+- for (j = 0; j < writer_n_durations[i]; j++) {
+- wdp = &wdpp[j];
+- pr_alert("%s%s %4d writer-duration: %5d %llu\n",
+- scale_type, SCALE_FLAG,
+- i, j, *wdp);
+- if (j % 100 == 0)
+- schedule_timeout_uninterruptible(1);
+- }
+- kfree(writer_durations[i]);
+- }
+- kfree(writer_tasks);
+- kfree(writer_durations);
+- kfree(writer_n_durations);
+- }
+-
+- /* Do torture-type-specific cleanup operations. */
+- if (cur_ops->cleanup != NULL)
+- cur_ops->cleanup();
+-
+- torture_cleanup_end();
+-}
+-
+ /*
+ * Return the number if non-negative. If -1, the number of CPUs.
+ * If less than -1, that much less than the number of CPUs, but
+@@ -624,20 +541,6 @@ static int compute_real(int n)
+ return nr;
+ }
+
+-/*
+- * RCU scalability shutdown kthread. Just waits to be awakened, then shuts
+- * down system.
+- */
+-static int
+-rcu_scale_shutdown(void *arg)
+-{
+- wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters);
+- smp_mb(); /* Wake before output. */
+- rcu_scale_cleanup();
+- kernel_power_off();
+- return -EINVAL;
+-}
+-
+ /*
+ * kfree_rcu() scalability tests: Start a kfree_rcu() loop on all CPUs for number
+ * of iterations and measure total time and number of GP for all iterations to complete.
+@@ -874,6 +777,103 @@ kfree_scale_init(void)
+ return firsterr;
+ }
+
++static void
++rcu_scale_cleanup(void)
++{
++ int i;
++ int j;
++ int ngps = 0;
++ u64 *wdp;
++ u64 *wdpp;
++
++ /*
++ * Would like warning at start, but everything is expedited
++ * during the mid-boot phase, so have to wait till the end.
++ */
++ if (rcu_gp_is_expedited() && !rcu_gp_is_normal() && !gp_exp)
++ SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!");
++ if (rcu_gp_is_normal() && gp_exp)
++ SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!");
++ if (gp_exp && gp_async)
++ SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!");
++
++ if (torture_cleanup_begin())
++ return;
++ if (!cur_ops) {
++ torture_cleanup_end();
++ return;
++ }
++
++ if (reader_tasks) {
++ for (i = 0; i < nrealreaders; i++)
++ torture_stop_kthread(rcu_scale_reader,
++ reader_tasks[i]);
++ kfree(reader_tasks);
++ }
++
++ if (writer_tasks) {
++ for (i = 0; i < nrealwriters; i++) {
++ torture_stop_kthread(rcu_scale_writer,
++ writer_tasks[i]);
++ if (!writer_n_durations)
++ continue;
++ j = writer_n_durations[i];
++ pr_alert("%s%s writer %d gps: %d\n",
++ scale_type, SCALE_FLAG, i, j);
++ ngps += j;
++ }
++ pr_alert("%s%s start: %llu end: %llu duration: %llu gps: %d batches: %ld\n",
++ scale_type, SCALE_FLAG,
++ t_rcu_scale_writer_started, t_rcu_scale_writer_finished,
++ t_rcu_scale_writer_finished -
++ t_rcu_scale_writer_started,
++ ngps,
++ rcuscale_seq_diff(b_rcu_gp_test_finished,
++ b_rcu_gp_test_started));
++ for (i = 0; i < nrealwriters; i++) {
++ if (!writer_durations)
++ break;
++ if (!writer_n_durations)
++ continue;
++ wdpp = writer_durations[i];
++ if (!wdpp)
++ continue;
++ for (j = 0; j < writer_n_durations[i]; j++) {
++ wdp = &wdpp[j];
++ pr_alert("%s%s %4d writer-duration: %5d %llu\n",
++ scale_type, SCALE_FLAG,
++ i, j, *wdp);
++ if (j % 100 == 0)
++ schedule_timeout_uninterruptible(1);
++ }
++ kfree(writer_durations[i]);
++ }
++ kfree(writer_tasks);
++ kfree(writer_durations);
++ kfree(writer_n_durations);
++ }
++
++ /* Do torture-type-specific cleanup operations. */
++ if (cur_ops->cleanup != NULL)
++ cur_ops->cleanup();
++
++ torture_cleanup_end();
++}
++
++/*
++ * RCU scalability shutdown kthread. Just waits to be awakened, then shuts
++ * down system.
++ */
++static int
++rcu_scale_shutdown(void *arg)
++{
++ wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters);
++ smp_mb(); /* Wake before output. */
++ rcu_scale_cleanup();
++ kernel_power_off();
++ return -EINVAL;
++}
++
+ static int __init
+ rcu_scale_init(void)
+ {
+--
+2.39.2
+
--- /dev/null
+From 3747640c0ed4a850bda665580fe98ccbb1ddf8ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Mar 2023 19:42:41 +0800
+Subject: rcu/rcuscale: Stop kfree_scale_thread thread(s) after unloading
+ rcuscale
+
+From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+
+[ Upstream commit 23fc8df26dead16687ae6eb47b0561a4a832e2f6 ]
+
+Running the 'kfree_rcu_test' test case [1] results in a splat [2].
+The root cause is the kfree_scale_thread thread(s) continue running
+after unloading the rcuscale module. This commit fixes that isue by
+invoking kfree_scale_cleanup() from rcu_scale_cleanup() when removing
+the rcuscale module.
+
+[1] modprobe rcuscale kfree_rcu_test=1
+ // After some time
+ rmmod rcuscale
+ rmmod torture
+
+[2] BUG: unable to handle page fault for address: ffffffffc0601a87
+ #PF: supervisor instruction fetch in kernel mode
+ #PF: error_code(0x0010) - not-present page
+ PGD 11de4f067 P4D 11de4f067 PUD 11de51067 PMD 112f4d067 PTE 0
+ Oops: 0010 [#1] PREEMPT SMP NOPTI
+ CPU: 1 PID: 1798 Comm: kfree_scale_thr Not tainted 6.3.0-rc1-rcu+ #1
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
+ RIP: 0010:0xffffffffc0601a87
+ Code: Unable to access opcode bytes at 0xffffffffc0601a5d.
+ RSP: 0018:ffffb25bc2e57e18 EFLAGS: 00010297
+ RAX: 0000000000000000 RBX: ffffffffc061f0b6 RCX: 0000000000000000
+ RDX: 0000000000000000 RSI: ffffffff962fd0de RDI: ffffffff962fd0de
+ RBP: ffffb25bc2e57ea8 R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000000
+ R13: 0000000000000000 R14: 000000000000000a R15: 00000000001c1dbe
+ FS: 0000000000000000(0000) GS:ffff921fa2200000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: ffffffffc0601a5d CR3: 000000011de4c006 CR4: 0000000000370ee0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ Call Trace:
+ <TASK>
+ ? kvfree_call_rcu+0xf0/0x3a0
+ ? kthread+0xf3/0x120
+ ? kthread_complete_and_exit+0x20/0x20
+ ? ret_from_fork+0x1f/0x30
+ </TASK>
+ Modules linked in: rfkill sunrpc ... [last unloaded: torture]
+ CR2: ffffffffc0601a87
+ ---[ end trace 0000000000000000 ]---
+
+Fixes: e6e78b004fa7 ("rcuperf: Add kfree_rcu() performance Tests")
+Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
+Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/rcuscale.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c
+index dd25d306559a5..602f0958e4362 100644
+--- a/kernel/rcu/rcuscale.c
++++ b/kernel/rcu/rcuscale.c
+@@ -797,6 +797,11 @@ rcu_scale_cleanup(void)
+ if (gp_exp && gp_async)
+ SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!");
+
++ if (kfree_rcu_test) {
++ kfree_scale_cleanup();
++ return;
++ }
++
+ if (torture_cleanup_begin())
+ return;
+ if (!cur_ops) {
+--
+2.39.2
+
--- /dev/null
+From 9fa45077e5c03b52da2db0e48b15a412fc72cbb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Apr 2023 11:11:29 -0700
+Subject: rcu-tasks: Stop rcu_tasks_invoke_cbs() from using never-onlined CPUs
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit 401b0de3ae4fa49d1014c8941e26d9a25f37e7cf ]
+
+The rcu_tasks_invoke_cbs() function relies on queue_work_on() to silently
+fall back to WORK_CPU_UNBOUND when the specified CPU is offline. However,
+the queue_work_on() function's silent fallback mechanism relies on that
+CPU having been online at some time in the past. When queue_work_on()
+is passed a CPU that has never been online, workqueue lockups ensue,
+which can be bad for your kernel's general health and well-being.
+
+This commit therefore checks whether a given CPU has ever been online,
+and, if not substitutes WORK_CPU_UNBOUND in the subsequent call to
+queue_work_on(). Why not simply omit the queue_work_on() call entirely?
+Because this function is flooding callback-invocation notifications
+to all CPUs, and must deal with possibilities that include a sparse
+cpu_possible_mask.
+
+This commit also moves the setting of the rcu_data structure's
+->beenonline field to rcu_cpu_starting(), which executes on the
+incoming CPU before that CPU has ever enabled interrupts. This ensures
+that the required workqueues are present. In addition, because the
+incoming CPU has not yet enabled its interrupts, there cannot yet have
+been any softirq handlers running on this CPU, which means that the
+WARN_ON_ONCE(!rdp->beenonline) within the RCU_SOFTIRQ handler cannot
+have triggered yet.
+
+Fixes: d363f833c6d88 ("rcu-tasks: Use workqueues for multiple rcu_tasks_invoke_cbs() invocations")
+Reported-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/rcu.h | 6 ++++++
+ kernel/rcu/tasks.h | 7 +++++--
+ kernel/rcu/tree.c | 12 +++++++++++-
+ 3 files changed, 22 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h
+index 115616ac3bfa6..2d7e85dbf6734 100644
+--- a/kernel/rcu/rcu.h
++++ b/kernel/rcu/rcu.h
+@@ -603,4 +603,10 @@ void show_rcu_tasks_trace_gp_kthread(void);
+ static inline void show_rcu_tasks_trace_gp_kthread(void) {}
+ #endif
+
++#ifdef CONFIG_TINY_RCU
++static inline bool rcu_cpu_beenfullyonline(int cpu) { return true; }
++#else
++bool rcu_cpu_beenfullyonline(int cpu);
++#endif
++
+ #endif /* __LINUX_RCU_H */
+diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
+index bfb5e1549f2b2..dfa6ff2eb32f2 100644
+--- a/kernel/rcu/tasks.h
++++ b/kernel/rcu/tasks.h
+@@ -455,6 +455,7 @@ static void rcu_tasks_invoke_cbs(struct rcu_tasks *rtp, struct rcu_tasks_percpu
+ {
+ int cpu;
+ int cpunext;
++ int cpuwq;
+ unsigned long flags;
+ int len;
+ struct rcu_head *rhp;
+@@ -465,11 +466,13 @@ static void rcu_tasks_invoke_cbs(struct rcu_tasks *rtp, struct rcu_tasks_percpu
+ cpunext = cpu * 2 + 1;
+ if (cpunext < smp_load_acquire(&rtp->percpu_dequeue_lim)) {
+ rtpcp_next = per_cpu_ptr(rtp->rtpcpu, cpunext);
+- queue_work_on(cpunext, system_wq, &rtpcp_next->rtp_work);
++ cpuwq = rcu_cpu_beenfullyonline(cpunext) ? cpunext : WORK_CPU_UNBOUND;
++ queue_work_on(cpuwq, system_wq, &rtpcp_next->rtp_work);
+ cpunext++;
+ if (cpunext < smp_load_acquire(&rtp->percpu_dequeue_lim)) {
+ rtpcp_next = per_cpu_ptr(rtp->rtpcpu, cpunext);
+- queue_work_on(cpunext, system_wq, &rtpcp_next->rtp_work);
++ cpuwq = rcu_cpu_beenfullyonline(cpunext) ? cpunext : WORK_CPU_UNBOUND;
++ queue_work_on(cpuwq, system_wq, &rtpcp_next->rtp_work);
+ }
+ }
+
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index 954a91fec912c..be490f55cb834 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -4279,7 +4279,6 @@ int rcutree_prepare_cpu(unsigned int cpu)
+ */
+ rnp = rdp->mynode;
+ raw_spin_lock_rcu_node(rnp); /* irqs already disabled. */
+- rdp->beenonline = true; /* We have now been online. */
+ rdp->gp_seq = READ_ONCE(rnp->gp_seq);
+ rdp->gp_seq_needed = rdp->gp_seq;
+ rdp->cpu_no_qs.b.norm = true;
+@@ -4306,6 +4305,16 @@ static void rcutree_affinity_setting(unsigned int cpu, int outgoing)
+ rcu_boost_kthread_setaffinity(rdp->mynode, outgoing);
+ }
+
++/*
++ * Has the specified (known valid) CPU ever been fully online?
++ */
++bool rcu_cpu_beenfullyonline(int cpu)
++{
++ struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu);
++
++ return smp_load_acquire(&rdp->beenonline);
++}
++
+ /*
+ * Near the end of the CPU-online process. Pretty much all services
+ * enabled, and the CPU is now very much alive.
+@@ -4409,6 +4418,7 @@ void rcu_cpu_starting(unsigned int cpu)
+ raw_spin_unlock_rcu_node(rnp);
+ }
+ arch_spin_unlock(&rcu_state.ofl_lock);
++ smp_store_release(&rdp->beenonline, true);
+ smp_mb(); /* Ensure RCU read-side usage follows above initialization. */
+ }
+
+--
+2.39.2
+
--- /dev/null
+From bc5610e4c5addbe8b99b9beac89c3636d36d0e3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 12:08:54 -0800
+Subject: rcuscale: Move shutdown from wait_event() to wait_event_idle()
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit ef1ef3d47677dc191b88650a9f7f91413452cc1b ]
+
+The rcu_scale_shutdown() and kfree_scale_shutdown() kthreads/functions
+use wait_event() to wait for the rcuscale test to complete. However,
+each updater thread in such a test waits for at least 100 grace periods.
+If each grace period takes more than 1.2 seconds, which is long, but
+not insanely so, this can trigger the hung-task timeout.
+
+This commit therefore replaces those wait_event() calls with calls to
+wait_event_idle(), which do not trigger the hung-task timeout.
+
+Reported-by: kernel test robot <yujie.liu@intel.com>
+Reported-by: Liam Howlett <liam.howlett@oracle.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Tested-by: Yujie Liu <yujie.liu@intel.com>
+Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
+Stable-dep-of: 23fc8df26dea ("rcu/rcuscale: Stop kfree_scale_thread thread(s) after unloading rcuscale")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/rcuscale.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c
+index 91fb5905a008f..4120f94030c3c 100644
+--- a/kernel/rcu/rcuscale.c
++++ b/kernel/rcu/rcuscale.c
+@@ -631,8 +631,7 @@ static int compute_real(int n)
+ static int
+ rcu_scale_shutdown(void *arg)
+ {
+- wait_event(shutdown_wq,
+- atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters);
++ wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters);
+ smp_mb(); /* Wake before output. */
+ rcu_scale_cleanup();
+ kernel_power_off();
+@@ -771,8 +770,8 @@ kfree_scale_cleanup(void)
+ static int
+ kfree_scale_shutdown(void *arg)
+ {
+- wait_event(shutdown_wq,
+- atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads);
++ wait_event_idle(shutdown_wq,
++ atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads);
+
+ smp_mb(); /* Wake before output. */
+
+--
+2.39.2
+
--- /dev/null
+From 0466365926abdf43ed08cbc5a7ef6dfe721951fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Mar 2023 16:40:08 -0700
+Subject: rcutorture: Correct name of use_softirq module parameter
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit b409afe0268faeb77267f028ea85f2d93438fced ]
+
+The BUSTED-BOOST and TREE03 scenarios specify a mythical tree.use_softirq
+module parameter, which means a failure to get full test coverage. This
+commit therefore corrects the name to rcutree.use_softirq.
+
+Fixes: e2b949d54392 ("rcutorture: Make TREE03 use real-time tree.use_softirq setting")
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot | 2 +-
+ tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot b/tools/testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot
+index f57720c52c0f9..84f6bb98ce993 100644
+--- a/tools/testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot
++++ b/tools/testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot
+@@ -5,4 +5,4 @@ rcutree.gp_init_delay=3
+ rcutree.gp_cleanup_delay=3
+ rcutree.kthread_prio=2
+ threadirqs
+-tree.use_softirq=0
++rcutree.use_softirq=0
+diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot b/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot
+index 64f864f1f361f..8e50bfd4b710d 100644
+--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot
++++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot
+@@ -4,4 +4,4 @@ rcutree.gp_init_delay=3
+ rcutree.gp_cleanup_delay=3
+ rcutree.kthread_prio=2
+ threadirqs
+-tree.use_softirq=0
++rcutree.use_softirq=0
+--
+2.39.2
+
--- /dev/null
+From d25fdc0d481f7fcf93861e6bfe4f7a644dc550bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 04:01:39 -0700
+Subject: RDMA/bnxt_re: Avoid calling wake_up threads from spin_lock context
+
+From: Kashyap Desai <kashyap.desai@broadcom.com>
+
+[ Upstream commit 3099bcdc19b701f732f638ee45679858c08559bb ]
+
+bnxt_qplib_service_creq can be called from interrupt or tasklet or
+process context. So the function take irq variant of spin_lock.
+But when wake_up is invoked with the lock held, it is putting the
+calling context to sleep.
+
+[exception RIP: __wake_up_common+190]
+RIP: ffffffffb7539d7e RSP: ffffa73300207ad8 RFLAGS: 00000083
+RAX: 0000000000000001 RBX: ffff91fa295f69b8 RCX: dead000000000200
+RDX: ffffa733344af940 RSI: ffffa73336527940 RDI: ffffa73336527940
+RBP: 000000000000001c R8: 0000000000000002 R9: 00000000000299c0
+R10: 0000017230de82c5 R11: 0000000000000002 R12: ffffa73300207b28
+R13: 0000000000000000 R14: ffffa733341bf928 R15: 0000000000000000
+ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
+
+Call the wakeup after releasing the lock.
+
+Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver")
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://lore.kernel.org/r/1686308514-11996-3-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+index 3d76fa71641a4..75e0c42f6f424 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -299,7 +299,8 @@ static int bnxt_qplib_process_func_event(struct bnxt_qplib_rcfw *rcfw,
+ }
+
+ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
+- struct creq_qp_event *qp_event)
++ struct creq_qp_event *qp_event,
++ u32 *num_wait)
+ {
+ struct creq_qp_error_notification *err_event;
+ struct bnxt_qplib_hwq *hwq = &rcfw->cmdq.hwq;
+@@ -308,6 +309,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
+ u16 cbit, blocked = 0;
+ struct pci_dev *pdev;
+ unsigned long flags;
++ u32 wait_cmds = 0;
+ __le16 mcookie;
+ u16 cookie;
+ int rc = 0;
+@@ -367,9 +369,10 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
+ crsqe->req_size = 0;
+
+ if (!blocked)
+- wake_up(&rcfw->cmdq.waitq);
++ wait_cmds++;
+ spin_unlock_irqrestore(&hwq->lock, flags);
+ }
++ *num_wait += wait_cmds;
+ return rc;
+ }
+
+@@ -383,6 +386,7 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t)
+ struct creq_base *creqe;
+ u32 sw_cons, raw_cons;
+ unsigned long flags;
++ u32 num_wakeup = 0;
+
+ /* Service the CREQ until budget is over */
+ spin_lock_irqsave(&hwq->lock, flags);
+@@ -401,7 +405,8 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t)
+ switch (type) {
+ case CREQ_BASE_TYPE_QP_EVENT:
+ bnxt_qplib_process_qp_event
+- (rcfw, (struct creq_qp_event *)creqe);
++ (rcfw, (struct creq_qp_event *)creqe,
++ &num_wakeup);
+ creq->stats.creq_qp_event_processed++;
+ break;
+ case CREQ_BASE_TYPE_FUNC_EVENT:
+@@ -429,6 +434,8 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t)
+ rcfw->res->cctx, true);
+ }
+ spin_unlock_irqrestore(&hwq->lock, flags);
++ if (num_wakeup)
++ wake_up_nr(&rcfw->cmdq.waitq, num_wakeup);
+ }
+
+ static irqreturn_t bnxt_qplib_creq_irq(int irq, void *dev_instance)
+--
+2.39.2
+
--- /dev/null
+From 87eb45709b1425895f12cad10f52193948a114b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 23:48:11 -0700
+Subject: RDMA/bnxt_re: Disable/kill tasklet only if it is enabled
+
+From: Selvin Xavier <selvin.xavier@broadcom.com>
+
+[ Upstream commit ab112ee7899d6171da5acd77a7ed7ae103f488de ]
+
+When the ulp hook to start the IRQ fails because the rings are not
+available, tasklets are not enabled. In this case when the driver is
+unloaded, driver calls CREQ tasklet_kill. This causes an indefinite hang
+as the tasklet is not enabled.
+
+Driver shouldn't call tasklet_kill if it is not enabled. So using the
+creq->requested and nq->requested flags to identify if both tasklets/irqs
+are registered. Checking this flag while scheduling the tasklet from
+ISR. Also, added a cleanup for disabling tasklet, in case request_irq
+fails during start_irq.
+
+Check for return value for bnxt_qplib_rcfw_start_irq and in case the
+bnxt_qplib_rcfw_start_irq fails, return bnxt_re_start_irq without
+attempting to start NQ IRQs.
+
+Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver")
+Link: https://lore.kernel.org/r/1684478897-12247-2-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/main.c | 12 +++++++++---
+ drivers/infiniband/hw/bnxt_re/qplib_fp.c | 16 ++++++++++------
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 14 +++++++++-----
+ 3 files changed, 28 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
+index 85e36c9f8e797..a9cc65614a9ee 100644
+--- a/drivers/infiniband/hw/bnxt_re/main.c
++++ b/drivers/infiniband/hw/bnxt_re/main.c
+@@ -283,15 +283,21 @@ static void bnxt_re_start_irq(void *handle, struct bnxt_msix_entry *ent)
+ for (indx = 0; indx < rdev->num_msix; indx++)
+ rdev->en_dev->msix_entries[indx].vector = ent[indx].vector;
+
+- bnxt_qplib_rcfw_start_irq(rcfw, msix_ent[BNXT_RE_AEQ_IDX].vector,
+- false);
++ rc = bnxt_qplib_rcfw_start_irq(rcfw, msix_ent[BNXT_RE_AEQ_IDX].vector,
++ false);
++ if (rc) {
++ ibdev_warn(&rdev->ibdev, "Failed to reinit CREQ\n");
++ return;
++ }
+ for (indx = BNXT_RE_NQ_IDX ; indx < rdev->num_msix; indx++) {
+ nq = &rdev->nq[indx - 1];
+ rc = bnxt_qplib_nq_start_irq(nq, indx - 1,
+ msix_ent[indx].vector, false);
+- if (rc)
++ if (rc) {
+ ibdev_warn(&rdev->ibdev, "Failed to reinit NQ index %d\n",
+ indx - 1);
++ return;
++ }
+ }
+ }
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+index ab2cc1c67f70b..a143bd3580a27 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+@@ -405,6 +405,9 @@ static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance)
+
+ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)
+ {
++ if (!nq->requested)
++ return;
++
+ tasklet_disable(&nq->nq_tasklet);
+ /* Mask h/w interrupt */
+ bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, false);
+@@ -412,11 +415,10 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)
+ synchronize_irq(nq->msix_vec);
+ if (kill)
+ tasklet_kill(&nq->nq_tasklet);
+- if (nq->requested) {
+- irq_set_affinity_hint(nq->msix_vec, NULL);
+- free_irq(nq->msix_vec, nq);
+- nq->requested = false;
+- }
++
++ irq_set_affinity_hint(nq->msix_vec, NULL);
++ free_irq(nq->msix_vec, nq);
++ nq->requested = false;
+ }
+
+ void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)
+@@ -455,8 +457,10 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
+
+ snprintf(nq->name, sizeof(nq->name), "bnxt_qplib_nq-%d", nq_indx);
+ rc = request_irq(nq->msix_vec, bnxt_qplib_nq_irq, 0, nq->name, nq);
+- if (rc)
++ if (rc) {
++ tasklet_disable(&nq->nq_tasklet);
+ return rc;
++ }
+
+ cpumask_clear(&nq->mask);
+ cpumask_set_cpu(nq_indx, &nq->mask);
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+index 061b2895dd9b5..e28f0eb5b55d4 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -635,6 +635,10 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill)
+ struct bnxt_qplib_creq_ctx *creq;
+
+ creq = &rcfw->creq;
++
++ if (!creq->requested)
++ return;
++
+ tasklet_disable(&creq->creq_tasklet);
+ /* Mask h/w interrupts */
+ bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, false);
+@@ -643,10 +647,8 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill)
+ if (kill)
+ tasklet_kill(&creq->creq_tasklet);
+
+- if (creq->requested) {
+- free_irq(creq->msix_vec, rcfw);
+- creq->requested = false;
+- }
++ free_irq(creq->msix_vec, rcfw);
++ creq->requested = false;
+ }
+
+ void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
+@@ -692,8 +694,10 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
+ tasklet_enable(&creq->creq_tasklet);
+ rc = request_irq(creq->msix_vec, bnxt_qplib_creq_irq, 0,
+ "bnxt_qplib_creq", rcfw);
+- if (rc)
++ if (rc) {
++ tasklet_disable(&creq->creq_tasklet);
+ return rc;
++ }
+ creq->requested = true;
+
+ bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, true);
+--
+2.39.2
+
--- /dev/null
+From f496d5c8154ccc08689202f63c137670f50ed840 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 23:48:15 -0700
+Subject: RDMA/bnxt_re: Fix to remove an unnecessary log
+
+From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+
+[ Upstream commit 43774bc156614346fe5dacabc8e8c229167f2536 ]
+
+During destroy_qp, driver sets the qp handle in the existing CQEs
+belonging to the QP being destroyed to NULL. As a result, a poll_cq after
+destroy_qp can report unnecessary messages. Remove this noise from system
+logs.
+
+Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver")
+Link: https://lore.kernel.org/r/1684478897-12247-6-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_fp.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+index 640d932bec376..74d56900387a1 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+@@ -2734,11 +2734,8 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq,
+
+ qp = (struct bnxt_qplib_qp *)((unsigned long)
+ le64_to_cpu(hwcqe->qp_handle));
+- if (!qp) {
+- dev_err(&cq->hwq.pdev->dev,
+- "FP: CQ Process terminal qp is NULL\n");
++ if (!qp)
+ return -EINVAL;
+- }
+
+ /* Must block new posting of SQ and RQ */
+ qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
+--
+2.39.2
+
--- /dev/null
+From 6af147dd0fd18a29eb7cb09d24c2582cf3ca8a97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 23:48:12 -0700
+Subject: RDMA/bnxt_re: Fix to remove unnecessary return labels
+
+From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+
+[ Upstream commit 9b3ee47796f529e5bc31a355d6cb756d68a7079a ]
+
+If there is no cleanup needed then just return directly. This cleans up
+the code and improve readability.
+
+Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver")
+Link: https://lore.kernel.org/r/1684478897-12247-3-git-send-email-selvin.xavier@broadcom.com
+Reviewed-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Reviewed-by: Saravanan Vajravel <saravanan.vajravel@broadcom.com>
+Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_fp.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+index a143bd3580a27..4abe1f59b3689 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+@@ -1605,7 +1605,7 @@ static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp,
+ il_src = (void *)wqe->sg_list[indx].addr;
+ t_len += len;
+ if (t_len > qp->max_inline_data)
+- goto bad;
++ return -ENOMEM;
+ while (len) {
+ if (pull_dst) {
+ pull_dst = false;
+@@ -1629,8 +1629,6 @@ static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp,
+ }
+
+ return t_len;
+-bad:
+- return -ENOMEM;
+ }
+
+ static u32 bnxt_qplib_put_sges(struct bnxt_qplib_hwq *hwq,
+@@ -2060,7 +2058,7 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
+ hwq_attr.sginfo = &cq->sg_info;
+ rc = bnxt_qplib_alloc_init_hwq(&cq->hwq, &hwq_attr);
+ if (rc)
+- goto exit;
++ return rc;
+
+ RCFW_CMD_PREP(req, CREATE_CQ, cmd_flags);
+
+@@ -2101,7 +2099,6 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
+
+ fail:
+ bnxt_qplib_free_hwq(res, &cq->hwq);
+-exit:
+ return rc;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From a5d794166675cd76b1961e34e37cb983e8b401a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 23:48:14 -0700
+Subject: RDMA/bnxt_re: Remove a redundant check inside bnxt_re_update_gid
+
+From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+
+[ Upstream commit b989f90cef0af48aa5679b6a75476371705ec53c ]
+
+The NULL check inside bnxt_re_update_gid() always return false. If
+sgid_tbl->tbl is not allocated, then dev_init would have failed.
+
+Fixes: 5fac5b1b297f ("RDMA/bnxt_re: Add vlan tag for untagged RoCE traffic when PFC is configured")
+Link: https://lore.kernel.org/r/1684478897-12247-5-git-send-email-selvin.xavier@broadcom.com
+Reviewed-by: Saravanan Vajravel <saravanan.vajravel@broadcom.com>
+Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
+Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/main.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
+index a9cc65614a9ee..b4edcf12d0d19 100644
+--- a/drivers/infiniband/hw/bnxt_re/main.c
++++ b/drivers/infiniband/hw/bnxt_re/main.c
+@@ -1010,12 +1010,6 @@ static int bnxt_re_update_gid(struct bnxt_re_dev *rdev)
+ if (!ib_device_try_get(&rdev->ibdev))
+ return 0;
+
+- if (!sgid_tbl) {
+- ibdev_err(&rdev->ibdev, "QPLIB: SGID table not allocated");
+- rc = -EINVAL;
+- goto out;
+- }
+-
+ for (index = 0; index < sgid_tbl->active; index++) {
+ gid_idx = sgid_tbl->hw_id[index];
+
+@@ -1033,7 +1027,7 @@ static int bnxt_re_update_gid(struct bnxt_re_dev *rdev)
+ rc = bnxt_qplib_update_sgid(sgid_tbl, &gid, gid_idx,
+ rdev->qplib_res.netdev->dev_addr);
+ }
+-out:
++
+ ib_device_put(&rdev->ibdev);
+ return rc;
+ }
+--
+2.39.2
+
--- /dev/null
+From 17aa4eb9853a16754df08dff32d5e904af67f60b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 23:48:13 -0700
+Subject: RDMA/bnxt_re: Use unique names while registering interrupts
+
+From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+
+[ Upstream commit ff2e4bfd162cf66a112a81509e419805add44d64 ]
+
+bnxt_re currently uses the names "bnxt_qplib_creq" and "bnxt_qplib_nq-0"
+while registering IRQs. There is no way to distinguish the IRQs of
+different device ports when there are multiple IB devices registered.
+This could make the scenarios worse where one want to pin IRQs of a device
+port to certain CPUs.
+
+Fixed the code to use unique names which has PCI BDF information while
+registering interrupts like: "bnxt_re-nq-0@pci:0000:65:00.0" and
+"bnxt_re-creq@pci:0000:65:00.1".
+
+Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver")
+Link: https://lore.kernel.org/r/1684478897-12247-4-git-send-email-selvin.xavier@broadcom.com
+Reviewed-by: Bhargava Chenna Marreddy <bhargava.marreddy@broadcom.com>
+Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_fp.c | 12 ++++++++++--
+ drivers/infiniband/hw/bnxt_re/qplib_fp.h | 2 +-
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 15 +++++++++++++--
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 1 +
+ 4 files changed, 25 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+index 4abe1f59b3689..640d932bec376 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+@@ -418,6 +418,8 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)
+
+ irq_set_affinity_hint(nq->msix_vec, NULL);
+ free_irq(nq->msix_vec, nq);
++ kfree(nq->name);
++ nq->name = NULL;
+ nq->requested = false;
+ }
+
+@@ -444,6 +446,7 @@ void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)
+ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
+ int msix_vector, bool need_init)
+ {
++ struct bnxt_qplib_res *res = nq->res;
+ int rc;
+
+ if (nq->requested)
+@@ -455,9 +458,14 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
+ else
+ tasklet_enable(&nq->nq_tasklet);
+
+- snprintf(nq->name, sizeof(nq->name), "bnxt_qplib_nq-%d", nq_indx);
++ nq->name = kasprintf(GFP_KERNEL, "bnxt_re-nq-%d@pci:%s",
++ nq_indx, pci_name(res->pdev));
++ if (!nq->name)
++ return -ENOMEM;
+ rc = request_irq(nq->msix_vec, bnxt_qplib_nq_irq, 0, nq->name, nq);
+ if (rc) {
++ kfree(nq->name);
++ nq->name = NULL;
+ tasklet_disable(&nq->nq_tasklet);
+ return rc;
+ }
+@@ -471,7 +479,7 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
+ nq->msix_vec, nq_indx);
+ }
+ nq->requested = true;
+- bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, true);
++ bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, res->cctx, true);
+
+ return rc;
+ }
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+index 0375019525431..f859710f9a7f4 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+@@ -471,7 +471,7 @@ typedef int (*srqn_handler_t)(struct bnxt_qplib_nq *nq,
+ struct bnxt_qplib_nq {
+ struct pci_dev *pdev;
+ struct bnxt_qplib_res *res;
+- char name[32];
++ char *name;
+ struct bnxt_qplib_hwq hwq;
+ struct bnxt_qplib_nq_db nq_db;
+ u16 ring_id;
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+index e28f0eb5b55d4..9c63b8b62edfc 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -648,6 +648,8 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill)
+ tasklet_kill(&creq->creq_tasklet);
+
+ free_irq(creq->msix_vec, rcfw);
++ kfree(creq->irq_name);
++ creq->irq_name = NULL;
+ creq->requested = false;
+ }
+
+@@ -680,9 +682,11 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
+ bool need_init)
+ {
+ struct bnxt_qplib_creq_ctx *creq;
++ struct bnxt_qplib_res *res;
+ int rc;
+
+ creq = &rcfw->creq;
++ res = rcfw->res;
+
+ if (creq->requested)
+ return -EFAULT;
+@@ -692,15 +696,22 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
+ tasklet_setup(&creq->creq_tasklet, bnxt_qplib_service_creq);
+ else
+ tasklet_enable(&creq->creq_tasklet);
++
++ creq->irq_name = kasprintf(GFP_KERNEL, "bnxt_re-creq@pci:%s",
++ pci_name(res->pdev));
++ if (!creq->irq_name)
++ return -ENOMEM;
+ rc = request_irq(creq->msix_vec, bnxt_qplib_creq_irq, 0,
+- "bnxt_qplib_creq", rcfw);
++ creq->irq_name, rcfw);
+ if (rc) {
++ kfree(creq->irq_name);
++ creq->irq_name = NULL;
+ tasklet_disable(&creq->creq_tasklet);
+ return rc;
+ }
+ creq->requested = true;
+
+- bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, true);
++ bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, res->cctx, true);
+
+ return 0;
+ }
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+index 0a3d8e7da3d42..b887e7fbad9ef 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+@@ -174,6 +174,7 @@ struct bnxt_qplib_creq_ctx {
+ u16 ring_id;
+ int msix_vec;
+ bool requested; /*irq handler installed */
++ char *irq_name;
+ };
+
+ /* RCFW Communication Channels */
+--
+2.39.2
+
--- /dev/null
+From fa53a95ded4aab0754055e33b4114ace62e4765b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 04:01:38 -0700
+Subject: RDMA/bnxt_re: wraparound mbox producer index
+
+From: Kashyap Desai <kashyap.desai@broadcom.com>
+
+[ Upstream commit 0af91306e17ef3d18e5f100aa58aa787869118af ]
+
+Driver is not handling the wraparound of the mbox producer index correctly.
+Currently the wraparound happens once u32 max is reached.
+
+Bit 31 of the producer index register is special and should be set
+only once for the first command. Because the producer index overflow
+setting bit31 after a long time, FW goes to initialization sequence
+and this causes FW hang.
+
+Fix is to wraparound the mbox producer index once it reaches u16 max.
+
+Fixes: cee0c7bba486 ("RDMA/bnxt_re: Refactor command queue management code")
+Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver")
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://lore.kernel.org/r/1686308514-11996-2-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+index 9c63b8b62edfc..3d76fa71641a4 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -181,7 +181,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req,
+ } while (size > 0);
+ cmdq->seq_num++;
+
+- cmdq_prod = hwq->prod;
++ cmdq_prod = hwq->prod & 0xFFFF;
+ if (test_bit(FIRMWARE_FIRST_FLAG, &cmdq->flags)) {
+ /* The very first doorbell write
+ * is required to set this flag
+@@ -598,7 +598,7 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
+ rcfw->cmdq_depth = BNXT_QPLIB_CMDQE_MAX_CNT_8192;
+
+ sginfo.pgsize = bnxt_qplib_cmdqe_page_size(rcfw->cmdq_depth);
+- hwq_attr.depth = rcfw->cmdq_depth;
++ hwq_attr.depth = rcfw->cmdq_depth & 0x7FFFFFFF;
+ hwq_attr.stride = BNXT_QPLIB_CMDQE_UNITS;
+ hwq_attr.type = HWQ_TYPE_CTX;
+ if (bnxt_qplib_alloc_init_hwq(&cmdq->hwq, &hwq_attr)) {
+--
+2.39.2
+
--- /dev/null
+From c8f366370c4c59508d93ad49ff16186bc85f17b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 May 2023 20:16:40 +0800
+Subject: RDMA/hns: Fix hns_roce_table_get return value
+
+From: Chengchang Tang <tangchengchang@huawei.com>
+
+[ Upstream commit cf5b608fb0e369c473a8303cad6ddb386505e5b8 ]
+
+The return value of set_hem has been fixed to ENODEV, which will lead a
+diagnostic information missing.
+
+Fixes: 9a4435375cd1 ("IB/hns: Add driver files for hns RoCE driver")
+Link: https://lore.kernel.org/r/20230523121641.3132102-3-huangjunxian6@hisilicon.com
+Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index aa8a08d1c0145..f30274986c0da 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -595,11 +595,12 @@ int hns_roce_table_get(struct hns_roce_dev *hr_dev,
+ }
+
+ /* Set HEM base address(128K/page, pa) to Hardware */
+- if (hr_dev->hw->set_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT)) {
++ ret = hr_dev->hw->set_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT);
++ if (ret) {
+ hns_roce_free_hem(hr_dev, table->hem[i]);
+ table->hem[i] = NULL;
+- ret = -ENODEV;
+- dev_err(dev, "set HEM base address to HW failed.\n");
++ dev_err(dev, "set HEM base address to HW failed, ret = %d.\n",
++ ret);
+ goto out;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 54777b69442ab15514128f6cf556a273108c7a9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 May 2023 13:18:45 +0200
+Subject: RDMA/irdma: avoid fortify-string warning in irdma_clr_wqes
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit b002760f877c0d91ecd3c78565b52f4bbac379dd ]
+
+Commit df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3") triggers a
+warning for fortified memset():
+
+In function 'fortify_memset_chk',
+ inlined from 'irdma_clr_wqes' at drivers/infiniband/hw/irdma/uk.c:103:4:
+include/linux/fortify-string.h:493:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning]
+ 493 | __write_overflow_field(p_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The problem here isthat the inner array only has four 8-byte elements, so
+clearing 4096 bytes overflows that. As this structure is part of an outer
+array, change the code to pass a pointer to the irdma_qp_quanta instead,
+and change the size argument for readability, matching the comment above
+it.
+
+Fixes: 551c46edc769 ("RDMA/irdma: Add user/kernel shared libraries")
+Link: https://lore.kernel.org/r/20230523111859.2197825-1-arnd@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/uk.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c
+index 16183e894da77..dd428d915c175 100644
+--- a/drivers/infiniband/hw/irdma/uk.c
++++ b/drivers/infiniband/hw/irdma/uk.c
+@@ -93,16 +93,18 @@ static int irdma_nop_1(struct irdma_qp_uk *qp)
+ */
+ void irdma_clr_wqes(struct irdma_qp_uk *qp, u32 qp_wqe_idx)
+ {
+- __le64 *wqe;
++ struct irdma_qp_quanta *sq;
+ u32 wqe_idx;
+
+ if (!(qp_wqe_idx & 0x7F)) {
+ wqe_idx = (qp_wqe_idx + 128) % qp->sq_ring.size;
+- wqe = qp->sq_base[wqe_idx].elem;
++ sq = qp->sq_base + wqe_idx;
+ if (wqe_idx)
+- memset(wqe, qp->swqe_polarity ? 0 : 0xFF, 0x1000);
++ memset(sq, qp->swqe_polarity ? 0 : 0xFF,
++ 128 * sizeof(*sq));
+ else
+- memset(wqe, qp->swqe_polarity ? 0xFF : 0, 0x1000);
++ memset(sq, qp->swqe_polarity ? 0xFF : 0,
++ 128 * sizeof(*sq));
+ }
+ }
+
+--
+2.39.2
+
--- /dev/null
+From f388953a051cdf1ee275cddd121039c740e229da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 17:13:32 -0500
+Subject: RDMA/rxe: Fix access checks in rxe_check_bind_mw
+
+From: Bob Pearson <rpearsonhpe@gmail.com>
+
+[ Upstream commit 425e1c9018fdf25cb4531606cc92d9d01a55534f ]
+
+The subroutine rxe_check_bind_mw() in rxe_mw.c performs checks on the mw
+access flags before they are set so they always succeed. This patch
+instead checks the access flags passed in the send wqe.
+
+Fixes: 32a577b4c3a9 ("RDMA/rxe: Add support for bind MW work requests")
+Link: https://lore.kernel.org/r/20230530221334.89432-4-rpearsonhpe@gmail.com
+Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_mw.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c
+index afa5ce1a71166..a7ec57ab8fadd 100644
+--- a/drivers/infiniband/sw/rxe/rxe_mw.c
++++ b/drivers/infiniband/sw/rxe/rxe_mw.c
+@@ -48,7 +48,7 @@ int rxe_dealloc_mw(struct ib_mw *ibmw)
+ }
+
+ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
+- struct rxe_mw *mw, struct rxe_mr *mr)
++ struct rxe_mw *mw, struct rxe_mr *mr, int access)
+ {
+ if (mw->ibmw.type == IB_MW_TYPE_1) {
+ if (unlikely(mw->state != RXE_MW_STATE_VALID)) {
+@@ -58,7 +58,7 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
+ }
+
+ /* o10-36.2.2 */
+- if (unlikely((mw->access & IB_ZERO_BASED))) {
++ if (unlikely((access & IB_ZERO_BASED))) {
+ rxe_dbg_mw(mw, "attempt to bind a zero based type 1 MW\n");
+ return -EINVAL;
+ }
+@@ -104,7 +104,7 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
+ }
+
+ /* C10-74 */
+- if (unlikely((mw->access &
++ if (unlikely((access &
+ (IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_ATOMIC)) &&
+ !(mr->access & IB_ACCESS_LOCAL_WRITE))) {
+ rxe_dbg_mw(mw,
+@@ -113,7 +113,7 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
+ }
+
+ /* C10-75 */
+- if (mw->access & IB_ZERO_BASED) {
++ if (access & IB_ZERO_BASED) {
+ if (unlikely(wqe->wr.wr.mw.length > mr->ibmr.length)) {
+ rxe_dbg_mw(mw,
+ "attempt to bind a ZB MW outside of the MR\n");
+@@ -133,12 +133,12 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
+ }
+
+ static void rxe_do_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
+- struct rxe_mw *mw, struct rxe_mr *mr)
++ struct rxe_mw *mw, struct rxe_mr *mr, int access)
+ {
+ u32 key = wqe->wr.wr.mw.rkey & 0xff;
+
+ mw->rkey = (mw->rkey & ~0xff) | key;
+- mw->access = wqe->wr.wr.mw.access;
++ mw->access = access;
+ mw->state = RXE_MW_STATE_VALID;
+ mw->addr = wqe->wr.wr.mw.addr;
+ mw->length = wqe->wr.wr.mw.length;
+@@ -169,6 +169,7 @@ int rxe_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
+ struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
+ u32 mw_rkey = wqe->wr.wr.mw.mw_rkey;
+ u32 mr_lkey = wqe->wr.wr.mw.mr_lkey;
++ int access = wqe->wr.wr.mw.access;
+
+ mw = rxe_pool_get_index(&rxe->mw_pool, mw_rkey >> 8);
+ if (unlikely(!mw)) {
+@@ -198,11 +199,11 @@ int rxe_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
+
+ spin_lock_bh(&mw->lock);
+
+- ret = rxe_check_bind_mw(qp, wqe, mw, mr);
++ ret = rxe_check_bind_mw(qp, wqe, mw, mr, access);
+ if (ret)
+ goto err_unlock;
+
+- rxe_do_bind_mw(qp, wqe, mw, mr);
++ rxe_do_bind_mw(qp, wqe, mw, mr, access);
+ err_unlock:
+ spin_unlock_bh(&mw->lock);
+ err_drop_mr:
+--
+2.39.2
+
--- /dev/null
+From 3310756fbcf07372212d3cb4f3d47caf754dd681 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 May 2023 13:13:58 +0200
+Subject: regulator: core: Fix more error checking for debugfs_create_dir()
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 2715bb11cfff964aa33946847f9527cfbd4874f5 ]
+
+In case of failure, debugfs_create_dir() does not return NULL, but an
+error pointer. Most incorrect error checks were fixed, but the one in
+create_regulator() was forgotten.
+
+Fix the remaining error check.
+
+Fixes: 2bf1c45be3b8f3a3 ("regulator: Fix error checking for debugfs_create_dir")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/ee980a108b5854dd8ce3630f8f673e784e057d17.1685013051.git.geert+renesas@glider.be
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 323e8187a98ff..2997a26a9ce3b 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1918,7 +1918,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
+
+ if (err != -EEXIST)
+ regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs);
+- if (!regulator->debugfs) {
++ if (IS_ERR(regulator->debugfs)) {
+ rdev_dbg(rdev, "Failed to create debugfs directory\n");
+ } else {
+ debugfs_create_u32("uA_load", 0444, regulator->debugfs,
+--
+2.39.2
+
--- /dev/null
+From 1a722eaee4bec612f1fa819f156619d662dd1096 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 May 2023 13:13:59 +0200
+Subject: regulator: core: Streamline debugfs operations
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 08880713ceec023dd94d634f1e8902728c385939 ]
+
+If CONFIG_DEBUG_FS is not set:
+
+ regulator: Failed to create debugfs directory
+ ...
+ regulator-dummy: Failed to create debugfs directory
+
+As per the comments for debugfs_create_dir(), errors returned by this
+function should be expected, and ignored:
+
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ *
+ * NOTE: it's expected that most callers should _ignore_ the errors returned
+ * by this function. Other debugfs functions handle the fact that the "dentry"
+ * passed to them could be an error and they don't crash in that case.
+ * Drivers should generally work fine even if debugfs fails to init anyway.
+
+Adhere to the debugfs spirit, and streamline all operations by:
+ 1. Demoting the importance of the printed error messages to debug
+ level, like is already done in create_regulator(),
+ 2. Further ignoring any returned errors, as by design, all debugfs
+ functions are no-ops when passed an error pointer.
+
+Fixes: 2bf1c45be3b8f3a3 ("regulator: Fix error checking for debugfs_create_dir")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/2f8bb6e113359ddfab7b59e4d4274bd4c06d6d0a.1685013051.git.geert+renesas@glider.be
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 30 +++++++++++++-----------------
+ 1 file changed, 13 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 2997a26a9ce3b..443be7b6e31df 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1918,19 +1918,17 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
+
+ if (err != -EEXIST)
+ regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs);
+- if (IS_ERR(regulator->debugfs)) {
++ if (IS_ERR(regulator->debugfs))
+ rdev_dbg(rdev, "Failed to create debugfs directory\n");
+- } else {
+- debugfs_create_u32("uA_load", 0444, regulator->debugfs,
+- ®ulator->uA_load);
+- debugfs_create_u32("min_uV", 0444, regulator->debugfs,
+- ®ulator->voltage[PM_SUSPEND_ON].min_uV);
+- debugfs_create_u32("max_uV", 0444, regulator->debugfs,
+- ®ulator->voltage[PM_SUSPEND_ON].max_uV);
+- debugfs_create_file("constraint_flags", 0444,
+- regulator->debugfs, regulator,
+- &constraint_flags_fops);
+- }
++
++ debugfs_create_u32("uA_load", 0444, regulator->debugfs,
++ ®ulator->uA_load);
++ debugfs_create_u32("min_uV", 0444, regulator->debugfs,
++ ®ulator->voltage[PM_SUSPEND_ON].min_uV);
++ debugfs_create_u32("max_uV", 0444, regulator->debugfs,
++ ®ulator->voltage[PM_SUSPEND_ON].max_uV);
++ debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
++ regulator, &constraint_flags_fops);
+
+ /*
+ * Check now if the regulator is an always on regulator - if
+@@ -5263,10 +5261,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
+ }
+
+ rdev->debugfs = debugfs_create_dir(rname, debugfs_root);
+- if (IS_ERR(rdev->debugfs)) {
+- rdev_warn(rdev, "Failed to create debugfs directory\n");
+- return;
+- }
++ if (IS_ERR(rdev->debugfs))
++ rdev_dbg(rdev, "Failed to create debugfs directory\n");
+
+ debugfs_create_u32("use_count", 0444, rdev->debugfs,
+ &rdev->use_count);
+@@ -6186,7 +6182,7 @@ static int __init regulator_init(void)
+
+ debugfs_root = debugfs_create_dir("regulator", NULL);
+ if (IS_ERR(debugfs_root))
+- pr_warn("regulator: Failed to create debugfs directory\n");
++ pr_debug("regulator: Failed to create debugfs directory\n");
+
+ #ifdef CONFIG_DEBUG_FS
+ debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
+--
+2.39.2
+
--- /dev/null
+From 64e9effc9d78a006a5cec60822b8b957ab056b65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Apr 2023 09:42:26 +0800
+Subject: riscv: uprobes: Restore thread.bad_cause
+
+From: Tiezhu Yang <yangtiezhu@loongson.cn>
+
+[ Upstream commit 58b1294dd1d65bb62f08dddbf418f954210c2057 ]
+
+thread.bad_cause is saved in arch_uprobe_pre_xol(), it should be restored
+in arch_uprobe_{post,abort}_xol() accordingly, otherwise the save operation
+is meaningless, this change is similar with x86 and powerpc.
+
+Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Reviewed-by: Guo Ren <guoren@kernel.org>
+Fixes: 74784081aac8 ("riscv: Add uprobes supported")
+Link: https://lore.kernel.org/r/1682214146-3756-1-git-send-email-yangtiezhu@loongson.cn
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/probes/uprobes.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/riscv/kernel/probes/uprobes.c b/arch/riscv/kernel/probes/uprobes.c
+index c976a21cd4bd5..194f166b2cc40 100644
+--- a/arch/riscv/kernel/probes/uprobes.c
++++ b/arch/riscv/kernel/probes/uprobes.c
+@@ -67,6 +67,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+ struct uprobe_task *utask = current->utask;
+
+ WARN_ON_ONCE(current->thread.bad_cause != UPROBE_TRAP_NR);
++ current->thread.bad_cause = utask->autask.saved_cause;
+
+ instruction_pointer_set(regs, utask->vaddr + auprobe->insn_size);
+
+@@ -102,6 +103,7 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+ {
+ struct uprobe_task *utask = current->utask;
+
++ current->thread.bad_cause = utask->autask.saved_cause;
+ /*
+ * Task has received a fatal signal, so reset back to probbed
+ * address.
+--
+2.39.2
+
--- /dev/null
+From 1b4c9d36e3387e079e7ed3dcf5a86366f122d55d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Jun 2023 13:51:08 +0300
+Subject: rtnetlink: extend RTEXT_FILTER_SKIP_STATS to IFLA_VF_INFO
+
+From: Edwin Peer <edwin.peer@broadcom.com>
+
+[ Upstream commit fa0e21fa44438a0e856d42224bfa24641d37b979 ]
+
+This filter already exists for excluding IPv6 SNMP stats. Extend its
+definition to also exclude IFLA_VF_INFO stats in RTM_GETLINK.
+
+This patch constitutes a partial fix for a netlink attribute nesting
+overflow bug in IFLA_VFINFO_LIST. By excluding the stats when the
+requester doesn't need them, the truncation of the VF list is avoided.
+
+While it was technically only the stats added in commit c5a9f6f0ab40
+("net/core: Add drop counters to VF statistics") breaking the camel's
+back, the appreciable size of the stats data should never have been
+included without due consideration for the maximum number of VFs
+supported by PCI.
+
+Fixes: 3b766cd83232 ("net/core: Add reading VF statistics through the PF netdevice")
+Fixes: c5a9f6f0ab40 ("net/core: Add drop counters to VF statistics")
+Signed-off-by: Edwin Peer <edwin.peer@broadcom.com>
+Cc: Edwin Peer <espeer@gmail.com>
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Link: https://lore.kernel.org/r/20230611105108.122586-1-gal@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/rtnetlink.c | 96 +++++++++++++++++++++++---------------------
+ 1 file changed, 51 insertions(+), 45 deletions(-)
+
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index f235cc6832767..bbecc31a2703f 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -958,24 +958,27 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
+ nla_total_size(sizeof(struct ifla_vf_rate)) +
+ nla_total_size(sizeof(struct ifla_vf_link_state)) +
+ nla_total_size(sizeof(struct ifla_vf_rss_query_en)) +
+- nla_total_size(0) + /* nest IFLA_VF_STATS */
+- /* IFLA_VF_STATS_RX_PACKETS */
+- nla_total_size_64bit(sizeof(__u64)) +
+- /* IFLA_VF_STATS_TX_PACKETS */
+- nla_total_size_64bit(sizeof(__u64)) +
+- /* IFLA_VF_STATS_RX_BYTES */
+- nla_total_size_64bit(sizeof(__u64)) +
+- /* IFLA_VF_STATS_TX_BYTES */
+- nla_total_size_64bit(sizeof(__u64)) +
+- /* IFLA_VF_STATS_BROADCAST */
+- nla_total_size_64bit(sizeof(__u64)) +
+- /* IFLA_VF_STATS_MULTICAST */
+- nla_total_size_64bit(sizeof(__u64)) +
+- /* IFLA_VF_STATS_RX_DROPPED */
+- nla_total_size_64bit(sizeof(__u64)) +
+- /* IFLA_VF_STATS_TX_DROPPED */
+- nla_total_size_64bit(sizeof(__u64)) +
+ nla_total_size(sizeof(struct ifla_vf_trust)));
++ if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) {
++ size += num_vfs *
++ (nla_total_size(0) + /* nest IFLA_VF_STATS */
++ /* IFLA_VF_STATS_RX_PACKETS */
++ nla_total_size_64bit(sizeof(__u64)) +
++ /* IFLA_VF_STATS_TX_PACKETS */
++ nla_total_size_64bit(sizeof(__u64)) +
++ /* IFLA_VF_STATS_RX_BYTES */
++ nla_total_size_64bit(sizeof(__u64)) +
++ /* IFLA_VF_STATS_TX_BYTES */
++ nla_total_size_64bit(sizeof(__u64)) +
++ /* IFLA_VF_STATS_BROADCAST */
++ nla_total_size_64bit(sizeof(__u64)) +
++ /* IFLA_VF_STATS_MULTICAST */
++ nla_total_size_64bit(sizeof(__u64)) +
++ /* IFLA_VF_STATS_RX_DROPPED */
++ nla_total_size_64bit(sizeof(__u64)) +
++ /* IFLA_VF_STATS_TX_DROPPED */
++ nla_total_size_64bit(sizeof(__u64)));
++ }
+ return size;
+ } else
+ return 0;
+@@ -1267,7 +1270,8 @@ static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb,
+ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
+ struct net_device *dev,
+ int vfs_num,
+- struct nlattr *vfinfo)
++ struct nlattr *vfinfo,
++ u32 ext_filter_mask)
+ {
+ struct ifla_vf_rss_query_en vf_rss_query_en;
+ struct nlattr *vf, *vfstats, *vfvlanlist;
+@@ -1373,33 +1377,35 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
+ goto nla_put_vf_failure;
+ }
+ nla_nest_end(skb, vfvlanlist);
+- memset(&vf_stats, 0, sizeof(vf_stats));
+- if (dev->netdev_ops->ndo_get_vf_stats)
+- dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
+- &vf_stats);
+- vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS);
+- if (!vfstats)
+- goto nla_put_vf_failure;
+- if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
+- vf_stats.rx_packets, IFLA_VF_STATS_PAD) ||
+- nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS,
+- vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
+- nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
+- vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
+- nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
+- vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
+- nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
+- vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
+- nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
+- vf_stats.multicast, IFLA_VF_STATS_PAD) ||
+- nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED,
+- vf_stats.rx_dropped, IFLA_VF_STATS_PAD) ||
+- nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED,
+- vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) {
+- nla_nest_cancel(skb, vfstats);
+- goto nla_put_vf_failure;
++ if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) {
++ memset(&vf_stats, 0, sizeof(vf_stats));
++ if (dev->netdev_ops->ndo_get_vf_stats)
++ dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
++ &vf_stats);
++ vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS);
++ if (!vfstats)
++ goto nla_put_vf_failure;
++ if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
++ vf_stats.rx_packets, IFLA_VF_STATS_PAD) ||
++ nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS,
++ vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
++ nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
++ vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
++ nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
++ vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
++ nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
++ vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
++ nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
++ vf_stats.multicast, IFLA_VF_STATS_PAD) ||
++ nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED,
++ vf_stats.rx_dropped, IFLA_VF_STATS_PAD) ||
++ nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED,
++ vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) {
++ nla_nest_cancel(skb, vfstats);
++ goto nla_put_vf_failure;
++ }
++ nla_nest_end(skb, vfstats);
+ }
+- nla_nest_end(skb, vfstats);
+ nla_nest_end(skb, vf);
+ return 0;
+
+@@ -1432,7 +1438,7 @@ static noinline_for_stack int rtnl_fill_vf(struct sk_buff *skb,
+ return -EMSGSIZE;
+
+ for (i = 0; i < num_vfs; i++) {
+- if (rtnl_fill_vfinfo(skb, dev, i, vfinfo))
++ if (rtnl_fill_vfinfo(skb, dev, i, vfinfo, ext_filter_mask))
+ return -EMSGSIZE;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From d709fed6e81e32e7878e7b4aab454f142966f7f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 May 2023 16:50:58 +0800
+Subject: samples/bpf: Fix buffer overflow in tcp_basertt
+
+From: Pengcheng Yang <yangpc@wangsu.com>
+
+[ Upstream commit f4dea9689c5fea3d07170c2cb0703e216f1a0922 ]
+
+Using sizeof(nv) or strlen(nv)+1 is correct.
+
+Fixes: c890063e4404 ("bpf: sample BPF_SOCKET_OPS_BASE_RTT program")
+Signed-off-by: Pengcheng Yang <yangpc@wangsu.com>
+Link: https://lore.kernel.org/r/1683276658-2860-1-git-send-email-yangpc@wangsu.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/bpf/tcp_basertt_kern.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/samples/bpf/tcp_basertt_kern.c b/samples/bpf/tcp_basertt_kern.c
+index 8dfe09a92feca..822b0742b8154 100644
+--- a/samples/bpf/tcp_basertt_kern.c
++++ b/samples/bpf/tcp_basertt_kern.c
+@@ -47,7 +47,7 @@ int bpf_basertt(struct bpf_sock_ops *skops)
+ case BPF_SOCK_OPS_BASE_RTT:
+ n = bpf_getsockopt(skops, SOL_TCP, TCP_CONGESTION,
+ cong, sizeof(cong));
+- if (!n && !__builtin_memcmp(cong, nv, sizeof(nv)+1)) {
++ if (!n && !__builtin_memcmp(cong, nv, sizeof(nv))) {
+ /* Set base_rtt to 80us */
+ rv = 80;
+ } else if (n) {
+--
+2.39.2
+
--- /dev/null
+From 9740a4c8e493738cdd065a31f77375501fd06c76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 16:30:41 +0200
+Subject: samples/bpf: xdp1 and xdp2 reduce XDPBUFSIZE to 60
+
+From: Jesper Dangaard Brouer <brouer@redhat.com>
+
+[ Upstream commit 60548b825b082cedf89b275c21c28b1e1d030e50 ]
+
+Default samples/pktgen scripts send 60 byte packets as hardware adds
+4-bytes FCS checksum, which fulfils minimum Ethernet 64 bytes frame
+size.
+
+XDP layer will not necessary have access to the 4-bytes FCS checksum.
+
+This leads to bpf_xdp_load_bytes() failing as it tries to copy 64-bytes
+from an XDP packet that only have 60-bytes available.
+
+Fixes: 772251742262 ("samples/bpf: fixup some tools to be able to support xdp multibuffer")
+Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://lore.kernel.org/bpf/168545704139.2996228.2516528552939485216.stgit@firesoul
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/bpf/xdp1_kern.c | 2 +-
+ samples/bpf/xdp2_kern.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/samples/bpf/xdp1_kern.c b/samples/bpf/xdp1_kern.c
+index 0a5c704badd00..d91f27cbcfa99 100644
+--- a/samples/bpf/xdp1_kern.c
++++ b/samples/bpf/xdp1_kern.c
+@@ -39,7 +39,7 @@ static int parse_ipv6(void *data, u64 nh_off, void *data_end)
+ return ip6h->nexthdr;
+ }
+
+-#define XDPBUFSIZE 64
++#define XDPBUFSIZE 60
+ SEC("xdp.frags")
+ int xdp_prog1(struct xdp_md *ctx)
+ {
+diff --git a/samples/bpf/xdp2_kern.c b/samples/bpf/xdp2_kern.c
+index 67804ecf7ce37..8bca674451ed1 100644
+--- a/samples/bpf/xdp2_kern.c
++++ b/samples/bpf/xdp2_kern.c
+@@ -55,7 +55,7 @@ static int parse_ipv6(void *data, u64 nh_off, void *data_end)
+ return ip6h->nexthdr;
+ }
+
+-#define XDPBUFSIZE 64
++#define XDPBUFSIZE 60
+ SEC("xdp.frags")
+ int xdp_prog1(struct xdp_md *ctx)
+ {
+--
+2.39.2
+
--- /dev/null
+From ddd6216638d030b4160e241132e052792d72cebd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 16:20:11 +0800
+Subject: sched/core: Avoid multiple calling update_rq_clock() in
+ __cfsb_csd_unthrottle()
+
+From: Hao Jia <jiahao.os@bytedance.com>
+
+[ Upstream commit ebb83d84e49b54369b0db67136a5fe1087124dcc ]
+
+After commit 8ad075c2eb1f ("sched: Async unthrottling for cfs
+bandwidth"), we may update the rq clock multiple times in the loop of
+__cfsb_csd_unthrottle().
+
+A prior (although less common) instance of this problem exists in
+unthrottle_offline_cfs_rqs().
+
+Cure both by ensuring update_rq_clock() is called before the loop and
+setting RQCF_ACT_SKIP during the loop, to supress further updates.
+The alternative would be pulling update_rq_clock() out of
+unthrottle_cfs_rq(), but that gives an even bigger mess.
+
+Fixes: 8ad075c2eb1f ("sched: Async unthrottling for cfs bandwidth")
+Reviewed-By: Ben Segall <bsegall@google.com>
+Suggested-by: Vincent Guittot <vincent.guittot@linaro.org>
+Signed-off-by: Hao Jia <jiahao.os@bytedance.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://lkml.kernel.org/r/20230613082012.49615-4-jiahao.os@bytedance.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 18 ++++++++++++++++++
+ kernel/sched/sched.h | 22 ++++++++++++++++++++++
+ 2 files changed, 40 insertions(+)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index ed89be0aa6503..853b7ef9dcafc 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -5519,6 +5519,14 @@ static void __cfsb_csd_unthrottle(void *arg)
+
+ rq_lock(rq, &rf);
+
++ /*
++ * Iterating over the list can trigger several call to
++ * update_rq_clock() in unthrottle_cfs_rq().
++ * Do it once and skip the potential next ones.
++ */
++ update_rq_clock(rq);
++ rq_clock_start_loop_update(rq);
++
+ /*
+ * Since we hold rq lock we're safe from concurrent manipulation of
+ * the CSD list. However, this RCU critical section annotates the
+@@ -5538,6 +5546,7 @@ static void __cfsb_csd_unthrottle(void *arg)
+
+ rcu_read_unlock();
+
++ rq_clock_stop_loop_update(rq);
+ rq_unlock(rq, &rf);
+ }
+
+@@ -6054,6 +6063,13 @@ static void __maybe_unused unthrottle_offline_cfs_rqs(struct rq *rq)
+
+ lockdep_assert_rq_held(rq);
+
++ /*
++ * The rq clock has already been updated in the
++ * set_rq_offline(), so we should skip updating
++ * the rq clock again in unthrottle_cfs_rq().
++ */
++ rq_clock_start_loop_update(rq);
++
+ rcu_read_lock();
+ list_for_each_entry_rcu(tg, &task_groups, list) {
+ struct cfs_rq *cfs_rq = tg->cfs_rq[cpu_of(rq)];
+@@ -6076,6 +6092,8 @@ static void __maybe_unused unthrottle_offline_cfs_rqs(struct rq *rq)
+ unthrottle_cfs_rq(cfs_rq);
+ }
+ rcu_read_unlock();
++
++ rq_clock_stop_loop_update(rq);
+ }
+
+ #else /* CONFIG_CFS_BANDWIDTH */
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index 3e8df6d31c1e3..3adac73b17ca5 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -1546,6 +1546,28 @@ static inline void rq_clock_cancel_skipupdate(struct rq *rq)
+ rq->clock_update_flags &= ~RQCF_REQ_SKIP;
+ }
+
++/*
++ * During cpu offlining and rq wide unthrottling, we can trigger
++ * an update_rq_clock() for several cfs and rt runqueues (Typically
++ * when using list_for_each_entry_*)
++ * rq_clock_start_loop_update() can be called after updating the clock
++ * once and before iterating over the list to prevent multiple update.
++ * After the iterative traversal, we need to call rq_clock_stop_loop_update()
++ * to clear RQCF_ACT_SKIP of rq->clock_update_flags.
++ */
++static inline void rq_clock_start_loop_update(struct rq *rq)
++{
++ lockdep_assert_rq_held(rq);
++ SCHED_WARN_ON(rq->clock_update_flags & RQCF_ACT_SKIP);
++ rq->clock_update_flags |= RQCF_ACT_SKIP;
++}
++
++static inline void rq_clock_stop_loop_update(struct rq *rq)
++{
++ lockdep_assert_rq_held(rq);
++ rq->clock_update_flags &= ~RQCF_ACT_SKIP;
++}
++
+ struct rq_flags {
+ unsigned long flags;
+ struct pin_cookie cookie;
+--
+2.39.2
+
--- /dev/null
+From dcddbf38f798f2924ce3094d0159cabe6c54ac43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 May 2023 22:12:55 +0800
+Subject: scsi: 3w-xxxx: Add error handling for initialization failure in
+ tw_probe()
+
+From: Yuchen Yang <u202114568@hust.edu.cn>
+
+[ Upstream commit 2e2fe5ac695a00ab03cab4db1f4d6be07168ed9d ]
+
+Smatch complains that:
+
+tw_probe() warn: missing error code 'retval'
+
+This patch adds error checking to tw_probe() to handle initialization
+failure. If tw_reset_sequence() function returns a non-zero value, the
+function will return -EINVAL to indicate initialization failure.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yuchen Yang <u202114568@hust.edu.cn>
+Link: https://lore.kernel.org/r/20230505141259.7730-1-u202114568@hust.edu.cn
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/3w-xxxx.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
+index ffdecb12d654c..9bd70e4618d52 100644
+--- a/drivers/scsi/3w-xxxx.c
++++ b/drivers/scsi/3w-xxxx.c
+@@ -2305,8 +2305,10 @@ static int tw_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
+ TW_DISABLE_INTERRUPTS(tw_dev);
+
+ /* Initialize the card */
+- if (tw_reset_sequence(tw_dev))
++ if (tw_reset_sequence(tw_dev)) {
++ retval = -EINVAL;
+ goto out_release_mem_region;
++ }
+
+ /* Set host specific parameters */
+ host->max_id = TW_MAX_UNITS;
+--
+2.39.2
+
--- /dev/null
+From 726c2f798aa329d38beb35dc042e3c2874e68cea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 May 2023 11:32:01 -0700
+Subject: scsi: lpfc: Revise NPIV ELS unsol rcv cmpl logic to drop ndlp based
+ on nlp_state
+
+From: Justin Tee <justin.tee@broadcom.com>
+
+[ Upstream commit 9914a3d033d3e1d836a43e93e9738e7dd44a096a ]
+
+When NPIV ports are zoned to devices that support both initiator and target
+mode, a remote device's initiated PRLI results in unintended final kref
+clean up of the device's ndlp structure. This disrupts NPIV ports'
+discovery for target devices that support both initiator and target mode.
+
+Modify the NPIV lpfc_drop_node clause such that we allow the ndlp to live
+so long as it was in NLP_STE_PLOGI_ISSUE, NLP_STE_REG_LOGIN_ISSUE, or
+NLP_STE_PRLI_ISSUE nlp_state. This allows lpfc's issued PRLI completion
+routine to determine if the final kref clean up should execute rather than
+a remote device's issued PRLI.
+
+Fixes: db651ec22524 ("scsi: lpfc: Correct used_rpi count when devloss tmo fires with no recovery")
+Signed-off-by: Justin Tee <justin.tee@broadcom.com>
+Link: https://lore.kernel.org/r/20230523183206.7728-5-justintee8345@gmail.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_els.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
+index 62d2ca688cd14..e07242ac0f014 100644
+--- a/drivers/scsi/lpfc/lpfc_els.c
++++ b/drivers/scsi/lpfc/lpfc_els.c
+@@ -5466,9 +5466,19 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ ndlp->nlp_flag &= ~NLP_RELEASE_RPI;
+ spin_unlock_irq(&ndlp->lock);
+ }
++ lpfc_drop_node(vport, ndlp);
++ } else if (ndlp->nlp_state != NLP_STE_PLOGI_ISSUE &&
++ ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE &&
++ ndlp->nlp_state != NLP_STE_PRLI_ISSUE) {
++ /* Drop ndlp if there is no planned or outstanding
++ * issued PRLI.
++ *
++ * In cases when the ndlp is acting as both an initiator
++ * and target function, let our issued PRLI determine
++ * the final ndlp kref drop.
++ */
++ lpfc_drop_node(vport, ndlp);
+ }
+-
+- lpfc_drop_node(vport, ndlp);
+ }
+
+ /* Release the originating I/O reference. */
+--
+2.39.2
+
--- /dev/null
+From 1da2c67a55a5079319304502eef607ea7b438176 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 May 2023 22:00:21 +0800
+Subject: scsi: qedf: Fix NULL dereference in error handling
+
+From: Jinhong Zhu <jinhongzhu@hust.edu.cn>
+
+[ Upstream commit f025312b089474a54e4859f3453771314d9e3d4f ]
+
+Smatch reported:
+
+drivers/scsi/qedf/qedf_main.c:3056 qedf_alloc_global_queues()
+warn: missing unwind goto?
+
+At this point in the function, nothing has been allocated so we can return
+directly. In particular the "qedf->global_queues" have not been allocated
+so calling qedf_free_global_queues() will lead to a NULL dereference when
+we check if (!gl[i]) and "gl" is NULL.
+
+Fixes: 61d8658b4a43 ("scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.")
+Signed-off-by: Jinhong Zhu <jinhongzhu@hust.edu.cn>
+Link: https://lore.kernel.org/r/20230502140022.2852-1-jinhongzhu@hust.edu.cn
+Reviewed-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qedf/qedf_main.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
+index 35e16600fc637..f2c7dd4db9c64 100644
+--- a/drivers/scsi/qedf/qedf_main.c
++++ b/drivers/scsi/qedf/qedf_main.c
+@@ -3043,9 +3043,8 @@ static int qedf_alloc_global_queues(struct qedf_ctx *qedf)
+ * addresses of our queues
+ */
+ if (!qedf->p_cpuq) {
+- status = -EINVAL;
+ QEDF_ERR(&qedf->dbg_ctx, "p_cpuq is NULL.\n");
+- goto mem_alloc_failure;
++ return -EINVAL;
+ }
+
+ qedf->global_queues = kzalloc((sizeof(struct global_queue *)
+--
+2.39.2
+
--- /dev/null
+From a5908ea8306a652d786f59464695ad4df26c8b9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 May 2023 13:36:20 -0700
+Subject: scsi: ufs: core: Fix handling of lrbp->cmd
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 549e91a9bbaa0ee480f59357868421a61d369770 ]
+
+ufshcd_queuecommand() may be called two times in a row for a SCSI command
+before it is completed. Hence make the following changes:
+
+ - In the functions that submit a command, do not check the old value of
+ lrbp->cmd nor clear lrbp->cmd in error paths.
+
+ - In ufshcd_release_scsi_cmd(), do not clear lrbp->cmd.
+
+See also scsi_send_eh_cmnd().
+
+This commit prevents that the following appears if a command times out:
+
+WARNING: at drivers/ufs/core/ufshcd.c:2965 ufshcd_queuecommand+0x6f8/0x9a8
+Call trace:
+ ufshcd_queuecommand+0x6f8/0x9a8
+ scsi_send_eh_cmnd+0x2c0/0x960
+ scsi_eh_test_devices+0x100/0x314
+ scsi_eh_ready_devs+0xd90/0x114c
+ scsi_error_handler+0x2b4/0xb70
+ kthread+0x16c/0x1e0
+
+Fixes: 5a0b0cb9bee7 ("[SCSI] ufs: Add support for sending NOP OUT UPIU")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20230524203659.1394307-3-bvanassche@acm.org
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index 8bf39a83ecd7f..dc63bd60db77d 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -2917,7 +2917,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
+ (hba->clk_gating.state != CLKS_ON));
+
+ lrbp = &hba->lrb[tag];
+- WARN_ON(lrbp->cmd);
+ lrbp->cmd = cmd;
+ lrbp->task_tag = tag;
+ lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun);
+@@ -2933,7 +2932,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
+
+ err = ufshcd_map_sg(hba, lrbp);
+ if (err) {
+- lrbp->cmd = NULL;
+ ufshcd_release(hba);
+ goto out;
+ }
+@@ -3152,7 +3150,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
+ down_read(&hba->clk_scaling_lock);
+
+ lrbp = &hba->lrb[tag];
+- WARN_ON(lrbp->cmd);
++ lrbp->cmd = NULL;
+ err = ufshcd_compose_dev_cmd(hba, lrbp, cmd_type, tag);
+ if (unlikely(err))
+ goto out;
+@@ -5391,7 +5389,6 @@ static void ufshcd_release_scsi_cmd(struct ufs_hba *hba,
+ struct scsi_cmnd *cmd = lrbp->cmd;
+
+ scsi_dma_unmap(cmd);
+- lrbp->cmd = NULL; /* Mark the command as completed. */
+ ufshcd_release(hba);
+ ufshcd_clk_scaling_update_busy(hba);
+ }
+@@ -7006,7 +7003,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba,
+ down_read(&hba->clk_scaling_lock);
+
+ lrbp = &hba->lrb[tag];
+- WARN_ON(lrbp->cmd);
+ lrbp->cmd = NULL;
+ lrbp->task_tag = tag;
+ lrbp->lun = 0;
+@@ -7178,7 +7174,6 @@ int ufshcd_advanced_rpmb_req_handler(struct ufs_hba *hba, struct utp_upiu_req *r
+ down_read(&hba->clk_scaling_lock);
+
+ lrbp = &hba->lrb[tag];
+- WARN_ON(lrbp->cmd);
+ lrbp->cmd = NULL;
+ lrbp->task_tag = tag;
+ lrbp->lun = UFS_UPIU_RPMB_WLUN;
+--
+2.39.2
+
--- /dev/null
+From 301056f741bdb52999541abd1a786320f403c3e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 May 2023 13:36:19 -0700
+Subject: scsi: ufs: core: Increase the START STOP UNIT timeout from one to ten
+ seconds
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit fe8637f7708c16765ecf4035813efbfdd2c9be10 ]
+
+One UFS vendor asked to increase the UFS timeout from 1 s to 3 s. Another
+UFS vendor asked to increase the UFS timeout from 1 s to 10 s. Hence this
+patch that increases the UFS timeout to 10 s. This patch can cause the
+total timeout to exceed 20 s, the Android shutdown timeout. This is fine
+since the loop around ufshcd_execute_start_stop() exists to deal with unit
+attentions and because unit attentions are reported quickly.
+
+Fixes: dcd5b7637c6d ("scsi: ufs: Reduce the START STOP UNIT timeout")
+Fixes: 8f2c96420c6e ("scsi: ufs: core: Reduce the power mode change timeout")
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
+Reviewed-by: Bean Huo <beanhuo@micron.com>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20230524203659.1394307-2-bvanassche@acm.org
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index aec74987cb4e0..8bf39a83ecd7f 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -9153,7 +9153,8 @@ static int ufshcd_execute_start_stop(struct scsi_device *sdev,
+ };
+
+ return scsi_execute_cmd(sdev, cdb, REQ_OP_DRV_IN, /*buffer=*/NULL,
+- /*bufflen=*/0, /*timeout=*/HZ, /*retries=*/0, &args);
++ /*bufflen=*/0, /*timeout=*/10 * HZ, /*retries=*/0,
++ &args);
+ }
+
+ /**
+--
+2.39.2
+
--- /dev/null
+From 31e5f5801e366d3eab0355c02320bfbca212b692 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Jun 2023 10:15:51 +0800
+Subject: scsi: ufs: core: mcq: Fix the incorrect OCS value for the device
+ command
+
+From: Stanley Chu <stanley.chu@mediatek.com>
+
+[ Upstream commit 0fef6bb730c490fcdc4347dbd21646d3ffe62cf5 ]
+
+In MCQ mode, when a device command uses a hardware queue shared with other
+commands, a race condition may occur in the following scenario:
+
+ 1. A device command is completed in CQx with CQE entry "e".
+
+ 2. The interrupt handler copies the "cqe" pointer to "hba->dev_cmd.cqe"
+ and completes "hba->dev_cmd.complete".
+
+ 3. The "ufshcd_wait_for_dev_cmd()" function is awakened and retrieves the
+ OCS value from "hba->dev_cmd.cqe".
+
+However, there is a possibility that the CQE entry "e" will be overwritten
+by newly completed commands in CQx, resulting in an incorrect OCS value
+being received by "ufshcd_wait_for_dev_cmd()".
+
+To avoid this race condition, the OCS value should be immediately copied to
+the struct "lrb" of the device command. Then "ufshcd_wait_for_dev_cmd()"
+can retrieve the OCS value from the struct "lrb".
+
+Fixes: 57b1c0ef89ac ("scsi: ufs: core: mcq: Add support to allocate multiple queues")
+Suggested-by: Can Guo <quic_cang@quicinc.com>
+Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
+Link: https://lore.kernel.org/r/20230610021553.1213-2-powen.kao@mediatek.com
+Tested-by: Po-Wen Kao <powen.kao@mediatek.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 10 +++++++---
+ include/ufs/ufshcd.h | 1 -
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index b788bd0053330..e67981317dcbf 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -3069,7 +3069,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
+ * not trigger any race conditions.
+ */
+ hba->dev_cmd.complete = NULL;
+- err = ufshcd_get_tr_ocs(lrbp, hba->dev_cmd.cqe);
++ err = ufshcd_get_tr_ocs(lrbp, NULL);
+ if (!err)
+ err = ufshcd_dev_cmd_completion(hba, lrbp);
+ } else {
+@@ -3156,7 +3156,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
+ goto out;
+
+ hba->dev_cmd.complete = &wait;
+- hba->dev_cmd.cqe = NULL;
+
+ ufshcd_add_query_upiu_trace(hba, UFS_QUERY_SEND, lrbp->ucd_req_ptr);
+
+@@ -5404,6 +5403,7 @@ void ufshcd_compl_one_cqe(struct ufs_hba *hba, int task_tag,
+ {
+ struct ufshcd_lrb *lrbp;
+ struct scsi_cmnd *cmd;
++ enum utp_ocs ocs;
+
+ lrbp = &hba->lrb[task_tag];
+ lrbp->compl_time_stamp = ktime_get();
+@@ -5419,7 +5419,11 @@ void ufshcd_compl_one_cqe(struct ufs_hba *hba, int task_tag,
+ } else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE ||
+ lrbp->command_type == UTP_CMD_TYPE_UFS_STORAGE) {
+ if (hba->dev_cmd.complete) {
+- hba->dev_cmd.cqe = cqe;
++ if (cqe) {
++ ocs = le32_to_cpu(cqe->status) & MASK_OCS;
++ lrbp->utr_descriptor_ptr->header.dword_2 =
++ cpu_to_le32(ocs);
++ }
+ complete(hba->dev_cmd.complete);
+ ufshcd_clk_scaling_update_busy(hba);
+ }
+diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
+index db70944c681aa..91803587691a6 100644
+--- a/include/ufs/ufshcd.h
++++ b/include/ufs/ufshcd.h
+@@ -225,7 +225,6 @@ struct ufs_dev_cmd {
+ struct mutex lock;
+ struct completion *complete;
+ struct ufs_query query;
+- struct cq_entry *cqe;
+ };
+
+ /**
+--
+2.39.2
+
--- /dev/null
+From 9606dbabcc353eaef7a2bd3c1ead233bf928b493 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 May 2023 15:40:47 -0700
+Subject: scsi: ufs: core: Remove a ufshcd_add_command_trace() call
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 72554035b9797e00e68cd866e6cefa7f0b2c6f76 ]
+
+ufshcd_add_command_trace() traces SCSI commands. Remove a
+ufshcd_add_command_trace() call from a code path that is not related to
+SCSI commands.
+
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20230531224050.25554-1-bvanassche@acm.org
+Reviewed-by: Avri Altman <avri.altman@wdc.com>
+Reviewed-by: Bean Huo <beanhuo@micron.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 0fef6bb730c4 ("scsi: ufs: core: mcq: Fix the incorrect OCS value for the device command")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index dc63bd60db77d..b788bd0053330 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -5420,7 +5420,6 @@ void ufshcd_compl_one_cqe(struct ufs_hba *hba, int task_tag,
+ lrbp->command_type == UTP_CMD_TYPE_UFS_STORAGE) {
+ if (hba->dev_cmd.complete) {
+ hba->dev_cmd.cqe = cqe;
+- ufshcd_add_command_trace(hba, task_tag, UFS_DEV_COMP);
+ complete(hba->dev_cmd.complete);
+ ufshcd_clk_scaling_update_busy(hba);
+ }
+--
+2.39.2
+
--- /dev/null
+From c53e503164edd3098a0570a9f56a5525dfaf0858 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 May 2023 13:26:39 -0700
+Subject: scsi: ufs: Declare ufshcd_{hold,release}() once
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 4b68b7f9c46d90c541d39c8b397a86ac0ca4c765 ]
+
+ufshcd_hold() and ufshcd_release are declared twice: once in
+drivers/ufs/core/ufshcd-priv.h and a second time in include/ufs/ufshcd.h.
+Remove the declarations from ufshcd-priv.h.
+
+Fixes: dd11376b9f1b ("scsi: ufs: Split the drivers/scsi/ufs directory")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20230529202640.11883-5-bvanassche@acm.org
+Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Keoseong Park <keosung.park@samsung.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd-priv.h | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h
+index 529f8507a5e4c..7d8ff743a1b28 100644
+--- a/drivers/ufs/core/ufshcd-priv.h
++++ b/drivers/ufs/core/ufshcd-priv.h
+@@ -84,9 +84,6 @@ unsigned long ufshcd_mcq_poll_cqe_lock(struct ufs_hba *hba,
+ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index,
+ u8 **buf, bool ascii);
+
+-int ufshcd_hold(struct ufs_hba *hba, bool async);
+-void ufshcd_release(struct ufs_hba *hba);
+-
+ int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd);
+
+ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
+--
+2.39.2
+
--- /dev/null
+From 73d4f2d6f5a329e4b328be17f04f0a40e51c837c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 May 2023 15:25:06 +0200
+Subject: sctp: add bpf_bypass_getsockopt proto callback
+
+From: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
+
+[ Upstream commit 2598619e012cee5273a2821441b9a051ad931249 ]
+
+Implement ->bpf_bypass_getsockopt proto callback and filter out
+SCTP_SOCKOPT_PEELOFF, SCTP_SOCKOPT_PEELOFF_FLAGS and SCTP_SOCKOPT_CONNECTX3
+socket options from running eBPF hook on them.
+
+SCTP_SOCKOPT_PEELOFF and SCTP_SOCKOPT_PEELOFF_FLAGS options do fd_install(),
+and if BPF_CGROUP_RUN_PROG_GETSOCKOPT hook returns an error after success of
+the original handler sctp_getsockopt(...), userspace will receive an error
+from getsockopt syscall and will be not aware that fd was successfully
+installed into a fdtable.
+
+As pointed by Marcelo Ricardo Leitner it seems reasonable to skip
+bpf getsockopt hook for SCTP_SOCKOPT_CONNECTX3 sockopt too.
+Because internaly, it triggers connect() and if error is masked
+then userspace will be confused.
+
+This patch was born as a result of discussion around a new SCM_PIDFD interface:
+https://lore.kernel.org/all/20230413133355.350571-3-aleksandr.mikhalitsyn@canonical.com/
+
+Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks")
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: Stanislav Fomichev <sdf@google.com>
+Cc: Neil Horman <nhorman@tuxdriver.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Cc: Xin Long <lucien.xin@gmail.com>
+Cc: linux-sctp@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Cc: netdev@vger.kernel.org
+Suggested-by: Stanislav Fomichev <sdf@google.com>
+Acked-by: Stanislav Fomichev <sdf@google.com>
+Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/socket.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 218e0982c3707..0932cbf568ee9 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -8280,6 +8280,22 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
+ return retval;
+ }
+
++static bool sctp_bpf_bypass_getsockopt(int level, int optname)
++{
++ if (level == SOL_SCTP) {
++ switch (optname) {
++ case SCTP_SOCKOPT_PEELOFF:
++ case SCTP_SOCKOPT_PEELOFF_FLAGS:
++ case SCTP_SOCKOPT_CONNECTX3:
++ return true;
++ default:
++ return false;
++ }
++ }
++
++ return false;
++}
++
+ static int sctp_hash(struct sock *sk)
+ {
+ /* STUB */
+@@ -9649,6 +9665,7 @@ struct proto sctp_prot = {
+ .shutdown = sctp_shutdown,
+ .setsockopt = sctp_setsockopt,
+ .getsockopt = sctp_getsockopt,
++ .bpf_bypass_getsockopt = sctp_bpf_bypass_getsockopt,
+ .sendmsg = sctp_sendmsg,
+ .recvmsg = sctp_recvmsg,
+ .bind = sctp_bind,
+@@ -9704,6 +9721,7 @@ struct proto sctpv6_prot = {
+ .shutdown = sctp_shutdown,
+ .setsockopt = sctp_setsockopt,
+ .getsockopt = sctp_getsockopt,
++ .bpf_bypass_getsockopt = sctp_bpf_bypass_getsockopt,
+ .sendmsg = sctp_sendmsg,
+ .recvmsg = sctp_recvmsg,
+ .bind = sctp_bind,
+--
+2.39.2
+
--- /dev/null
+From 8d5ba5e1fca7579cb99760c91d3994cb56ec1923 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 11:49:46 +0200
+Subject: selftests/bpf: Do not use sign-file as testcase
+
+From: Alexey Gladkov <legion@kernel.org>
+
+[ Upstream commit f04a32b2c5b539e3c097cb5c7c1df12a8f4a0cf0 ]
+
+The sign-file utility (from scripts/) is used in prog_tests/verify_pkcs7_sig.c,
+but the utility should not be called as a test. Executing this utility produces
+the following error:
+
+ selftests: /linux/tools/testing/selftests/bpf: urandom_read
+ ok 16 selftests: /linux/tools/testing/selftests/bpf: urandom_read
+
+ selftests: /linux/tools/testing/selftests/bpf: sign-file
+ not ok 17 selftests: /linux/tools/testing/selftests/bpf: sign-file # exit=2
+
+Also, urandom_read is mistakenly used as a test. It does not lead to an error,
+but should be moved over to TEST_GEN_FILES as well. The empty TEST_CUSTOM_PROGS
+can then be removed.
+
+Fixes: fc97590668ae ("selftests/bpf: Add test for bpf_verify_pkcs7_signature() kfunc")
+Signed-off-by: Alexey Gladkov <legion@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Roberto Sassu <roberto.sassu@huawei.com>
+Acked-by: Stanislav Fomichev <sdf@google.com>
+Link: https://lore.kernel.org/bpf/ZEuWFk3QyML9y5QQ@example.org
+Link: https://lore.kernel.org/bpf/88e3ab23029d726a2703adcf6af8356f7a2d3483.1684316821.git.legion@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/Makefile | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
+index ad01c9e1ff12b..625eedb84eecc 100644
+--- a/tools/testing/selftests/bpf/Makefile
++++ b/tools/testing/selftests/bpf/Makefile
+@@ -88,8 +88,7 @@ TEST_GEN_PROGS_EXTENDED = test_sock_addr test_skb_cgroup_id_user \
+ xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_hw_metadata \
+ xdp_features
+
+-TEST_CUSTOM_PROGS = $(OUTPUT)/urandom_read $(OUTPUT)/sign-file
+-TEST_GEN_FILES += liburandom_read.so
++TEST_GEN_FILES += liburandom_read.so urandom_read sign-file
+
+ # Emit succinct information message describing current building step
+ # $1 - generic step name (e.g., CC, LINK, etc);
+--
+2.39.2
+
--- /dev/null
+From 23d550ece4c04a2f8ce4ce75fe9e3122397d9f1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 13:30:47 +0200
+Subject: selftests/bpf: Fix check_mtu using wrong variable type
+
+From: Jesper Dangaard Brouer <brouer@redhat.com>
+
+[ Upstream commit 095641817e1bf6aa2560e025e47575188ee3edaf ]
+
+Dan Carpenter found via Smatch static checker, that unsigned 'mtu_lo' is
+never less than zero.
+
+Variable mtu_lo should have been an 'int', because read_mtu_device_lo()
+uses minus as error indications.
+
+Fixes: b62eba563229 ("selftests/bpf: Tests using bpf_check_mtu BPF-helper")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Link: https://lore.kernel.org/bpf/168605104733.3636467.17945947801753092590.stgit@firesoul
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/check_mtu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/check_mtu.c b/tools/testing/selftests/bpf/prog_tests/check_mtu.c
+index 5338d2ea04603..2a9a30650350e 100644
+--- a/tools/testing/selftests/bpf/prog_tests/check_mtu.c
++++ b/tools/testing/selftests/bpf/prog_tests/check_mtu.c
+@@ -183,7 +183,7 @@ static void test_check_mtu_tc(__u32 mtu, __u32 ifindex)
+
+ void serial_test_check_mtu(void)
+ {
+- __u32 mtu_lo;
++ int mtu_lo;
+
+ if (test__start_subtest("bpf_check_mtu XDP-attach"))
+ test_check_mtu_xdp_attach();
+--
+2.39.2
+
--- /dev/null
+From 7390740dd3a7ce93d43978d8872cba3e4e177ff8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Jun 2023 01:16:37 +0300
+Subject: selftests/bpf: Fix invalid pointer check in get_xlated_program()
+
+From: Eduard Zingerman <eddyz87@gmail.com>
+
+[ Upstream commit b23ed4d74c4d583b5f621ee4c776699442833554 ]
+
+Dan Carpenter reported invalid check for calloc() result in
+test_verifier.c:get_xlated_program():
+
+ ./tools/testing/selftests/bpf/test_verifier.c:1365 get_xlated_program()
+ warn: variable dereferenced before check 'buf' (see line 1364)
+
+ ./tools/testing/selftests/bpf/test_verifier.c
+ 1363 *cnt = xlated_prog_len / buf_element_size;
+ 1364 *buf = calloc(*cnt, buf_element_size);
+ 1365 if (!buf) {
+
+ This should be if (!*buf) {
+
+ 1366 perror("can't allocate xlated program buffer");
+ 1367 return -ENOMEM;
+
+This commit refactors the get_xlated_program() to avoid using double
+pointer type.
+
+Fixes: 933ff53191eb ("selftests/bpf: specify expected instructions in test_verifier tests")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Closes: https://lore.kernel.org/bpf/ZH7u0hEGVB4MjGZq@moroto/
+Link: https://lore.kernel.org/bpf/20230609221637.2631800-1-eddyz87@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/test_verifier.c | 24 +++++++++++----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
+index 8b9949bb833d7..2e9bdf2e91351 100644
+--- a/tools/testing/selftests/bpf/test_verifier.c
++++ b/tools/testing/selftests/bpf/test_verifier.c
+@@ -1232,45 +1232,46 @@ static bool cmp_str_seq(const char *log, const char *exp)
+ return true;
+ }
+
+-static int get_xlated_program(int fd_prog, struct bpf_insn **buf, int *cnt)
++static struct bpf_insn *get_xlated_program(int fd_prog, int *cnt)
+ {
++ __u32 buf_element_size = sizeof(struct bpf_insn);
+ struct bpf_prog_info info = {};
+ __u32 info_len = sizeof(info);
+ __u32 xlated_prog_len;
+- __u32 buf_element_size = sizeof(struct bpf_insn);
++ struct bpf_insn *buf;
+
+ if (bpf_prog_get_info_by_fd(fd_prog, &info, &info_len)) {
+ perror("bpf_prog_get_info_by_fd failed");
+- return -1;
++ return NULL;
+ }
+
+ xlated_prog_len = info.xlated_prog_len;
+ if (xlated_prog_len % buf_element_size) {
+ printf("Program length %d is not multiple of %d\n",
+ xlated_prog_len, buf_element_size);
+- return -1;
++ return NULL;
+ }
+
+ *cnt = xlated_prog_len / buf_element_size;
+- *buf = calloc(*cnt, buf_element_size);
++ buf = calloc(*cnt, buf_element_size);
+ if (!buf) {
+ perror("can't allocate xlated program buffer");
+- return -ENOMEM;
++ return NULL;
+ }
+
+ bzero(&info, sizeof(info));
+ info.xlated_prog_len = xlated_prog_len;
+- info.xlated_prog_insns = (__u64)(unsigned long)*buf;
++ info.xlated_prog_insns = (__u64)(unsigned long)buf;
+ if (bpf_prog_get_info_by_fd(fd_prog, &info, &info_len)) {
+ perror("second bpf_prog_get_info_by_fd failed");
+ goto out_free_buf;
+ }
+
+- return 0;
++ return buf;
+
+ out_free_buf:
+- free(*buf);
+- return -1;
++ free(buf);
++ return NULL;
+ }
+
+ static bool is_null_insn(struct bpf_insn *insn)
+@@ -1403,7 +1404,8 @@ static bool check_xlated_program(struct bpf_test *test, int fd_prog)
+ if (!check_expected && !check_unexpected)
+ goto out;
+
+- if (get_xlated_program(fd_prog, &buf, &cnt)) {
++ buf = get_xlated_program(fd_prog, &cnt);
++ if (!buf) {
+ printf("FAIL: can't get xlated program\n");
+ result = false;
+ goto out;
+--
+2.39.2
+
--- /dev/null
+From f5e82b092c8b5c2eacc4543300e613eaa71cfce2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 May 2023 09:52:33 +0000
+Subject: selftests: cgroup: fix unexpected failure on test_memcg_low
+
+From: Haifeng Xu <haifeng.xu@shopee.com>
+
+[ Upstream commit 19ab365762c6cc39dfdee9e13ab0d12fe4b5540d ]
+
+Since commit f079a020ba95 ("selftests: memcg: factor out common parts of
+memory.{low,min} tests"), the value used in second alloc_anon has changed
+from 148M to 170M. Because memory.low allows reclaiming page cache in
+child cgroups, so the memory.current is close to 30M instead of 50M.
+Therefore, adjust the expected value of parent cgroup.
+
+Link: https://lkml.kernel.org/r/20230522095233.4246-2-haifeng.xu@shopee.com
+Fixes: f079a020ba95 ("selftests: memcg: factor out common parts of memory.{low,min} tests")
+Signed-off-by: Haifeng Xu <haifeng.xu@shopee.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Roman Gushchin <roman.gushchin@linux.dev>
+Cc: Shakeel Butt <shakeelb@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/cgroup/test_memcontrol.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c
+index f4f7c0aef702b..a2a90f4bfe9fe 100644
+--- a/tools/testing/selftests/cgroup/test_memcontrol.c
++++ b/tools/testing/selftests/cgroup/test_memcontrol.c
+@@ -292,6 +292,7 @@ static int test_memcg_protection(const char *root, bool min)
+ char *children[4] = {NULL};
+ const char *attribute = min ? "memory.min" : "memory.low";
+ long c[4];
++ long current;
+ int i, attempts;
+ int fd;
+
+@@ -400,7 +401,8 @@ static int test_memcg_protection(const char *root, bool min)
+ goto cleanup;
+ }
+
+- if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3))
++ current = min ? MB(50) : MB(30);
++ if (!values_close(cg_read_long(parent[1], "memory.current"), current, 3))
+ goto cleanup;
+
+ if (!reclaim_until(children[0], MB(10)))
+--
+2.39.2
+
--- /dev/null
+From 4906c519bcccb3af7b96a0faf6db5c4d21937656 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 23:03:34 +0200
+Subject: selftests: rtnetlink: remove netdevsim device after ipsec offload
+ test
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+[ Upstream commit 5f789f103671fec3733ebe756e56adf15c90c21d ]
+
+On systems where netdevsim is built-in or loaded before the test
+starts, kci_test_ipsec_offload doesn't remove the netdevsim device it
+created during the test.
+
+Fixes: e05b2d141fef ("netdevsim: move netdev creation/destruction to dev probe")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://lore.kernel.org/r/e1cb94f4f82f4eca4a444feec4488a1323396357.1687466906.git.sd@queasysnail.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/rtnetlink.sh | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh
+index 275491be3da2f..cafd14b1ed2ab 100755
+--- a/tools/testing/selftests/net/rtnetlink.sh
++++ b/tools/testing/selftests/net/rtnetlink.sh
+@@ -835,6 +835,7 @@ EOF
+ fi
+
+ # clean up any leftovers
++ echo 0 > /sys/bus/netdevsim/del_device
+ $probed && rmmod netdevsim
+
+ if [ $ret -ne 0 ]; then
+--
+2.39.2
+
drm-use-mgr-dev-in-drm_dbg_kms-in-drm_dp_add_payload_part2.patch
+fs-pipe-reveal-missing-function-protoypes.patch
+block-fix-the-type-of-the-second-bdev_op_is_zoned_wr.patch
+blkcg-drop-unnecessary-rcu-read-un-locks-from-blkg_c.patch
+blkcg-restructure-blkg_conf_prep-and-friends.patch
+block-rq_qos-protect-rq_qos-apis-with-a-new-lock.patch
+splice-fix-filemap_splice_read-to-use-the-correct-in.patch
+erofs-kill-hooked-chains-to-avoid-loops-on-deduplica.patch
+x86-resctrl-only-show-tasks-pid-in-current-pid-names.patch
+fsverity-use-warn_on_once-instead-of-warn_on.patch
+fsverity-use-shash-api-instead-of-ahash-api.patch
+fsverity-don-t-use-bio_first_page_all-in-fsverity_ve.patch
+blk-iocost-use-spin_lock_irqsave-in-adjust_inuse_and.patch
+x86-sev-fix-calculation-of-end-address-based-on-numb.patch
+blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-.patch
+virt-sevguest-add-config_crypto-dependency.patch
+blk-mq-fix-potential-io-hang-by-wrong-wake_batch.patch
+lockd-drop-inappropriate-svc_get-from-locked_get.patch
+nvme-core-fix-memory-leak-in-dhchap_secret_store.patch
+nvme-core-fix-memory-leak-in-dhchap_ctrl_secret.patch
+nvme-core-add-missing-fault-injection-cleanup.patch
+nvme-core-fix-dev_pm_qos-memleak.patch
+md-raid10-check-slab-out-of-bounds-in-md_bitmap_get_.patch
+md-raid10-fix-overflow-of-md-safe_mode_delay.patch
+md-raid10-fix-wrong-setting-of-max_corr_read_errors.patch
+md-raid10-fix-null-ptr-deref-of-mreplace-in-raid10_s.patch
+md-raid10-fix-io-loss-while-replacement-replace-rdev.patch
+md-raid1-10-factor-out-a-helper-to-add-bio-to-plug.patch
+md-raid1-10-factor-out-a-helper-to-submit-normal-wri.patch
+md-raid1-10-submit-write-io-directly-if-bitmap-is-no.patch
+block-fix-blktrace-debugfs-entries-leakage.patch
+irqchip-loongson-eiointc-fix-irq-affinity-setting-du.patch
+splice-don-t-call-file_accessed-in-copy_splice_read.patch
+irqchip-stm32-exti-fix-warning-on-initialized-field-.patch
+irqchip-jcore-aic-fix-missing-allocation-of-irq-desc.patch
+svcrdma-prevent-page-release-when-nothing-was-receiv.patch
+erofs-fix-compact-4b-support-for-16k-block-size.patch
+posix-timers-prevent-rt-livelock-in-itimer_delete.patch
+tick-rcu-fix-bogus-ratelimit-condition.patch
+tracing-timer-add-missing-hrtimer-modes-to-decode_hr.patch
+btrfs-make-btrfs_split_bio-work-on-struct-btrfs_bio.patch
+btrfs-fix-file_offset-for-req_btrfs_one_ordered-bios.patch
+clocksource-drivers-cadence-ttc-fix-memory-leak-in-t.patch
+pm-domains-fix-integer-overflow-issues-in-genpd_pars.patch
+perf-arm-cmn-fix-dtc-reset.patch
+x86-mm-allow-guest.enc_status_change_prepare-to-fail.patch
+x86-tdx-fix-race-between-set_memory_encrypted-and-lo.patch
+drivers-perf-hisi-don-t-migrate-perf-to-the-cpu-goin.patch
+perf-arm_cspmu-set-irq-affinitiy-only-if-overflow-in.patch
+perf-arm_cspmu-fix-event-attribute-type.patch
+apei-ghes-correctly-return-null-for-ghes_get_devices.patch
+powercap-rapl-fix-invalid-initialization-for-pl4_sup.patch
+powercap-rapl-fix-config_iosf_mbi-dependency.patch
+pm-domains-move-the-verification-of-in-params-from-g.patch
+arm-9303-1-kprobes-avoid-missing-declaration-warning.patch
+cpufreq-intel_pstate-fix-energy_performance_preferen.patch
+thermal-drivers-qcom-tsens-v0_1-add-support-for-msm8.patch
+thermal-drivers-qcom-tsens-v0_1-fix-mdm9607-slope-va.patch
+thermal-drivers-qcom-tsens-v0_1-add-mdm9607-correcti.patch
+thermal-drivers-sun8i-fix-some-error-handling-paths-.patch
+thermal-hwmon-use-the-right-device-for-devm_thermal_.patch
+thermal-drivers-qoriq-only-enable-supported-sensors.patch
+rcu-make-rcu_cpu_starting-rely-on-interrupts-being-d.patch
+rcu-tasks-stop-rcu_tasks_invoke_cbs-from-using-never.patch
+rcutorture-correct-name-of-use_softirq-module-parame.patch
+rcuscale-move-shutdown-from-wait_event-to-wait_event.patch
+rcu-rcuscale-move-rcu_scale_-after-kfree_scale_clean.patch
+rcu-rcuscale-stop-kfree_scale_thread-thread-s-after-.patch
+x86-mtrr-remove-physical-address-size-calculation.patch
+x86-mtrr-replace-size_or_mask-and-size_and_mask-with.patch
+x86-mtrr-support-setting-mtrr-state-for-software-def.patch
+x86-xen-set-mtrr-state-when-running-as-xen-pv-initia.patch
+kselftest-vdso-fix-accumulation-of-uninitialized-ret.patch
+perf-ibs-fix-interface-via-core-pmu-events.patch
+x86-mm-fix-__swp_entry_to_pte-for-xen-pv-guests.patch
+locking-atomic-arm-fix-sync-ops.patch
+evm-complete-description-of-evm_inode_setattr.patch
+evm-fix-build-warnings.patch
+ima-fix-build-warnings.patch
+pstore-ram-add-check-for-kstrdup.patch
+sched-core-avoid-multiple-calling-update_rq_clock-in.patch
+igc-enable-and-fix-rx-hash-usage-by-netstack.patch
+wifi-ath9k-fix-ar9003-mac-hardware-hang-check-regist.patch
+wifi-ath9k-avoid-referencing-uninit-memory-in-ath9k_.patch
+libbpf-btf_dump_type_data_check_overflow-needs-to-co.patch
+samples-bpf-fix-buffer-overflow-in-tcp_basertt.patch
+spi-spi-geni-qcom-correct-cs_toggle-bit-in-spi_trans.patch
+wifi-wilc1000-fix-for-absent-rsn-capabilities-wfa-te.patch
+wifi-mwifiex-fix-the-size-of-a-memory-allocation-in-.patch
+sctp-add-bpf_bypass_getsockopt-proto-callback.patch
+libbpf-fix-offsetof-and-container_of-to-work-with-co.patch
+bpf-don-t-efault-for-g-s-setsockopt-with-wrong-optle.patch
+spi-dw-round-of-n_bytes-to-power-of-2.patch
+nfc-llcp-fix-possible-use-of-uninitialized-variable-.patch
+bpftool-jit-limited-misreported-as-negative-value-on.patch
+bpf-remove-bpf-trampoline-selector.patch
+bpf-fix-memleak-due-to-fentry-attach-failure.patch
+selftests-bpf-do-not-use-sign-file-as-testcase.patch
+regulator-core-fix-more-error-checking-for-debugfs_c.patch
+regulator-core-streamline-debugfs-operations.patch
+wifi-orinoco-fix-an-error-handling-path-in-spectrum_.patch
+wifi-orinoco-fix-an-error-handling-path-in-orinoco_c.patch
+wifi-atmel-fix-an-error-handling-path-in-atmel_probe.patch
+wifi-wl3501_cs-fix-an-error-handling-path-in-wl3501_.patch
+wifi-ray_cs-fix-an-error-handling-path-in-ray_probe.patch
+wifi-ath9k-don-t-allow-to-overwrite-endpoint0-attrib.patch
+wifi-rtw88-usb-silence-log-flooding-error-message.patch
+samples-bpf-xdp1-and-xdp2-reduce-xdpbufsize-to-60.patch
+wifi-ath10k-trigger-sta-disconnect-after-reconfig-co.patch
+tools-resolve_btfids-fix-setting-hostcflags.patch
+wifi-mac80211-recalc-min-chandef-for-new-sta-links.patch
+selftests-bpf-fix-check_mtu-using-wrong-variable-typ.patch
+wifi-rsi-do-not-configure-wowlan-in-shutdown-hook-if.patch
+wifi-rsi-do-not-set-mmc_pm_keep_power-in-shutdown.patch
+ice-handle-extts-in-the-miscellaneous-interrupt-thre.patch
+selftests-cgroup-fix-unexpected-failure-on-test_memc.patch
+watchdog-perf-define-dummy-watchdog_update_hrtimer_t.patch
+watchdog-perf-more-properly-prevent-false-positives-.patch
+kexec-fix-a-memory-leak-in-crash_shrink_memory.patch
+mmc-mediatek-avoid-ugly-error-message-when-sdio-wake.patch
+memstick-r592-make-memstick_debug_get_tpc_name-stati.patch
+selftests-bpf-fix-invalid-pointer-check-in-get_xlate.patch
+wifi-ath9k-fix-possible-stall-on-ath9k_txq_list_has_.patch
+wifi-mac80211-fix-permissions-for-valid_links-debugf.patch
+rtnetlink-extend-rtext_filter_skip_stats-to-ifla_vf_.patch
+wifi-ath11k-add-missing-check-for-ioremap.patch
+wifi-ath11k-add-missing-ops-config-for-ipq5018-in-at.patch
+wifi-ath11k-restart-firmware-after-cold-boot-calibra.patch
+wifi-ath11k-add-missing-hw_ops-get_ring_selector-for.patch
+wifi-iwlwifi-pull-from-txqs-with-softirqs-disabled.patch
+wifi-iwlwifi-pcie-fix-null-pointer-dereference-in-iw.patch
+wifi-mac80211-remove-missing-iftype-sband-data-eht-c.patch
+wifi-cfg80211-rewrite-merging-of-inherited-elements.patch
+wifi-cfg80211-drop-incorrect-nontransmitted-bss-upda.patch
+wifi-cfg80211-fix-regulatory-disconnect-with-ocb-nan.patch
+wifi-ieee80211-fix-the-common-size-calculation-for-r.patch
+mmc-add-mmc_quirk_broken_sd_cache-for-kingston-canva.patch
+wifi-iwlwifi-mvm-indicate-hw-decrypt-for-beacon-prot.patch
+wifi-ath9k-convert-msecs-to-jiffies-where-needed.patch
+bpf-factor-out-socket-lookup-functions-for-the-tc-ho.patch
+bpf-call-__bpf_sk_lookup-__bpf_skc_lookup-directly-v.patch
+bpf-fix-bpf-socket-lookup-from-tc-xdp-to-respect-soc.patch
+can-length-fix-bitstuffing-count.patch
+can-kvaser_pciefd-add-function-to-set-skb-hwtstamps.patch
+can-kvaser_pciefd-set-hardware-timestamp-on-transmit.patch
+net-stmmac-fix-double-serdes-powerdown.patch
+netlink-fix-potential-deadlock-in-netlink_set_err.patch
+netlink-do-not-hard-code-device-address-lenth-in-fdb.patch
+bonding-do-not-assume-skb-mac_header-is-set.patch
+selftests-rtnetlink-remove-netdevsim-device-after-ip.patch
+gtp-fix-use-after-free-in-__gtp_encap_destroy.patch
+net-axienet-move-reset-before-64-bit-dma-detection.patch
+ocfs2-fix-use-of-slab-data-with-sendpage.patch
+sfc-fix-crash-when-reading-stats-while-nic-is-resett.patch
+net-nfc-fix-use-after-free-caused-by-nfc_llcp_find_l.patch
+lib-ts_bm-reset-initial-match-offset-for-every-block.patch
+netfilter-conntrack-dccp-copy-entire-header-to-stack.patch
+netfilter-nf_conntrack_sip-fix-the-ct_sip_parse_nume.patch
+ipvlan-fix-return-value-of-ipvlan_queue_xmit.patch
+net-dsa-avoid-suspicious-rcu-usage-for-synced-vlan-a.patch
+netlink-add-__sock_i_ino-for-__netlink_diag_dump.patch
+drm-amd-display-add-logging-for-display-mall-refresh.patch
+drm-amd-display-fix-is_timing_changed-prototype.patch
+radeon-avoid-double-free-in-ci_dpm_init.patch
+drm-amd-display-explicitly-specify-update-type-per-p.patch
+drm-i915-guc-more-debug-print-updates-guc-slpc.patch
+drm-i915-guc-slpc-provide-sysfs-for-efficient-freq.patch
+drm-bridge-it6505-move-a-variable-assignment-behind-.patch
+input-drv260x-sleep-between-polling-go-bit.patch
+input-cyttsp4_core-change-del_timer_sync-to-timer_sh.patch
+drm-bridge-ti-sn65dsi83-fix-enable-error-path.patch
+drm-bridge-tc358768-always-enable-hs-video-mode.patch
+drm-bridge-tc358768-fix-pll-parameters-computation.patch
+drm-bridge-tc358768-fix-pll-target-frequency.patch
+drm-bridge-tc358768-fix-tclk_zerocnt-computation.patch
+drm-bridge-tc358768-add-atomic_get_input_bus_fmts-im.patch
+drm-bridge-tc358768-fix-tclk_trailcnt-computation.patch
+drm-bridge-tc358768-fix-ths_zerocnt-computation.patch
+drm-bridge-tc358768-fix-txtagocnt-computation.patch
+drm-bridge-tc358768-fix-ths_trailcnt-computation.patch
+drm-vram-helper-fix-function-names-in-vram-helper-do.patch
+arm-dts-bcm5301x-drop-clock-names-from-the-spi-node.patch
+arm-dts-meson8b-correct-uart_b-and-uart_c-clock-refe.patch
+clk-vc5-fix-.driver_data-content-in-i2c_device_id.patch
+clk-vc7-fix-.driver_data-content-in-i2c_device_id.patch
+clk-rs9-check-for-vendor-device-id.patch
+clk-rs9-support-device-specific-dif-bit-calculation.patch
+clk-rs9-add-support-for-9fgv0441.patch
+clk-rs9-fix-.driver_data-content-in-i2c_device_id.patch
+input-adxl34x-do-not-hardcode-interrupt-trigger-type.patch
+drm-sun4i_tcon-use-devm_clk_get_enabled-in-sun4i_tco.patch
+drm-panel-sharp-ls043t1le01-adjust-mode-settings.patch
+driver-soc-xilinx-use-_safe-loop-iterator-to-avoid-a.patch
+asoc-dt-bindings-mediatek-mt8188-afe-correct-clock-n.patch
+asoc-intel-sof_sdw-remove-sof_sdw_tgl_hdmi-for-meteo.patch
+drm-vkms-isolate-pixel-conversion-functionality.patch
+drm-add-fixed-point-helper-to-get-rounded-integer-va.patch
+drm-vkms-fix-rgb565-pixel-conversion.patch
+arm-dts-stm32-move-ethernet-mac-eeprom-from-som-to-c.patch
+bus-ti-sysc-fix-dispc-quirk-masking-bool-variables.patch
+arm64-dts-microchip-sparx5-do-not-use-psci-on-refere.patch
+drm-bridge-tc358767-switch-to-devm-mipi-dsi-helpers.patch
+clk-imx-scu-use-_safe-list-iterator-to-avoid-a-use-a.patch
+hwmon-f71882fg-prevent-possible-division-by-zero.patch
+rdma-bnxt_re-disable-kill-tasklet-only-if-it-is-enab.patch
+rdma-bnxt_re-fix-to-remove-unnecessary-return-labels.patch
+rdma-bnxt_re-use-unique-names-while-registering-inte.patch
+rdma-bnxt_re-remove-a-redundant-check-inside-bnxt_re.patch
+rdma-bnxt_re-fix-to-remove-an-unnecessary-log.patch
+drm-msm-dsi-don-t-allow-enabling-14nm-vco-with-unpro.patch
+drm-msm-disp-dpu-get-timing-engine-status-from-intf-.patch
+drm-msm-dpu-set-dpu_data_hctl_en-for-in-intf_sc7180_.patch
+drm-nouveau-dispnv50-fix-missing-prototypes-warning.patch
+iommu-virtio-detach-domain-on-endpoint-release.patch
+iommu-virtio-return-size-mapped-for-a-detached-domai.patch
+clk-renesas-rzg2l-fix-cpg_sipll5_clk1-register-write.patch
+arm-dts-gta04-move-model-property-out-of-pinctrl-nod.patch
+drm-bridge-anx7625-prevent-endless-probe-loop.patch
+arm-mfd-gpio-fixup-tps65010-regression-on-omap1-osk1.patch
+arm-omap1-drop-header-on-ams-delta.patch
+arm-omap1-remove-reliance-on-gpio-numbers-from-palmt.patch
+arm-omap1-remove-reliance-on-gpio-numbers-from-sx1.patch
+arm-mmc-convert-old-mmci-omap-to-gpio-descriptors.patch
+arm-omap1-exorcise-the-legacy-gpio-header.patch
+arm-musb-omap2-remove-global-gpio-numbers-from-tusb6.patch
+arm-dts-qcom-msm8974-do-not-use-underscore-in-node-n.patch
+arm64-dts-qcom-pm8998-don-t-use-gic_spi-for-spmi-int.patch
+arm64-dts-qcom-ipq6018-correct-qrng-unit-address.patch
+arm64-dts-qcom-msm8916-correct-camss-unit-address.patch
+arm64-dts-qcom-msm8916-correct-mmc-unit-address.patch
+arm64-dts-qcom-msm8916-move-wcn-compatible-to-boards.patch
+arm64-dts-qcom-msm8916-correct-wcnss-unit-address.patch
+arm64-dts-qcom-msm8953-correct-iommu-unit-address.patch
+arm64-dts-qcom-msm8976-correct-mmc-unit-address.patch
+arm64-dts-qcom-msm8994-correct-spmi-unit-address.patch
+arm64-dts-qcom-msm8996-correct-camss-unit-address.patch
+arm64-dts-qcom-sdm630-correct-camss-unit-address.patch
+arm64-dts-qcom-sdm845-correct-camss-unit-address.patch
+arm64-dts-qcom-sm6115-correct-thermal-sensor-unit-ad.patch
+arm64-dts-qcom-sm8350-correct-dma-controller-unit-ad.patch
+arm64-dts-qcom-sm8350-correct-pci-phy-unit-address.patch
+arm64-dts-qcom-sm8550-add-qce-ip-family-compatible-v.patch
+arm64-dts-qcom-sm8550-correct-crypto-unit-address.patch
+arm64-dts-qcom-sm8550-correct-pinctrl-unit-address.patch
+arm64-dts-qcom-sdm845-polaris-add-missing-touchscree.patch
+arm64-dts-qcom-apq8016-sbc-fix-regulator-constraints.patch
+arm64-dts-qcom-apq8016-sbc-fix-1.8v-power-rail-on-ls.patch
+drm-bridge-ti-sn65dsi83-fix-enable-disable-flow-to-m.patch
+drm-panel-simple-fix-active-size-for-ampire-am-48027.patch
+arm-ep93xx-fix-missing-prototype-warnings.patch
+arm-omap2-fix-missing-tick_broadcast-prototype.patch
+arm64-dts-qcom-pm7250b-add-missing-spmi-vadc-include.patch
+arm64-dts-qcom-apq8096-fix-fixed-regulator-name-prop.patch
+arm64-dts-mediatek-mt8183-add-mediatek-broken-save-r.patch
+arm-dts-stm32-shorten-the-av96-hdmi-sound-card-name.patch
+memory-brcmstb_dpfe-fix-testing-array-offset-after-u.patch
+arm-dts-qcom-apq8074-dragonboard-set-dma-as-remotely.patch
+asoc-es8316-increment-max-value-for-alc-capture-targ.patch
+asoc-es8316-do-not-set-rate-constraints-for-unsuppor.patch
+arm-dts-meson8-correct-uart_b-and-uart_c-clock-refer.patch
+soc-fsl-qe-fix-usb.c-build-errors.patch
+rdma-irdma-avoid-fortify-string-warning-in-irdma_clr.patch
+ib-hfi1-fix-wrong-mmu_node-used-for-user-sdma-packet.patch
+rdma-hns-fix-hns_roce_table_get-return-value.patch
+arm-dts-iwg20d-q7-common-fix-backlight-pwm-specifier.patch
+arm64-dts-renesas-ulcb-kf-remove-flow-control-for-sc.patch
+drm-msm-dpu-set-dsc-flush-bit-correctly-at-mdp-ctl-f.patch
+drm-msm-dpu-always-clear-every-individual-pending-fl.patch
+fbdev-omapfb-lcd_mipid-fix-an-error-handling-path-in.patch
+arm64-dts-ti-k3-j7200-fix-physical-address-of-pin.patch
+input-pm8941-powerkey-fix-debounce-on-gen2-pmics.patch
+arm-dts-stm32-fix-audio-routing-on-stm32mp15xx-dhcom.patch
+arm-dts-stm32-fix-i2s-endpoint-format-property-for-s.patch
+hwmon-gsc-hwmon-fix-fan-pwm-temperature-scaling.patch
+hwmon-pmbus-adm1275-fix-problems-with-temperature-mo.patch
+arm-dts-bcm5301x-fix-duplex-full-full-duplex.patch
+clk-export-clk_hw_forward_rate_request.patch
+mips-dts-ci20-fix-act8600-regulator-node-names.patch
+drm-amd-display-fix-a-test-calculateprefetchschedule.patch
+drm-amd-display-fix-a-test-dml32_rq_dlg_get_rq_reg.patch
+drm-amdkfd-fix-potential-deallocation-of-previously-.patch
+soc-mediatek-svs-fix-mt8192-gpu-node-name.patch
+drm-amd-display-fix-artifacting-on-edp-panels-when-e.patch
+drm-radeon-fix-possible-division-by-zero-errors.patch
+hid-uclogic-modular-kunit-tests-should-not-depend-on.patch
+rdma-rxe-fix-access-checks-in-rxe_check_bind_mw.patch
+amdgpu-validate-offset_in_bo-of-drm_amdgpu_gem_va.patch
+drm-msm-a6xx-don-t-set-io_pgtable_quirk_arm_outer_wb.patch
+drm-msm-a5xx-really-check-for-a510-in-a5xx_gpu_init.patch
+rdma-bnxt_re-wraparound-mbox-producer-index.patch
+rdma-bnxt_re-avoid-calling-wake_up-threads-from-spin.patch
+clk-imx-clk-imxrt1050-fix-memory-leak-in-imxrt1050_c.patch
+clk-imx-clk-imx8mn-fix-memory-leak-in-imx8mn_clocks_.patch
+clk-imx93-fix-memory-leak-and-missing-unwind-goto-in.patch
+clk-imx-clk-imx8mp-improve-error-handling-in-imx8mp_.patch
+clk-mediatek-fix-of_iomap-memory-leak.patch
+arm64-dts-qcom-qdu1000-flush-rsc-sleep-wake-votes.patch
+arm64-dts-qcom-sdm670-flush-rsc-sleep-wake-votes.patch
+arm64-dts-qcom-sdm845-flush-rsc-sleep-wake-votes.patch
+arm64-dts-qcom-sm8550-flush-rsc-sleep-wake-votes.patch
+arm64-dts-qcom-sm8250-edo-panel-framebuffer-is-2.5k-.patch
+arm64-dts-qcom-sm8550-add-missing-interconnect-path-.patch
+clk-bcm-rpi-fix-off-by-one-in-raspberrypi_discover_c.patch
+clk-clocking-wizard-fix-oops-in-clk_wzrd_register_di.patch
+clk-tegra-tegra124-emc-fix-potential-memory-leak.patch
+arm64-dts-ti-k3-j721e-beagleboneai64-fix-mailbox-nod.patch
+arm64-dts-ti-k3-j784s4-evm-fix-main_i2c0-alias.patch
+arm64-dts-ti-k3-j784s4-evm-enable-mcu-cpsw2g.patch
+arm64-dts-ti-k3-j784s4-fix-wakeup-pinmux-range-and-p.patch
+arm64-dts-ti-k3-am69-sk-fix-main_i2c0-alias.patch
+alsa-ac97-fix-possible-null-dereference-in-snd_ac97_.patch
+drm-msm-dpu-do-not-enable-color-management-if-dspps-.patch
+drm-msm-dpu-fix-slice_last_group_size-calculation.patch
+drm-msm-dsi-remove-incorrect-references-to-slice_cou.patch
+drm-msm-dp-drop-aux-devices-together-with-dp-control.patch
+drm-msm-dp-free-resources-after-unregistering-them.patch
+arm64-dts-mediatek-add-cpufreq-nodes-for-mt8192.patch
+arm64-dts-mediatek-mt8192-fix-cpus-capacity-dmips-mh.patch
+arm64-dts-mt7986-increase-bl2-partition-on-nand-of-b.patch
+drm-amdgpu-fix-memcpy-in-sienna_cichlid_append_power.patch
+drm-amdgpu-fix-usage-of-umc-fill-record-in-ras.patch
+drm-msm-dpu-correct-merge_3d-length.patch
+clk-mediatek-clk-mt8173-apmixedsys-fix-return-value-.patch
+clk-mediatek-clk-mt8173-apmixedsys-fix-iomap-not-rel.patch
+clk-vc5-check-memory-returned-by-kasprintf.patch
+clk-cdce925-check-return-value-of-kasprintf.patch
+clk-si5341-return-error-if-one-synth-clock-registrat.patch
+clk-si5341-check-return-value-of-devm_-kasprintf.patch
+clk-si5341-free-unused-memory-on-probe-failure.patch
+clk-keystone-sci-clk-check-return-value-of-kasprintf.patch
+clk-ti-clkctrl-check-return-value-of-kasprintf.patch
+drivers-meson-secure-pwrc-always-enable-dma-domain.patch
+ovl-update-of-dentry-revalidate-flags-after-copy-up.patch
+asoc-imx-audmix-check-return-value-of-devm_kasprintf.patch
+clk-fix-memory-leak-in-devm_clk_notifier_register.patch
+arm-dts-lan966x-kontron-d10-fix-board-reset.patch
+arm-dts-lan966x-kontron-d10-fix-spi-cs.patch
+asoc-amd-acp-clear-pdm-dma-interrupt-mask.patch
+mips-dts-ci20-add-parent-supplies-to-act8600-regulat.patch
+mips-dts-ci20-raise-vddcore-voltage-to-1.125-volts.patch
+iommufd-do-not-access-the-area-pointer-after-unlocki.patch
+iommufd-call-iopt_area_contig_done-under-the-lock.patch
+pci-cadence-fix-gen2-link-retraining-process.patch
+pci-vmd-reset-vmd-config-register-between-soft-reboo.patch
+scsi-qedf-fix-null-dereference-in-error-handling.patch
+pinctrl-bcm2835-handle-gpiochip_add_pin_range-errors.patch
+platform-x86-lenovo-yogabook-fix-work-race-on-remove.patch
+platform-x86-lenovo-yogabook-reprobe-devices-on-remo.patch
+platform-x86-lenovo-yogabook-set-default-keyboard-ba.patch
+pci-aspm-disable-aspm-on-mfd-function-removal-to-avo.patch
+scsi-3w-xxxx-add-error-handling-for-initialization-f.patch
+pinctrl-at91-don-t-mix-non-devm-calls-with-devm-ones.patch
+pinctrl-at91-use-dev_err_probe-instead-of-custom-mes.patch
+pinctrl-at91-fix-a-couple-null-vs-is_err-checks.patch
+pci-pciehp-cancel-bringup-sequence-if-card-is-not-pr.patch
+perf-evsel-don-t-let-for_each_group-treat-the-head-o.patch
+pci-ftpci100-release-the-clock-resources.patch
+pinctrl-sunplus-add-check-for-kmalloc.patch
+scsi-ufs-declare-ufshcd_-hold-release-once.patch
+pci-add-pci_clear_master-stub-for-non-config_pci.patch
+scsi-lpfc-revise-npiv-els-unsol-rcv-cmpl-logic-to-dr.patch
+scsi-ufs-core-increase-the-start-stop-unit-timeout-f.patch
+scsi-ufs-core-fix-handling-of-lrbp-cmd.patch
+pinctrl-tegra-duplicate-pinmux-functions-table.patch
+perf-bench-add-missing-setlocale-call-to-allow-usage.patch
+pinctrl-cherryview-return-correct-value-if-pin-in-pu.patch
+platform-x86-intel-pmc-remove-meteor-lake-s-platform.patch
+platform-x86-think-lmi-mutex-protection-around-multi.patch
+platform-x86-think-lmi-correct-system-password-inter.patch
+platform-x86-think-lmi-correct-nvme-password-handlin.patch
+pinctrl-sunplus-add-check-for-kmalloc.patch-4157
+pinctrl-npcm7xx-add-missing-check-for-ioremap.patch
+kcsan-don-t-expect-64-bits-atomic-builtins-from-32-b.patch
+powerpc-interrupt-don-t-read-msr-from-interrupt_exit.patch
+powerpc-signal32-force-inlining-of-__unsafe_save_use.patch
+perf-script-fix-allocation-of-evsel-priv-related-to-.patch
+platform-x86-thinkpad_acpi-fix-lkp-tests-warnings-fo.patch
+perf-dwarf-aux-fix-off-by-one-in-die_get_varname.patch
+perf-tests-task_analyzer-fix-bad-substitution-1.patch
+perf-tests-task_analyzer-skip-tests-if-no-libtraceev.patch
+platform-x86-dell-dell-rbtn-fix-resources-leaking-on.patch
+perf-tool-x86-consolidate-is_amd-check-into-single-f.patch
+perf-tool-x86-fix-perf_env-memory-leak.patch
+powerpc-64s-fix-vas-mm-use-after-free.patch
+pinctrl-freescale-fix-a-memory-out-of-bounds-when-nu.patch
+pinctrl-microchip-sgpio-check-return-value-of-devm_k.patch
+pinctrl-at91-pio4-check-return-value-of-devm_kasprin.patch
+perf-stat-reset-aggr-stats-for-each-run.patch
+scsi-ufs-core-remove-a-ufshcd_add_command_trace-call.patch
+scsi-ufs-core-mcq-fix-the-incorrect-ocs-value-for-th.patch
+powerpc-powernv-sriov-perform-null-check-on-iov-befo.patch
+powerpc-update-ppc_save_regs-to-save-current-r1-in-p.patch
+pci-qcom-remove-pcie20_-prefix-from-register-definit.patch
+pci-qcom-sort-and-group-registers-and-bitfield-defin.patch
+pci-qcom-use-lower-case-for-hex.patch
+pci-qcom-use-dwc-helpers-for-modifying-the-read-only.patch
+pci-qcom-disable-write-access-to-read-only-registers.patch
+platform-x86-intel-pmc-update-maps-for-meteor-lake-p.patch
+riscv-uprobes-restore-thread.bad_cause.patch
+powerpc-book3s64-mm-fix-directmap-stats-in-proc-memi.patch
+powerpc-mm-dax-fix-the-condition-when-checking-if-al.patch
+perf-test-set-perf_exec_path-for-script-execution.patch
+pci-endpoint-fix-a-kconfig-prompt-of-vntb-driver.patch
+pci-endpoint-functions-pci-epf-test-fix-dma_chan-dir.patch
+pci-vmd-fix-uninitialized-variable-usage-in-vmd_enab.patch
+vfio-mdev-move-the-compat_class-initialization-to-mo.patch
+hwrng-virtio-fix-race-on-data_avail-and-actual-data.patch
+modpost-remove-broken-calculation-of-exception_table.patch
+crypto-nx-fix-build-warnings-when-debug_fs-is-not-en.patch
+modpost-fix-section-mismatch-message-for-r_arm_abs32.patch
+modpost-fix-section-mismatch-message-for-r_arm_-pc24.patch
+crypto-marvell-cesa-fix-type-mismatch-warning.patch
+crypto-jitter-correct-health-test-during-initializat.patch
+modpost-fix-off-by-one-in-is_executable_section.patch
+arc-define-asm_nl-and-__align-_str-outside-ifdef-__a.patch
+crypto-qat-unmap-buffer-before-free-for-dh.patch
+crypto-qat-unmap-buffers-before-free-for-rsa.patch
+nfsv4.2-fix-wrong-shrinker_id.patch
+nfsv4.1-freeze-the-session-table-upon-receiving-nfs4.patch
+smb3-do-not-send-lease-break-acknowledgment-if-all-f.patch
+dax-fix-dax_mapping_release-use-after-free.patch
+dax-introduce-alloc_dev_dax_id.patch
+dax-kmem-pass-valid-argument-to-memory_group_registe.patch
+hwrng-st-keep-clock-enabled-while-hwrng-is-registere.patch
+i2c-omap-improve-error-reporting-for-problems-during.patch
+i2c-convert-to-platform-remove-callback-returning-vo.patch
+i2c-ocores-use-devm_-managed-clks.patch
+kbuild-fix-cfi-failures-with-gcov.patch
+kbuild-disable-gcov-for-.mod.o.patch
+cxl-region-move-cache-invalidation-before-region-tea.patch
+cxl-region-flag-partially-torn-down-regions-as-unusa.patch
+cxl-region-fix-state-transitions-after-reset-failure.patch
+kbuild-builddeb-always-make-modules_install-to-insta.patch
+kbuild-deb-pkg-remove-the-config_modules-check-in-bu.patch
+efi-libstub-disable-pci-dma-before-grabbing-the-efi-.patch
+cifs-prevent-use-after-free-by-freeing-the-cfile-lat.patch
+cifs-do-all-necessary-checks-for-credits-within-or-b.patch
+smb-client-fix-broken-file-attrs-with-nodfs-mounts.patch
+smb-client-fix-shared-dfs-root-mounts-with-different.patch
+ksmbd-avoid-field-overflow-warning.patch
+arm64-sme-use-str-p-to-clear-ffr-context-field-in-st.patch
+x86-efi-make-efi_set_virtual_address_map-ibt-safe.patch
--- /dev/null
+From 26c5b78823e024d825287c9c4f8e7abe09fafad7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Jun 2023 15:34:48 +0100
+Subject: sfc: fix crash when reading stats while NIC is resetting
+
+From: Edward Cree <ecree.xilinx@gmail.com>
+
+[ Upstream commit d1b355438b8325a486f087e506d412c4e852f37b ]
+
+efx_net_stats() (.ndo_get_stats64) can be called during an ethtool
+ selftest, during which time nic_data->mc_stats is NULL as the NIC has
+ been fini'd. In this case do not attempt to fetch the latest stats
+ from the hardware, else we will crash on a NULL dereference:
+ BUG: kernel NULL pointer dereference, address: 0000000000000038
+ RIP efx_nic_update_stats
+ abridged calltrace:
+ efx_ef10_update_stats_pf
+ efx_net_stats
+ dev_get_stats
+ dev_seq_printf_stats
+Skipping the read is safe, we will simply give out stale stats.
+To ensure that the free in efx_ef10_fini_nic() does not race against
+ efx_ef10_update_stats_pf(), which could cause a TOCTTOU bug, take the
+ efx->stats_lock in fini_nic (it is already held across update_stats).
+
+Fixes: d3142c193dca ("sfc: refactor EF10 stats handling")
+Reviewed-by: Pieter Jansen van Vuuren <pieter.jansen-van-vuuren@amd.com>
+Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/sfc/ef10.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
+index b63e47af63655..8c019f382a7f3 100644
+--- a/drivers/net/ethernet/sfc/ef10.c
++++ b/drivers/net/ethernet/sfc/ef10.c
+@@ -1297,8 +1297,10 @@ static void efx_ef10_fini_nic(struct efx_nic *efx)
+ {
+ struct efx_ef10_nic_data *nic_data = efx->nic_data;
+
++ spin_lock_bh(&efx->stats_lock);
+ kfree(nic_data->mc_stats);
+ nic_data->mc_stats = NULL;
++ spin_unlock_bh(&efx->stats_lock);
+ }
+
+ static int efx_ef10_init_nic(struct efx_nic *efx)
+@@ -1852,9 +1854,14 @@ static size_t efx_ef10_update_stats_pf(struct efx_nic *efx, u64 *full_stats,
+
+ efx_ef10_get_stat_mask(efx, mask);
+
+- efx_nic_copy_stats(efx, nic_data->mc_stats);
+- efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT,
+- mask, stats, nic_data->mc_stats, false);
++ /* If NIC was fini'd (probably resetting), then we can't read
++ * updated stats right now.
++ */
++ if (nic_data->mc_stats) {
++ efx_nic_copy_stats(efx, nic_data->mc_stats);
++ efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT,
++ mask, stats, nic_data->mc_stats, false);
++ }
+
+ /* Update derived statistics */
+ efx_nic_fix_nodesc_drop_stat(efx,
+--
+2.39.2
+
--- /dev/null
+From dffc0360e6d90f2afced6810b1ad9736823723b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jun 2023 21:24:49 -0300
+Subject: smb: client: fix broken file attrs with nodfs mounts
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit d439b29057e26464120fc6c18f97433aa003b5fe ]
+
+*_get_inode_info() functions expect -EREMOTE when query path info
+calls find a DFS link, regardless whether !CONFIG_CIFS_DFS_UPCALL or
+'nodfs' mount option. Otherwise, those files will miss the fake DFS
+file attributes.
+
+Before patch
+
+ $ mount.cifs //srv/dfs /mnt/1 -o ...,nodfs
+ $ ls -l /mnt/1
+ ls: cannot access '/mnt/1/link': Operation not supported
+ total 0
+ -rwxr-xr-x 1 root root 0 Jul 26 2022 dfstest2_file1.txt
+ drwxr-xr-x 2 root root 0 Aug 8 2022 dir1
+ d????????? ? ? ? ? ? link
+
+After patch
+
+ $ mount.cifs //srv/dfs /mnt/1 -o ...,nodfs
+ $ ls -l /mnt/1
+ total 0
+ -rwxr-xr-x 1 root root 0 Jul 26 2022 dfstest2_file1.txt
+ drwxr-xr-x 2 root root 0 Aug 8 2022 dir1
+ drwx--x--x 2 root root 0 Jun 26 20:29 link
+
+Fixes: c877ce47e137 ("cifs: reduce roundtrips on create/qinfo requests")
+Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2inode.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
+index 7e3ac4cb4efa6..8e696fbd72fa8 100644
+--- a/fs/cifs/smb2inode.c
++++ b/fs/cifs/smb2inode.c
+@@ -609,9 +609,6 @@ int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+ if (islink)
+ rc = -EREMOTE;
+ }
+- if (rc == -EREMOTE && IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) && cifs_sb &&
+- (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS))
+- rc = -EOPNOTSUPP;
+ }
+
+ out:
+--
+2.39.2
+
--- /dev/null
+From 75074d4ebb2eec97e5da6c30c51dd714e8fc8099 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 16:04:17 -0300
+Subject: smb: client: fix shared DFS root mounts with different prefixes
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit 3ae872de410751fe5e629e04da491a632d95201c ]
+
+When having two DFS root mounts that are connected to same namespace,
+same mount options but different prefix paths, we can't really use the
+shared @server->origin_fullpath when chasing DFS links in them.
+
+Move the origin_fullpath field to cifs_tcon structure so when having
+shared DFS root mounts with different prefix paths, and we need to
+chase any DFS links, dfs_get_automount_devname() will pick up the
+correct full path out of the @tcon that will be used for the new
+mount.
+
+Before patch
+
+ mount.cifs //dom/dfs/dir /mnt/1 -o ...
+ mount.cifs //dom/dfs /mnt/2 -o ...
+ # shared server, ses, tcon
+ # server: origin_fullpath=//dom/dfs/dir
+
+ # @server->origin_fullpath + '/dir/link1'
+ $ ls /mnt/2/dir/link1
+ ls: cannot open directory '/mnt/2/dir/link1': No such file or directory
+
+After patch
+
+ mount.cifs //dom/dfs/dir /mnt/1 -o ...
+ mount.cifs //dom/dfs /mnt/2 -o ...
+ # shared server & ses
+ # tcon_1: origin_fullpath=//dom/dfs/dir
+ # tcon_2: origin_fullpath=//dom/dfs
+
+ # @tcon_2->origin_fullpath + '/dir/link1'
+ $ ls /mnt/2/dir/link1
+ dir0 dir1 dir10 dir3 dir5 dir6 dir7 dir9 target2_file.txt tsub
+
+Fixes: 8e3554150d6c ("cifs: fix sharing of DFS connections")
+Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/cifs_debug.c | 16 +++++-----
+ fs/cifs/cifsglob.h | 10 +++----
+ fs/cifs/cifsproto.h | 2 +-
+ fs/cifs/connect.c | 70 +++++++++++++++++++++++++-------------------
+ fs/cifs/dfs.c | 55 +++++++++++++---------------------
+ fs/cifs/dfs.h | 19 ++++++------
+ fs/cifs/dfs_cache.c | 8 +++--
+ fs/cifs/misc.c | 38 ++++++++++++++++++------
+ 8 files changed, 118 insertions(+), 100 deletions(-)
+
+diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
+index d4ed200a94714..7e0667bdfba07 100644
+--- a/fs/cifs/cifs_debug.c
++++ b/fs/cifs/cifs_debug.c
+@@ -121,6 +121,12 @@ static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon)
+ seq_puts(m, " nosparse");
+ if (tcon->need_reconnect)
+ seq_puts(m, "\tDISCONNECTED ");
++ spin_lock(&tcon->tc_lock);
++ if (tcon->origin_fullpath) {
++ seq_printf(m, "\n\tDFS origin fullpath: %s",
++ tcon->origin_fullpath);
++ }
++ spin_unlock(&tcon->tc_lock);
+ seq_putc(m, '\n');
+ }
+
+@@ -377,13 +383,9 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
+ seq_printf(m, "\nIn Send: %d In MaxReq Wait: %d",
+ atomic_read(&server->in_send),
+ atomic_read(&server->num_waiters));
+- if (IS_ENABLED(CONFIG_CIFS_DFS_UPCALL)) {
+- if (server->origin_fullpath)
+- seq_printf(m, "\nDFS origin full path: %s",
+- server->origin_fullpath);
+- if (server->leaf_fullpath)
+- seq_printf(m, "\nDFS leaf full path: %s",
+- server->leaf_fullpath);
++ if (server->leaf_fullpath) {
++ seq_printf(m, "\nDFS leaf full path: %s",
++ server->leaf_fullpath);
+ }
+
+ seq_printf(m, "\n\n\tSessions: ");
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index 5f8fd20951af3..56d440772e029 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -736,23 +736,20 @@ struct TCP_Server_Info {
+ #endif
+ struct mutex refpath_lock; /* protects leaf_fullpath */
+ /*
+- * origin_fullpath: Canonical copy of smb3_fs_context::source.
+- * It is used for matching existing DFS tcons.
+- *
+ * leaf_fullpath: Canonical DFS referral path related to this
+ * connection.
+ * It is used in DFS cache refresher, reconnect and may
+ * change due to nested DFS links.
+ *
+- * Both protected by @refpath_lock and @srv_lock. The @refpath_lock is
+- * mosly used for not requiring a copy of @leaf_fullpath when getting
++ * Protected by @refpath_lock and @srv_lock. The @refpath_lock is
++ * mostly used for not requiring a copy of @leaf_fullpath when getting
+ * cached or new DFS referrals (which might also sleep during I/O).
+ * While @srv_lock is held for making string and NULL comparions against
+ * both fields as in mount(2) and cache refresh.
+ *
+ * format: \\HOST\SHARE[\OPTIONAL PATH]
+ */
+- char *origin_fullpath, *leaf_fullpath;
++ char *leaf_fullpath;
+ };
+
+ static inline bool is_smb1(struct TCP_Server_Info *server)
+@@ -1242,6 +1239,7 @@ struct cifs_tcon {
+ struct delayed_work dfs_cache_work;
+ #endif
+ struct delayed_work query_interfaces; /* query interfaces workqueue job */
++ char *origin_fullpath; /* canonical copy of smb3_fs_context::source */
+ };
+
+ /*
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+index c1c704990b986..16eac67fd48ac 100644
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -649,7 +649,7 @@ int smb2_parse_query_directory(struct cifs_tcon *tcon, struct kvec *rsp_iov,
+ int resp_buftype,
+ struct cifs_search_info *srch_inf);
+
+-struct super_block *cifs_get_tcp_super(struct TCP_Server_Info *server);
++struct super_block *cifs_get_dfs_tcon_super(struct cifs_tcon *tcon);
+ void cifs_put_tcp_super(struct super_block *sb);
+ int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix);
+ char *extract_hostname(const char *unc);
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 1250d156619b7..f0189afd940cf 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -996,7 +996,6 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
+ */
+ }
+
+- kfree(server->origin_fullpath);
+ kfree(server->leaf_fullpath);
+ kfree(server);
+
+@@ -1386,7 +1385,9 @@ match_security(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ }
+
+ /* this function must be called with srv_lock held */
+-static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
++static int match_server(struct TCP_Server_Info *server,
++ struct smb3_fs_context *ctx,
++ bool match_super)
+ {
+ struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;
+
+@@ -1417,36 +1418,38 @@ static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *
+ (struct sockaddr *)&server->srcaddr))
+ return 0;
+ /*
+- * - Match for an DFS tcon (@server->origin_fullpath).
+- * - Match for an DFS root server connection (@server->leaf_fullpath).
+- * - If none of the above and @ctx->leaf_fullpath is set, then
+- * it is a new DFS connection.
+- * - If 'nodfs' mount option was passed, then match only connections
+- * that have no DFS referrals set
+- * (e.g. can't failover to other targets).
++ * When matching cifs.ko superblocks (@match_super == true), we can't
++ * really match either @server->leaf_fullpath or @server->dstaddr
++ * directly since this @server might belong to a completely different
++ * server -- in case of domain-based DFS referrals or DFS links -- as
++ * provided earlier by mount(2) through 'source' and 'ip' options.
++ *
++ * Otherwise, match the DFS referral in @server->leaf_fullpath or the
++ * destination address in @server->dstaddr.
++ *
++ * When using 'nodfs' mount option, we avoid sharing it with DFS
++ * connections as they might failover.
+ */
+- if (!ctx->nodfs) {
+- if (ctx->source && server->origin_fullpath) {
+- if (!dfs_src_pathname_equal(ctx->source,
+- server->origin_fullpath))
++ if (!match_super) {
++ if (!ctx->nodfs) {
++ if (server->leaf_fullpath) {
++ if (!ctx->leaf_fullpath ||
++ strcasecmp(server->leaf_fullpath,
++ ctx->leaf_fullpath))
++ return 0;
++ } else if (ctx->leaf_fullpath) {
+ return 0;
++ }
+ } else if (server->leaf_fullpath) {
+- if (!ctx->leaf_fullpath ||
+- strcasecmp(server->leaf_fullpath,
+- ctx->leaf_fullpath))
+- return 0;
+- } else if (ctx->leaf_fullpath) {
+ return 0;
+ }
+- } else if (server->origin_fullpath || server->leaf_fullpath) {
+- return 0;
+ }
+
+ /*
+ * Match for a regular connection (address/hostname/port) which has no
+ * DFS referrals set.
+ */
+- if (!server->origin_fullpath && !server->leaf_fullpath &&
++ if (!server->leaf_fullpath &&
+ (strcasecmp(server->hostname, ctx->server_hostname) ||
+ !match_server_address(server, addr) ||
+ !match_port(server, addr)))
+@@ -1482,7 +1485,8 @@ cifs_find_tcp_session(struct smb3_fs_context *ctx)
+ * Skip ses channels since they're only handled in lower layers
+ * (e.g. cifs_send_recv).
+ */
+- if (CIFS_SERVER_IS_CHAN(server) || !match_server(server, ctx)) {
++ if (CIFS_SERVER_IS_CHAN(server) ||
++ !match_server(server, ctx, false)) {
+ spin_unlock(&server->srv_lock);
+ continue;
+ }
+@@ -2270,10 +2274,16 @@ static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
+
+ if (tcon->status == TID_EXITING)
+ return 0;
+- /* Skip UNC validation when matching DFS connections or superblocks */
+- if (!server->origin_fullpath && !server->leaf_fullpath &&
+- strncmp(tcon->tree_name, ctx->UNC, MAX_TREE_SIZE))
++
++ if (tcon->origin_fullpath) {
++ if (!ctx->source ||
++ !dfs_src_pathname_equal(ctx->source,
++ tcon->origin_fullpath))
++ return 0;
++ } else if (!server->leaf_fullpath &&
++ strncmp(tcon->tree_name, ctx->UNC, MAX_TREE_SIZE)) {
+ return 0;
++ }
+ if (tcon->seal != ctx->seal)
+ return 0;
+ if (tcon->snapshot_time != ctx->snapshot_time)
+@@ -2672,7 +2682,7 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
+ }
+
+ static int match_prepath(struct super_block *sb,
+- struct TCP_Server_Info *server,
++ struct cifs_tcon *tcon,
+ struct cifs_mnt_data *mnt_data)
+ {
+ struct smb3_fs_context *ctx = mnt_data->ctx;
+@@ -2683,8 +2693,8 @@ static int match_prepath(struct super_block *sb,
+ bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
+ new->prepath;
+
+- if (server->origin_fullpath &&
+- dfs_src_pathname_equal(server->origin_fullpath, ctx->source))
++ if (tcon->origin_fullpath &&
++ dfs_src_pathname_equal(tcon->origin_fullpath, ctx->source))
+ return 1;
+
+ if (old_set && new_set && !strcmp(new->prepath, old->prepath))
+@@ -2732,10 +2742,10 @@ cifs_match_super(struct super_block *sb, void *data)
+ spin_lock(&ses->ses_lock);
+ spin_lock(&ses->chan_lock);
+ spin_lock(&tcon->tc_lock);
+- if (!match_server(tcp_srv, ctx) ||
++ if (!match_server(tcp_srv, ctx, true) ||
+ !match_session(ses, ctx) ||
+ !match_tcon(tcon, ctx) ||
+- !match_prepath(sb, tcp_srv, mnt_data)) {
++ !match_prepath(sb, tcon, mnt_data)) {
+ rc = 0;
+ goto out;
+ }
+diff --git a/fs/cifs/dfs.c b/fs/cifs/dfs.c
+index 2390b2fedd6a3..267536a7531df 100644
+--- a/fs/cifs/dfs.c
++++ b/fs/cifs/dfs.c
+@@ -249,14 +249,12 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx)
+ server = mnt_ctx->server;
+ tcon = mnt_ctx->tcon;
+
+- mutex_lock(&server->refpath_lock);
+- spin_lock(&server->srv_lock);
+- if (!server->origin_fullpath) {
+- server->origin_fullpath = origin_fullpath;
++ spin_lock(&tcon->tc_lock);
++ if (!tcon->origin_fullpath) {
++ tcon->origin_fullpath = origin_fullpath;
+ origin_fullpath = NULL;
+ }
+- spin_unlock(&server->srv_lock);
+- mutex_unlock(&server->refpath_lock);
++ spin_unlock(&tcon->tc_lock);
+
+ if (list_empty(&tcon->dfs_ses_list)) {
+ list_replace_init(&mnt_ctx->dfs_ses_list,
+@@ -279,18 +277,13 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)
+ {
+ struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
+ struct cifs_ses *ses;
+- char *source = ctx->source;
+ bool nodfs = ctx->nodfs;
+ int rc;
+
+ *isdfs = false;
+- /* Temporarily set @ctx->source to NULL as we're not matching DFS
+- * superblocks yet. See cifs_match_super() and match_server().
+- */
+- ctx->source = NULL;
+ rc = get_session(mnt_ctx, NULL);
+ if (rc)
+- goto out;
++ return rc;
+
+ ctx->dfs_root_ses = mnt_ctx->ses;
+ /*
+@@ -304,7 +297,7 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)
+ rc = dfs_get_referral(mnt_ctx, ctx->UNC + 1, NULL, NULL);
+ if (rc) {
+ if (rc != -ENOENT && rc != -EOPNOTSUPP && rc != -EIO)
+- goto out;
++ return rc;
+ nodfs = true;
+ }
+ }
+@@ -312,7 +305,7 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)
+ rc = cifs_mount_get_tcon(mnt_ctx);
+ if (!rc)
+ rc = cifs_is_path_remote(mnt_ctx);
+- goto out;
++ return rc;
+ }
+
+ *isdfs = true;
+@@ -328,12 +321,7 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)
+ rc = __dfs_mount_share(mnt_ctx);
+ if (ses == ctx->dfs_root_ses)
+ cifs_put_smb_ses(ses);
+-out:
+- /*
+- * Restore previous value of @ctx->source so DFS superblock can be
+- * matched in cifs_match_super().
+- */
+- ctx->source = source;
++
+ return rc;
+ }
+
+@@ -567,11 +555,11 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
+ int rc;
+ struct TCP_Server_Info *server = tcon->ses->server;
+ const struct smb_version_operations *ops = server->ops;
+- struct super_block *sb = NULL;
+- struct cifs_sb_info *cifs_sb;
+ struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT(tl);
+- char *tree;
++ struct cifs_sb_info *cifs_sb = NULL;
++ struct super_block *sb = NULL;
+ struct dfs_info3_param ref = {0};
++ char *tree;
+
+ /* only send once per connect */
+ spin_lock(&tcon->tc_lock);
+@@ -603,19 +591,18 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
+ goto out;
+ }
+
+- sb = cifs_get_tcp_super(server);
+- if (IS_ERR(sb)) {
+- rc = PTR_ERR(sb);
+- cifs_dbg(VFS, "%s: could not find superblock: %d\n", __func__, rc);
+- goto out;
+- }
+-
+- cifs_sb = CIFS_SB(sb);
++ sb = cifs_get_dfs_tcon_super(tcon);
++ if (!IS_ERR(sb))
++ cifs_sb = CIFS_SB(sb);
+
+- /* If it is not dfs or there was no cached dfs referral, then reconnect to same share */
+- if (!server->leaf_fullpath ||
++ /*
++ * Tree connect to last share in @tcon->tree_name whether dfs super or
++ * cached dfs referral was not found.
++ */
++ if (!cifs_sb || !server->leaf_fullpath ||
+ dfs_cache_noreq_find(server->leaf_fullpath + 1, &ref, &tl)) {
+- rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, tcon, cifs_sb->local_nls);
++ rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, tcon,
++ cifs_sb ? cifs_sb->local_nls : nlsc);
+ goto out;
+ }
+
+diff --git a/fs/cifs/dfs.h b/fs/cifs/dfs.h
+index 1c90df5ecfbda..98e9d2aca6a7a 100644
+--- a/fs/cifs/dfs.h
++++ b/fs/cifs/dfs.h
+@@ -39,16 +39,15 @@ static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page)
+ {
+ struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+- struct TCP_Server_Info *server = tcon->ses->server;
+ size_t len;
+ char *s;
+
+- spin_lock(&server->srv_lock);
+- if (unlikely(!server->origin_fullpath)) {
+- spin_unlock(&server->srv_lock);
++ spin_lock(&tcon->tc_lock);
++ if (unlikely(!tcon->origin_fullpath)) {
++ spin_unlock(&tcon->tc_lock);
+ return ERR_PTR(-EREMOTE);
+ }
+- spin_unlock(&server->srv_lock);
++ spin_unlock(&tcon->tc_lock);
+
+ s = dentry_path_raw(dentry, page, PATH_MAX);
+ if (IS_ERR(s))
+@@ -57,16 +56,16 @@ static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page)
+ if (!s[1])
+ s++;
+
+- spin_lock(&server->srv_lock);
+- len = strlen(server->origin_fullpath);
++ spin_lock(&tcon->tc_lock);
++ len = strlen(tcon->origin_fullpath);
+ if (s < (char *)page + len) {
+- spin_unlock(&server->srv_lock);
++ spin_unlock(&tcon->tc_lock);
+ return ERR_PTR(-ENAMETOOLONG);
+ }
+
+ s -= len;
+- memcpy(s, server->origin_fullpath, len);
+- spin_unlock(&server->srv_lock);
++ memcpy(s, tcon->origin_fullpath, len);
++ spin_unlock(&tcon->tc_lock);
+ convert_delimiter(s, '/');
+
+ return s;
+diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c
+index 1513b2709889b..33adf43a01f1d 100644
+--- a/fs/cifs/dfs_cache.c
++++ b/fs/cifs/dfs_cache.c
+@@ -1248,18 +1248,20 @@ static int refresh_tcon(struct cifs_tcon *tcon, bool force_refresh)
+ int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb)
+ {
+ struct cifs_tcon *tcon;
+- struct TCP_Server_Info *server;
+
+ if (!cifs_sb || !cifs_sb->master_tlink)
+ return -EINVAL;
+
+ tcon = cifs_sb_master_tcon(cifs_sb);
+- server = tcon->ses->server;
+
+- if (!server->origin_fullpath) {
++ spin_lock(&tcon->tc_lock);
++ if (!tcon->origin_fullpath) {
++ spin_unlock(&tcon->tc_lock);
+ cifs_dbg(FYI, "%s: not a dfs mount\n", __func__);
+ return 0;
+ }
++ spin_unlock(&tcon->tc_lock);
++
+ /*
+ * After reconnecting to a different server, unique ids won't match anymore, so we disable
+ * serverino. This prevents dentry revalidation to think the dentry are stale (ESTALE).
+diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
+index cd914be905b24..b0dedc26643b6 100644
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -156,6 +156,7 @@ tconInfoFree(struct cifs_tcon *tcon)
+ #ifdef CONFIG_CIFS_DFS_UPCALL
+ dfs_put_root_smb_sessions(&tcon->dfs_ses_list);
+ #endif
++ kfree(tcon->origin_fullpath);
+ kfree(tcon);
+ }
+
+@@ -1106,20 +1107,25 @@ struct super_cb_data {
+ struct super_block *sb;
+ };
+
+-static void tcp_super_cb(struct super_block *sb, void *arg)
++static void tcon_super_cb(struct super_block *sb, void *arg)
+ {
+ struct super_cb_data *sd = arg;
+- struct TCP_Server_Info *server = sd->data;
+ struct cifs_sb_info *cifs_sb;
+- struct cifs_tcon *tcon;
++ struct cifs_tcon *t1 = sd->data, *t2;
+
+ if (sd->sb)
+ return;
+
+ cifs_sb = CIFS_SB(sb);
+- tcon = cifs_sb_master_tcon(cifs_sb);
+- if (tcon->ses->server == server)
++ t2 = cifs_sb_master_tcon(cifs_sb);
++
++ spin_lock(&t2->tc_lock);
++ if (t1->ses == t2->ses &&
++ t1->ses->server == t2->ses->server &&
++ t2->origin_fullpath &&
++ dfs_src_pathname_equal(t2->origin_fullpath, t1->origin_fullpath))
+ sd->sb = sb;
++ spin_unlock(&t2->tc_lock);
+ }
+
+ static struct super_block *__cifs_get_super(void (*f)(struct super_block *, void *),
+@@ -1145,6 +1151,7 @@ static struct super_block *__cifs_get_super(void (*f)(struct super_block *, void
+ return sd.sb;
+ }
+ }
++ pr_warn_once("%s: could not find dfs superblock\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+@@ -1154,9 +1161,15 @@ static void __cifs_put_super(struct super_block *sb)
+ cifs_sb_deactive(sb);
+ }
+
+-struct super_block *cifs_get_tcp_super(struct TCP_Server_Info *server)
++struct super_block *cifs_get_dfs_tcon_super(struct cifs_tcon *tcon)
+ {
+- return __cifs_get_super(tcp_super_cb, server);
++ spin_lock(&tcon->tc_lock);
++ if (!tcon->origin_fullpath) {
++ spin_unlock(&tcon->tc_lock);
++ return ERR_PTR(-ENOENT);
++ }
++ spin_unlock(&tcon->tc_lock);
++ return __cifs_get_super(tcon_super_cb, tcon);
+ }
+
+ void cifs_put_tcp_super(struct super_block *sb)
+@@ -1238,9 +1251,16 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid,
+ */
+ if (strlen(full_path) < 2 || !cifs_sb ||
+ (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) ||
+- !is_tcon_dfs(tcon) || !ses->server->origin_fullpath)
++ !is_tcon_dfs(tcon))
+ return 0;
+
++ spin_lock(&tcon->tc_lock);
++ if (!tcon->origin_fullpath) {
++ spin_unlock(&tcon->tc_lock);
++ return 0;
++ }
++ spin_unlock(&tcon->tc_lock);
++
+ /*
+ * Slow path - tcon is DFS and @full_path has prefix path, so attempt
+ * to get a referral to figure out whether it is an DFS link.
+@@ -1264,7 +1284,7 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid,
+
+ /*
+ * XXX: we are not using dfs_cache_find() here because we might
+- * end filling all the DFS cache and thus potentially
++ * end up filling all the DFS cache and thus potentially
+ * removing cached DFS targets that the client would eventually
+ * need during failover.
+ */
+--
+2.39.2
+
--- /dev/null
+From 51e2febf4aa11b69ad4b570789f2843b0a6a4953 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Jun 2023 19:02:24 +0000
+Subject: SMB3: Do not send lease break acknowledgment if all file handles have
+ been closed
+
+From: Bharath SM <bharathsm@microsoft.com>
+
+[ Upstream commit da787d5b74983f7525d1eb4b9c0b4aff2821511a ]
+
+In case if all existing file handles are deferred handles and if all of
+them gets closed due to handle lease break then we dont need to send
+lease break acknowledgment to server, because last handle close will be
+considered as lease break ack.
+After closing deferred handels, we check for openfile list of inode,
+if its empty then we skip sending lease break ack.
+
+Fixes: 59a556aebc43 ("SMB3: drop reference to cfile before sending oplock break")
+Reviewed-by: Tom Talpey <tom@talpey.com>
+Signed-off-by: Bharath SM <bharathsm@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/file.c | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 051283386e229..1a854dc204823 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -4936,20 +4936,19 @@ void cifs_oplock_break(struct work_struct *work)
+
+ _cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
+ /*
+- * releasing stale oplock after recent reconnect of smb session using
+- * a now incorrect file handle is not a data integrity issue but do
+- * not bother sending an oplock release if session to server still is
+- * disconnected since oplock already released by the server
++ * MS-SMB2 3.2.5.19.1 and 3.2.5.19.2 (and MS-CIFS 3.2.5.42) do not require
++ * an acknowledgment to be sent when the file has already been closed.
++ * check for server null, since can race with kill_sb calling tree disconnect.
+ */
+- if (!oplock_break_cancelled) {
+- /* check for server null since can race with kill_sb calling tree disconnect */
+- if (tcon->ses && tcon->ses->server) {
+- rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid,
+- volatile_fid, net_fid, cinode);
+- cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
+- } else
+- pr_warn_once("lease break not sent for unmounted share\n");
+- }
++ spin_lock(&cinode->open_file_lock);
++ if (tcon->ses && tcon->ses->server && !oplock_break_cancelled &&
++ !list_empty(&cinode->openFileList)) {
++ spin_unlock(&cinode->open_file_lock);
++ rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid,
++ volatile_fid, net_fid, cinode);
++ cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
++ } else
++ spin_unlock(&cinode->open_file_lock);
+
+ cifs_done_oplock_break(cinode);
+ }
+--
+2.39.2
+
--- /dev/null
+From 2d79ca0f58b04bb9d22c129ff6b5311ce9572c97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 May 2023 15:52:16 -0700
+Subject: soc/fsl/qe: fix usb.c build errors
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 7b1a78babd0d2cd27aa07255dee0c2d7ac0f31e3 ]
+
+Fix build errors in soc/fsl/qe/usb.c when QUICC_ENGINE is not set.
+This happens when PPC_EP88XC is set, which selects CPM1 & CPM.
+When CPM is set, USB_FSL_QE can be set without QUICC_ENGINE
+being set. When USB_FSL_QE is set, QE_USB deafults to y, which
+causes build errors when QUICC_ENGINE is not set. Making
+QE_USB depend on QUICC_ENGINE prevents QE_USB from defaulting to y.
+
+Fixes these build errors:
+
+drivers/soc/fsl/qe/usb.o: in function `qe_usb_clock_set':
+usb.c:(.text+0x1e): undefined reference to `qe_immr'
+powerpc-linux-ld: usb.c:(.text+0x2a): undefined reference to `qe_immr'
+powerpc-linux-ld: usb.c:(.text+0xbc): undefined reference to `qe_setbrg'
+powerpc-linux-ld: usb.c:(.text+0xca): undefined reference to `cmxgcr_lock'
+powerpc-linux-ld: usb.c:(.text+0xce): undefined reference to `cmxgcr_lock'
+
+Fixes: 5e41486c408e ("powerpc/QE: add support for QE USB clocks routing")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: kernel test robot <lkp@intel.com>
+Link: https://lore.kernel.org/all/202301101500.pillNv6R-lkp@intel.com/
+Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Leo Li <leoyang.li@nxp.com>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Nicolas Schier <nicolas@fjasle.eu>
+Cc: Qiang Zhao <qiang.zhao@nxp.com>
+Cc: linuxppc-dev <linuxppc-dev@lists.ozlabs.org>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: Kumar Gala <galak@kernel.crashing.org>
+Acked-by: Nicolas Schier <nicolas@jasle.eu>
+Signed-off-by: Li Yang <leoyang.li@nxp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/qe/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/soc/fsl/qe/Kconfig b/drivers/soc/fsl/qe/Kconfig
+index 357c5800b112f..7afa796dbbb89 100644
+--- a/drivers/soc/fsl/qe/Kconfig
++++ b/drivers/soc/fsl/qe/Kconfig
+@@ -39,6 +39,7 @@ config QE_TDM
+
+ config QE_USB
+ bool
++ depends on QUICC_ENGINE
+ default y if USB_FSL_QE
+ help
+ QE USB Controller support
+--
+2.39.2
+
--- /dev/null
+From a389f8cbd40e4ab2eca749ea8a8d72a16aea6a26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 May 2023 14:35:30 +0800
+Subject: soc: mediatek: SVS: Fix MT8192 GPU node name
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 95094495401bdf6a0649d220dfd095e6079b5e39 ]
+
+Device tree node names should be generic. The planned device node name
+for the GPU, according to the bindings and posted DT changes, is "gpu",
+not "mali".
+
+Fix the GPU node name in the SVS driver to follow.
+
+Fixes: 0bbb09b2af9d ("soc: mediatek: SVS: add mt8192 SVS GPU driver")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Link: https://lore.kernel.org/r/20230531063532.2240038-1-wenst@chromium.org
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/mediatek/mtk-svs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
+index f26eb2f637d52..77d6299774427 100644
+--- a/drivers/soc/mediatek/mtk-svs.c
++++ b/drivers/soc/mediatek/mtk-svs.c
+@@ -2101,9 +2101,9 @@ static int svs_mt8192_platform_probe(struct svs_platform *svsp)
+ svsb = &svsp->banks[idx];
+
+ if (svsb->type == SVSB_HIGH)
+- svsb->opp_dev = svs_add_device_link(svsp, "mali");
++ svsb->opp_dev = svs_add_device_link(svsp, "gpu");
+ else if (svsb->type == SVSB_LOW)
+- svsb->opp_dev = svs_get_subsys_device(svsp, "mali");
++ svsb->opp_dev = svs_get_subsys_device(svsp, "gpu");
+
+ if (IS_ERR(svsb->opp_dev))
+ return dev_err_probe(svsp->dev, PTR_ERR(svsb->opp_dev),
+--
+2.39.2
+
--- /dev/null
+From ccf3708badab664abb0f917d6f980bc9a99cfe8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 10:47:45 +0000
+Subject: spi: dw: Round of n_bytes to power of 2
+
+From: Joy Chakraborty <joychakr@google.com>
+
+[ Upstream commit 9f34baf67e4d08908fd94ff29c825bb673295336 ]
+
+n_bytes variable in the driver represents the number of bytes per word
+that needs to be sent/copied to fifo. Bits/word can be between 8 and 32
+bits from the client but in memory they are a power of 2, same is mentioned
+in spi.h header:
+"
+ * @bits_per_word: Data transfers involve one or more words; word sizes
+ * like eight or 12 bits are common. In-memory wordsizes are
+ * powers of two bytes (e.g. 20 bit samples use 32 bits).
+ * This may be changed by the device's driver, or left at the
+ * default (0) indicating protocol words are eight bit bytes.
+ * The spi_transfer.bits_per_word can override this for each transfer.
+"
+
+Hence, round of n_bytes to a power of 2 to avoid values like 3 which
+would generate unalligned/odd accesses to memory/fifo.
+
+* tested on Baikal-T1 based system with DW SPI-looped back interface
+transferring a chunk of data with DFS:8,12,16.
+
+Fixes: a51acc2400d4 ("spi: dw: Add support for 32-bits max xfer size")
+Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com
+Signed-off-by: Joy Chakraborty <joychakr@google.com
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com
+Tested-by: Serge Semin <fancer.lancer@gmail.com
+Link: https://lore.kernel.org/r/20230512104746.1797865-4-joychakr@google.com
+Signed-off-by: Mark Brown <broonie@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-dw-core.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c
+index c3bfb6c84cab2..4976e3b8923ee 100644
+--- a/drivers/spi/spi-dw-core.c
++++ b/drivers/spi/spi-dw-core.c
+@@ -426,7 +426,10 @@ static int dw_spi_transfer_one(struct spi_controller *master,
+ int ret;
+
+ dws->dma_mapped = 0;
+- dws->n_bytes = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE);
++ dws->n_bytes =
++ roundup_pow_of_two(DIV_ROUND_UP(transfer->bits_per_word,
++ BITS_PER_BYTE));
++
+ dws->tx = (void *)transfer->tx_buf;
+ dws->tx_len = transfer->len / dws->n_bytes;
+ dws->rx = transfer->rx_buf;
+--
+2.39.2
+
--- /dev/null
+From eb5612eb4815518c2a85a96a58343c1b0bcdda6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Apr 2023 14:12:08 +0530
+Subject: spi: spi-geni-qcom: Correct CS_TOGGLE bit in SPI_TRANS_CFG
+
+From: Vijaya Krishna Nivarthi <quic_vnivarth@quicinc.com>
+
+[ Upstream commit 5fd7c99ecf45c8ee8a9b1268f0ffc91cc6271da2 ]
+
+The CS_TOGGLE bit when set is supposed to instruct FW to
+toggle CS line between words. The driver with intent of
+disabling this behaviour has been unsetting BIT(0). This has
+not caused any trouble so far because the original BIT(1)
+is untouched and BIT(0) likely wasn't being used.
+
+Correct this to prevent a potential future bug.
+
+Signed-off-by: Vijaya Krishna Nivarthi <quic_vnivarth@quicinc.com
+Acked-by: Konrad Dybcio <konrad.dybcio@linaro.org
+Fixes: 561de45f72bd ("spi: spi-geni-qcom: Add SPI driver support for GENI based QUP")
+Reviewed-by: Douglas Anderson <dianders@chromium.org
+Link: https://lore.kernel.org/r/1682412128-1913-1-git-send-email-quic_vnivarth@quicinc.com
+Signed-off-by: Mark Brown <broonie@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-geni-qcom.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
+index baf477383682d..d147519fe1089 100644
+--- a/drivers/spi/spi-geni-qcom.c
++++ b/drivers/spi/spi-geni-qcom.c
+@@ -35,7 +35,7 @@
+ #define CS_DEMUX_OUTPUT_SEL GENMASK(3, 0)
+
+ #define SE_SPI_TRANS_CFG 0x25c
+-#define CS_TOGGLE BIT(0)
++#define CS_TOGGLE BIT(1)
+
+ #define SE_SPI_WORD_LEN 0x268
+ #define WORD_LEN_MSK GENMASK(9, 0)
+--
+2.39.2
+
--- /dev/null
+From a2b12dc62b9203747c1818b271e81817c4da22c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 16:03:38 +0200
+Subject: splice: don't call file_accessed in copy_splice_read
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 0b24be4691c9e6ea13ca70050d42a9f9032fa788 ]
+
+copy_splice_read calls into ->read_iter to read the data, which already
+calls file_accessed.
+
+Fixes: 33b3b041543e ("splice: Add a func to do a splice from an O_DIRECT file without ITER_PIPE")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Reviewed-by: David Howells <dhowells@redhat.com>
+Link: https://lore.kernel.org/r/20230614140341.521331-2-hch@lst.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/splice.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/fs/splice.c b/fs/splice.c
+index 2c3dec2b6dfaf..5eca589fe8479 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -338,7 +338,6 @@ ssize_t direct_splice_read(struct file *in, loff_t *ppos,
+ reclaim -= ret;
+ remain = ret;
+ *ppos = kiocb.ki_pos;
+- file_accessed(in);
+ } else if (ret < 0) {
+ /*
+ * callers of ->splice_read() expect -EAGAIN on
+--
+2.39.2
+
--- /dev/null
+From 266f69978a5a4699bb6a00c687f7edddd5b10bac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 May 2023 14:49:48 +0100
+Subject: splice: Fix filemap_splice_read() to use the correct inode
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit c37222082f23c456664d1c3182a714670ab8f9a4 ]
+
+Fix filemap_splice_read() to use file->f_mapping->host, not file->f_inode,
+as the source of the file size because in the case of a block device,
+file->f_inode points to the block-special file (which is typically 0
+length) and not the backing store.
+
+Fixes: 07073eb01c5f ("splice: Add a func to do a splice from a buffered file without ITER_PIPE")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+cc: Steve French <stfrench@microsoft.com>
+cc: Jens Axboe <axboe@kernel.dk>
+cc: Al Viro <viro@zeniv.linux.org.uk>
+cc: David Hildenbrand <david@redhat.com>
+cc: John Hubbard <jhubbard@nvidia.com>
+cc: linux-mm@kvack.org
+cc: linux-block@vger.kernel.org
+cc: linux-fsdevel@vger.kernel.org
+Link: https://lore.kernel.org/r/20230522135018.2742245-2-dhowells@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/filemap.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mm/filemap.c b/mm/filemap.c
+index 2723104cc06a1..8f048e62279a2 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -2903,7 +2903,7 @@ ssize_t filemap_splice_read(struct file *in, loff_t *ppos,
+ do {
+ cond_resched();
+
+- if (*ppos >= i_size_read(file_inode(in)))
++ if (*ppos >= i_size_read(in->f_mapping->host))
+ break;
+
+ iocb.ki_pos = *ppos;
+@@ -2919,7 +2919,7 @@ ssize_t filemap_splice_read(struct file *in, loff_t *ppos,
+ * part of the page is not copied back to userspace (unless
+ * another truncate extends the file - this is desired though).
+ */
+- isize = i_size_read(file_inode(in));
++ isize = i_size_read(in->f_mapping->host);
+ if (unlikely(*ppos >= isize))
+ break;
+ end_offset = min_t(loff_t, isize, *ppos + len);
+--
+2.39.2
+
--- /dev/null
+From 2b3d493e00f6df154c395d45207219cdd5cc5024 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 10:10:20 -0400
+Subject: svcrdma: Prevent page release when nothing was received
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit baf6d18b116b7dc84ed5e212c3a89f17cdc3f28c ]
+
+I noticed that svc_rqst_release_pages() was still unnecessarily
+releasing a page when svc_rdma_recvfrom() returns zero.
+
+Fixes: a53d5cb0646a ("svcrdma: Avoid releasing a page in svc_xprt_release()")
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+index a22fe7587fa6f..70207d8a318a4 100644
+--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
++++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+@@ -796,6 +796,12 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
+ struct svc_rdma_recv_ctxt *ctxt;
+ int ret;
+
++ /* Prevent svc_xprt_release() from releasing pages in rq_pages
++ * when returning 0 or an error.
++ */
++ rqstp->rq_respages = rqstp->rq_pages;
++ rqstp->rq_next_page = rqstp->rq_respages;
++
+ rqstp->rq_xprt_ctxt = NULL;
+
+ ctxt = NULL;
+@@ -819,12 +825,6 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
+ DMA_FROM_DEVICE);
+ svc_rdma_build_arg_xdr(rqstp, ctxt);
+
+- /* Prevent svc_xprt_release from releasing pages in rq_pages
+- * if we return 0 or an error.
+- */
+- rqstp->rq_respages = rqstp->rq_pages;
+- rqstp->rq_next_page = rqstp->rq_respages;
+-
+ ret = svc_rdma_xdr_decode_req(&rqstp->rq_arg, ctxt);
+ if (ret < 0)
+ goto out_err;
+--
+2.39.2
+
--- /dev/null
+From f3b05bcac866b7fd1dae679023495cd3f8cfaa9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jun 2023 12:47:46 +0200
+Subject: thermal/drivers/qcom/tsens-v0_1: Add mdm9607 correction offsets
+
+From: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+
+[ Upstream commit b6f739da0070c36655118618a173a59fa14c7adc ]
+
+According to the msm-3.18 vendor kernel from Qualcomm, mdm9607 needs
+"correction factors" to adjust for additional offsets observed after the
+factory calibration values in the fuses [1, 2].
+
+The fixed offsets should be applied unless there is a special
+calibration mode value that indicates that no offsets are needed [3].
+
+Note that the new calibration mode values are called differently in this
+patch compared to the vendor kernel:
+ - TSENS_TWO_POINT_CALIB_N_WA -> ONE_PT_CALIB2_NO_OFFSET
+ - TSENS_TWO_POINT_CALIB_N_OFFSET_WA -> TWO_PT_CALIB_NO_OFFSET
+This is because close inspection of the calibration function [3] reveals
+that TSENS_TWO_POINT_CALIB_N_WA is actually a "one point" calibration
+because the if statements skip all "point2" related code for it.
+
+[1]: https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/commit/d9d2db1b82bf3f72f5de0803d55e6849eb5b671e
+[2]: https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/commit/d75aef53a760e8ff7bac54049d00c8b2ee1b193e
+[3]: https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/blob/LE.UM.4.3.2.r1-04200-9x07/drivers/thermal/msm-tsens.c#L2987-3136
+
+Fixes: a2149ab815fc ("thermal/drivers/qcom/tsens-v0_1: Add support for MDM9607")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230508-msm8909-tsens-v5-3-5eb632235ba7@kernkonzept.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/qcom/tsens-v0_1.c | 11 +++++++++++
+ drivers/thermal/qcom/tsens.c | 16 +++++++++++++++-
+ drivers/thermal/qcom/tsens.h | 4 ++++
+ 3 files changed, 30 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
+index e89a0da4b4e14..e9ce7b62b3818 100644
+--- a/drivers/thermal/qcom/tsens-v0_1.c
++++ b/drivers/thermal/qcom/tsens-v0_1.c
+@@ -277,6 +277,17 @@ static int __init init_9607(struct tsens_priv *priv)
+ for (i = 0; i < priv->num_sensors; ++i)
+ priv->sensor[i].slope = 3000;
+
++ priv->sensor[0].p1_calib_offset = 1;
++ priv->sensor[0].p2_calib_offset = 1;
++ priv->sensor[1].p1_calib_offset = -4;
++ priv->sensor[1].p2_calib_offset = -2;
++ priv->sensor[2].p1_calib_offset = 4;
++ priv->sensor[2].p2_calib_offset = 8;
++ priv->sensor[3].p1_calib_offset = -3;
++ priv->sensor[3].p2_calib_offset = -5;
++ priv->sensor[4].p1_calib_offset = -4;
++ priv->sensor[4].p2_calib_offset = -4;
++
+ return init_common(priv);
+ }
+
+diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
+index eb33a8bf0488d..2c02c86db6527 100644
+--- a/drivers/thermal/qcom/tsens.c
++++ b/drivers/thermal/qcom/tsens.c
+@@ -134,10 +134,12 @@ int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2,
+ p1[i] = p1[i] + (base1 << shift);
+ break;
+ case TWO_PT_CALIB:
++ case TWO_PT_CALIB_NO_OFFSET:
+ for (i = 0; i < priv->num_sensors; i++)
+ p2[i] = (p2[i] + base2) << shift;
+ fallthrough;
+ case ONE_PT_CALIB2:
++ case ONE_PT_CALIB2_NO_OFFSET:
+ for (i = 0; i < priv->num_sensors; i++)
+ p1[i] = (p1[i] + base1) << shift;
+ break;
+@@ -149,6 +151,18 @@ int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2,
+ }
+ }
+
++ /* Apply calibration offset workaround except for _NO_OFFSET modes */
++ switch (mode) {
++ case TWO_PT_CALIB:
++ for (i = 0; i < priv->num_sensors; i++)
++ p2[i] += priv->sensor[i].p2_calib_offset;
++ fallthrough;
++ case ONE_PT_CALIB2:
++ for (i = 0; i < priv->num_sensors; i++)
++ p1[i] += priv->sensor[i].p1_calib_offset;
++ break;
++ }
++
+ return mode;
+ }
+
+@@ -254,7 +268,7 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
+
+ if (!priv->sensor[i].slope)
+ priv->sensor[i].slope = SLOPE_DEFAULT;
+- if (mode == TWO_PT_CALIB) {
++ if (mode == TWO_PT_CALIB || mode == TWO_PT_CALIB_NO_OFFSET) {
+ /*
+ * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
+ * temp_120_degc - temp_30_degc (x2 - x1)
+diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
+index 433eba370998c..1cd8f4fe0971f 100644
+--- a/drivers/thermal/qcom/tsens.h
++++ b/drivers/thermal/qcom/tsens.h
+@@ -10,6 +10,8 @@
+ #define ONE_PT_CALIB 0x1
+ #define ONE_PT_CALIB2 0x2
+ #define TWO_PT_CALIB 0x3
++#define ONE_PT_CALIB2_NO_OFFSET 0x6
++#define TWO_PT_CALIB_NO_OFFSET 0x7
+ #define CAL_DEGC_PT1 30
+ #define CAL_DEGC_PT2 120
+ #define SLOPE_FACTOR 1000
+@@ -57,6 +59,8 @@ struct tsens_sensor {
+ unsigned int hw_id;
+ int slope;
+ u32 status;
++ int p1_calib_offset;
++ int p2_calib_offset;
+ };
+
+ /**
+--
+2.39.2
+
--- /dev/null
+From 036dee2bc46900a77362656fe61cd7b048dc02a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 May 2023 23:12:21 +0300
+Subject: thermal/drivers/qcom/tsens-v0_1: Add support for MSM8226
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matti Lehtimäki <matti.lehtimaki@gmail.com>
+
+[ Upstream commit 598e1afca47fdbb302ce8d288b06bcc8728efc6c ]
+
+The MSM8226 TSENS IP has 6 thermal sensors in a TSENS v0.1 block.
+The thermal sensors use non-standard slope values.
+
+Signed-off-by: Matti Lehtimäki <matti.lehtimaki@gmail.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Luca Weiss <luca@z3ntu.xyz>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230507201225.89694-4-matti.lehtimaki@gmail.com
+Stable-dep-of: 6812d1dfbca9 ("thermal/drivers/qcom/tsens-v0_1: Fix mdm9607 slope values")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/qcom/tsens-v0_1.c | 27 ++++++++++++++++++++++++++-
+ drivers/thermal/qcom/tsens.c | 3 +++
+ drivers/thermal/qcom/tsens.h | 2 +-
+ 3 files changed, 30 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
+index e89c6f39a3aea..ad57ab94546b0 100644
+--- a/drivers/thermal/qcom/tsens-v0_1.c
++++ b/drivers/thermal/qcom/tsens-v0_1.c
+@@ -243,6 +243,18 @@ static int calibrate_8974(struct tsens_priv *priv)
+ return 0;
+ }
+
++static int __init init_8226(struct tsens_priv *priv)
++{
++ priv->sensor[0].slope = 2901;
++ priv->sensor[1].slope = 2846;
++ priv->sensor[2].slope = 3038;
++ priv->sensor[3].slope = 2955;
++ priv->sensor[4].slope = 2901;
++ priv->sensor[5].slope = 2846;
++
++ return init_common(priv);
++}
++
+ static int __init init_8939(struct tsens_priv *priv) {
+ priv->sensor[0].slope = 2911;
+ priv->sensor[1].slope = 2789;
+@@ -258,7 +270,7 @@ static int __init init_8939(struct tsens_priv *priv) {
+ return init_common(priv);
+ }
+
+-/* v0.1: 8916, 8939, 8974, 9607 */
++/* v0.1: 8226, 8916, 8939, 8974, 9607 */
+
+ static struct tsens_features tsens_v0_1_feat = {
+ .ver_major = VER_0_1,
+@@ -313,6 +325,19 @@ static const struct tsens_ops ops_v0_1 = {
+ .get_temp = get_temp_common,
+ };
+
++static const struct tsens_ops ops_8226 = {
++ .init = init_8226,
++ .calibrate = tsens_calibrate_common,
++ .get_temp = get_temp_common,
++};
++
++struct tsens_plat_data data_8226 = {
++ .num_sensors = 6,
++ .ops = &ops_8226,
++ .feat = &tsens_v0_1_feat,
++ .fields = tsens_v0_1_regfields,
++};
++
+ static const struct tsens_ops ops_8916 = {
+ .init = init_common,
+ .calibrate = calibrate_8916,
+diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
+index 8020ead2794e9..eb33a8bf0488d 100644
+--- a/drivers/thermal/qcom/tsens.c
++++ b/drivers/thermal/qcom/tsens.c
+@@ -1095,6 +1095,9 @@ static const struct of_device_id tsens_table[] = {
+ }, {
+ .compatible = "qcom,mdm9607-tsens",
+ .data = &data_9607,
++ }, {
++ .compatible = "qcom,msm8226-tsens",
++ .data = &data_8226,
+ }, {
+ .compatible = "qcom,msm8916-tsens",
+ .data = &data_8916,
+diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
+index dba9cd38f637c..433eba370998c 100644
+--- a/drivers/thermal/qcom/tsens.h
++++ b/drivers/thermal/qcom/tsens.h
+@@ -635,7 +635,7 @@ int get_temp_common(const struct tsens_sensor *s, int *temp);
+ extern struct tsens_plat_data data_8960;
+
+ /* TSENS v0.1 targets */
+-extern struct tsens_plat_data data_8916, data_8939, data_8974, data_9607;
++extern struct tsens_plat_data data_8226, data_8916, data_8939, data_8974, data_9607;
+
+ /* TSENS v1 targets */
+ extern struct tsens_plat_data data_tsens_v1, data_8976, data_8956;
+--
+2.39.2
+
--- /dev/null
+From 98171c334f2bf76c07cca2936edf077f270743cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jun 2023 12:47:45 +0200
+Subject: thermal/drivers/qcom/tsens-v0_1: Fix mdm9607 slope values
+
+From: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+
+[ Upstream commit 6812d1dfbca99cd5032683354bf50e0002b2aa02 ]
+
+According to the msm-3.18 vendor kernel from Qualcomm [1], mdm9607 uses
+a non-standard slope value of 3000 (instead of 3200) for all sensors.
+Fill it properly similar to the 8939 code added recently.
+
+[1]: https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/blob/LE.UM.4.3.2.r1-04200-9x07/arch/arm/boot/dts/qcom/mdm9607.dtsi#L875
+
+Fixes: a2149ab815fc ("thermal/drivers/qcom/tsens-v0_1: Add support for MDM9607")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230508-msm8909-tsens-v5-2-5eb632235ba7@kernkonzept.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/qcom/tsens-v0_1.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
+index ad57ab94546b0..e89a0da4b4e14 100644
+--- a/drivers/thermal/qcom/tsens-v0_1.c
++++ b/drivers/thermal/qcom/tsens-v0_1.c
+@@ -270,6 +270,16 @@ static int __init init_8939(struct tsens_priv *priv) {
+ return init_common(priv);
+ }
+
++static int __init init_9607(struct tsens_priv *priv)
++{
++ int i;
++
++ for (i = 0; i < priv->num_sensors; ++i)
++ priv->sensor[i].slope = 3000;
++
++ return init_common(priv);
++}
++
+ /* v0.1: 8226, 8916, 8939, 8974, 9607 */
+
+ static struct tsens_features tsens_v0_1_feat = {
+@@ -381,9 +391,15 @@ struct tsens_plat_data data_8974 = {
+ .fields = tsens_v0_1_regfields,
+ };
+
++static const struct tsens_ops ops_9607 = {
++ .init = init_9607,
++ .calibrate = tsens_calibrate_common,
++ .get_temp = get_temp_common,
++};
++
+ struct tsens_plat_data data_9607 = {
+ .num_sensors = 5,
+- .ops = &ops_v0_1,
++ .ops = &ops_9607,
+ .feat = &tsens_v0_1_feat,
+ .fields = tsens_v0_1_regfields,
+ };
+--
+2.39.2
+
--- /dev/null
+From 8cb4f438d91a5ffc513d68ab27f68aded06c995a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 May 2023 16:37:45 +0800
+Subject: thermal/drivers/qoriq: Only enable supported sensors
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit 9301575df2509ecf8bd66f601046afaff606b1d5 ]
+
+There are MAX 16 sensors, but not all of them supported. Such as
+i.MX8MQ, there are only 3 sensors. Enabling all 16 sensors will
+touch reserved bits from i.MX8MQ reference mannual, and TMU will stuck,
+temperature will not update anymore.
+
+Fixes: 45038e03d633 ("thermal: qoriq: Enable all sensors before registering them")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230516083746.63436-3-peng.fan@oss.nxp.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/qoriq_thermal.c | 30 +++++++++++++++++++-----------
+ 1 file changed, 19 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
+index 5c9205fe30733..dec66cf3eba2c 100644
+--- a/drivers/thermal/qoriq_thermal.c
++++ b/drivers/thermal/qoriq_thermal.c
+@@ -31,7 +31,6 @@
+ #define TMR_DISABLE 0x0
+ #define TMR_ME 0x80000000
+ #define TMR_ALPF 0x0c000000
+-#define TMR_MSITE_ALL GENMASK(15, 0)
+
+ #define REGS_TMTMIR 0x008 /* Temperature measurement interval Register */
+ #define TMTMIR_DEFAULT 0x0000000f
+@@ -105,6 +104,11 @@ static int tmu_get_temp(struct thermal_zone_device *tz, int *temp)
+ * within sensor range. TEMP is an 9 bit value representing
+ * temperature in KelVin.
+ */
++
++ regmap_read(qdata->regmap, REGS_TMR, &val);
++ if (!(val & TMR_ME))
++ return -EAGAIN;
++
+ if (regmap_read_poll_timeout(qdata->regmap,
+ REGS_TRITSR(qsensor->id),
+ val,
+@@ -128,15 +132,7 @@ static const struct thermal_zone_device_ops tmu_tz_ops = {
+ static int qoriq_tmu_register_tmu_zone(struct device *dev,
+ struct qoriq_tmu_data *qdata)
+ {
+- int id;
+-
+- if (qdata->ver == TMU_VER1) {
+- regmap_write(qdata->regmap, REGS_TMR,
+- TMR_MSITE_ALL | TMR_ME | TMR_ALPF);
+- } else {
+- regmap_write(qdata->regmap, REGS_V2_TMSR, TMR_MSITE_ALL);
+- regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF_V2);
+- }
++ int id, sites = 0;
+
+ for (id = 0; id < SITES_MAX; id++) {
+ struct thermal_zone_device *tzd;
+@@ -153,14 +149,26 @@ static int qoriq_tmu_register_tmu_zone(struct device *dev,
+ if (ret == -ENODEV)
+ continue;
+
+- regmap_write(qdata->regmap, REGS_TMR, TMR_DISABLE);
+ return ret;
+ }
+
++ if (qdata->ver == TMU_VER1)
++ sites |= 0x1 << (15 - id);
++ else
++ sites |= 0x1 << id;
++
+ if (devm_thermal_add_hwmon_sysfs(dev, tzd))
+ dev_warn(dev,
+ "Failed to add hwmon sysfs attributes\n");
++ }
+
++ if (sites) {
++ if (qdata->ver == TMU_VER1) {
++ regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF | sites);
++ } else {
++ regmap_write(qdata->regmap, REGS_V2_TMSR, sites);
++ regmap_write(qdata->regmap, REGS_TMR, TMR_ME | TMR_ALPF_V2);
++ }
+ }
+
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From 86fab1e4b9f2ff7cd6d88e49e66c558ced3f7aba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 May 2023 20:46:05 +0200
+Subject: thermal/drivers/sun8i: Fix some error handling paths in
+ sun8i_ths_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 89382022b370dfd34eaae9c863baa123fcd4d132 ]
+
+Should an error occur after calling sun8i_ths_resource_init() in the probe
+function, some resources need to be released, as already done in the
+.remove() function.
+
+Switch to the devm_clk_get_enabled() helper and add a new devm_action to
+turn sun8i_ths_resource_init() into a fully managed function.
+
+Move the place where reset_control_deassert() is called so that the
+recommended order of reset release/clock enable steps is kept.
+A64 manual states that:
+
+ 3.3.6.4. Gating and reset
+
+ Make sure that the reset signal has been released before the release of
+ module clock gating;
+
+This fixes the issue and removes some LoC at the same time.
+
+Fixes: dccc5c3b6f30 ("thermal/drivers/sun8i: Add thermal driver for H6/H5/H3/A64/A83T/R40")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/a8ae84bd2dc4b55fe428f8e20f31438bf8bb6762.1684089931.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/sun8i_thermal.c | 55 +++++++++++----------------------
+ 1 file changed, 18 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
+index 497beac63e5d9..31063e82afb69 100644
+--- a/drivers/thermal/sun8i_thermal.c
++++ b/drivers/thermal/sun8i_thermal.c
+@@ -319,6 +319,11 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev)
+ return ret;
+ }
+
++static void sun8i_ths_reset_control_assert(void *data)
++{
++ reset_control_assert(data);
++}
++
+ static int sun8i_ths_resource_init(struct ths_device *tmdev)
+ {
+ struct device *dev = tmdev->dev;
+@@ -339,47 +344,35 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev)
+ if (IS_ERR(tmdev->reset))
+ return PTR_ERR(tmdev->reset);
+
+- tmdev->bus_clk = devm_clk_get(&pdev->dev, "bus");
++ ret = reset_control_deassert(tmdev->reset);
++ if (ret)
++ return ret;
++
++ ret = devm_add_action_or_reset(dev, sun8i_ths_reset_control_assert,
++ tmdev->reset);
++ if (ret)
++ return ret;
++
++ tmdev->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus");
+ if (IS_ERR(tmdev->bus_clk))
+ return PTR_ERR(tmdev->bus_clk);
+ }
+
+ if (tmdev->chip->has_mod_clk) {
+- tmdev->mod_clk = devm_clk_get(&pdev->dev, "mod");
++ tmdev->mod_clk = devm_clk_get_enabled(&pdev->dev, "mod");
+ if (IS_ERR(tmdev->mod_clk))
+ return PTR_ERR(tmdev->mod_clk);
+ }
+
+- ret = reset_control_deassert(tmdev->reset);
+- if (ret)
+- return ret;
+-
+- ret = clk_prepare_enable(tmdev->bus_clk);
+- if (ret)
+- goto assert_reset;
+-
+ ret = clk_set_rate(tmdev->mod_clk, 24000000);
+ if (ret)
+- goto bus_disable;
+-
+- ret = clk_prepare_enable(tmdev->mod_clk);
+- if (ret)
+- goto bus_disable;
++ return ret;
+
+ ret = sun8i_ths_calibrate(tmdev);
+ if (ret)
+- goto mod_disable;
++ return ret;
+
+ return 0;
+-
+-mod_disable:
+- clk_disable_unprepare(tmdev->mod_clk);
+-bus_disable:
+- clk_disable_unprepare(tmdev->bus_clk);
+-assert_reset:
+- reset_control_assert(tmdev->reset);
+-
+- return ret;
+ }
+
+ static int sun8i_h3_thermal_init(struct ths_device *tmdev)
+@@ -530,17 +523,6 @@ static int sun8i_ths_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int sun8i_ths_remove(struct platform_device *pdev)
+-{
+- struct ths_device *tmdev = platform_get_drvdata(pdev);
+-
+- clk_disable_unprepare(tmdev->mod_clk);
+- clk_disable_unprepare(tmdev->bus_clk);
+- reset_control_assert(tmdev->reset);
+-
+- return 0;
+-}
+-
+ static const struct ths_thermal_chip sun8i_a83t_ths = {
+ .sensor_num = 3,
+ .scale = 705,
+@@ -642,7 +624,6 @@ MODULE_DEVICE_TABLE(of, of_ths_match);
+
+ static struct platform_driver ths_driver = {
+ .probe = sun8i_ths_probe,
+- .remove = sun8i_ths_remove,
+ .driver = {
+ .name = "sun8i-thermal",
+ .of_match_table = of_ths_match,
+--
+2.39.2
+
--- /dev/null
+From 38eed605e18204cc3df2911a28a52d62d2f54914 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Mar 2023 21:14:36 +0100
+Subject: thermal/hwmon: Use the right device for
+ devm_thermal_add_hwmon_sysfs()
+
+From: Daniel Lezcano <daniel.lezcano@linaro.org>
+
+[ Upstream commit 4a16c190f761cb3a87dcbbf355f91c71ce1f8c0b ]
+
+The devres variant of thermal_add_hwmon_sysfs() only takes the thermal
+zone structure pointer as parameter.
+
+Actually, it uses the tz->device to add it in the devres list.
+
+It is preferable to use the device registering the thermal zone
+instead of the thermal zone device itself. That prevents the driver
+accessing the thermal zone structure internals and it is from my POV
+more correct regarding how devm_ is used.
+
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> #amlogic_thermal
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com> #sun8i_thermal
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> #MediaTek auxadc
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 9301575df250 ("thermal/drivers/qoriq: Only enable supported sensors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/amlogic_thermal.c | 2 +-
+ drivers/thermal/imx8mm_thermal.c | 2 +-
+ drivers/thermal/imx_sc_thermal.c | 2 +-
+ drivers/thermal/k3_bandgap.c | 2 +-
+ drivers/thermal/mediatek/auxadc_thermal.c | 2 +-
+ drivers/thermal/qcom/qcom-spmi-adc-tm5.c | 2 +-
+ drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 2 +-
+ drivers/thermal/qcom/tsens.c | 2 +-
+ drivers/thermal/qoriq_thermal.c | 2 +-
+ drivers/thermal/sun8i_thermal.c | 2 +-
+ drivers/thermal/tegra/tegra30-tsensor.c | 2 +-
+ drivers/thermal/thermal_hwmon.c | 4 ++--
+ drivers/thermal/thermal_hwmon.h | 4 ++--
+ drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +-
+ 14 files changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/thermal/amlogic_thermal.c b/drivers/thermal/amlogic_thermal.c
+index 9235fda4ec1eb..337153042318f 100644
+--- a/drivers/thermal/amlogic_thermal.c
++++ b/drivers/thermal/amlogic_thermal.c
+@@ -285,7 +285,7 @@ static int amlogic_thermal_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+- if (devm_thermal_add_hwmon_sysfs(pdata->tzd))
++ if (devm_thermal_add_hwmon_sysfs(&pdev->dev, pdata->tzd))
+ dev_warn(&pdev->dev, "Failed to add hwmon sysfs attributes\n");
+
+ ret = amlogic_thermal_initialize(pdata);
+diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c
+index 72b5d6f319c1d..e1bec196c5350 100644
+--- a/drivers/thermal/imx8mm_thermal.c
++++ b/drivers/thermal/imx8mm_thermal.c
+@@ -343,7 +343,7 @@ static int imx8mm_tmu_probe(struct platform_device *pdev)
+ }
+ tmu->sensors[i].hw_id = i;
+
+- if (devm_thermal_add_hwmon_sysfs(tmu->sensors[i].tzd))
++ if (devm_thermal_add_hwmon_sysfs(&pdev->dev, tmu->sensors[i].tzd))
+ dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n");
+ }
+
+diff --git a/drivers/thermal/imx_sc_thermal.c b/drivers/thermal/imx_sc_thermal.c
+index f32e59e746231..e24572fc9e731 100644
+--- a/drivers/thermal/imx_sc_thermal.c
++++ b/drivers/thermal/imx_sc_thermal.c
+@@ -119,7 +119,7 @@ static int imx_sc_thermal_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+- if (devm_thermal_add_hwmon_sysfs(sensor->tzd))
++ if (devm_thermal_add_hwmon_sysfs(&pdev->dev, sensor->tzd))
+ dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n");
+ }
+
+diff --git a/drivers/thermal/k3_bandgap.c b/drivers/thermal/k3_bandgap.c
+index 22c9bcb899c37..df184b837cdd0 100644
+--- a/drivers/thermal/k3_bandgap.c
++++ b/drivers/thermal/k3_bandgap.c
+@@ -222,7 +222,7 @@ static int k3_bandgap_probe(struct platform_device *pdev)
+ goto err_alloc;
+ }
+
+- if (devm_thermal_add_hwmon_sysfs(data[id].tzd))
++ if (devm_thermal_add_hwmon_sysfs(dev, data[id].tzd))
+ dev_warn(dev, "Failed to add hwmon sysfs attributes\n");
+ }
+
+diff --git a/drivers/thermal/mediatek/auxadc_thermal.c b/drivers/thermal/mediatek/auxadc_thermal.c
+index ab730f9552d0e..585704d2df2be 100644
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -1210,7 +1210,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
+ goto err_disable_clk_peri_therm;
+ }
+
+- ret = devm_thermal_add_hwmon_sysfs(tzdev);
++ ret = devm_thermal_add_hwmon_sysfs(&pdev->dev, tzdev);
+ if (ret)
+ dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
+
+diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
+index 31164ade2dd11..dcb24a94f3fb4 100644
+--- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
++++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
+@@ -689,7 +689,7 @@ static int adc_tm5_register_tzd(struct adc_tm5_chip *adc_tm)
+ return PTR_ERR(tzd);
+ }
+ adc_tm->channels[i].tzd = tzd;
+- if (devm_thermal_add_hwmon_sysfs(tzd))
++ if (devm_thermal_add_hwmon_sysfs(adc_tm->dev, tzd))
+ dev_warn(adc_tm->dev,
+ "Failed to add hwmon sysfs attributes\n");
+ }
+diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
+index 101c75d0e13f3..c0cfb255c14e2 100644
+--- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
++++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
+@@ -459,7 +459,7 @@ static int qpnp_tm_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+- if (devm_thermal_add_hwmon_sysfs(chip->tz_dev))
++ if (devm_thermal_add_hwmon_sysfs(&pdev->dev, chip->tz_dev))
+ dev_warn(&pdev->dev,
+ "Failed to add hwmon sysfs attributes\n");
+
+diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
+index 2c02c86db6527..38f5c783fb297 100644
+--- a/drivers/thermal/qcom/tsens.c
++++ b/drivers/thermal/qcom/tsens.c
+@@ -1206,7 +1206,7 @@ static int tsens_register(struct tsens_priv *priv)
+ if (priv->ops->enable)
+ priv->ops->enable(priv, i);
+
+- if (devm_thermal_add_hwmon_sysfs(tzd))
++ if (devm_thermal_add_hwmon_sysfs(priv->dev, tzd))
+ dev_warn(priv->dev,
+ "Failed to add hwmon sysfs attributes\n");
+ }
+diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
+index 431c29c0898a7..5c9205fe30733 100644
+--- a/drivers/thermal/qoriq_thermal.c
++++ b/drivers/thermal/qoriq_thermal.c
+@@ -157,7 +157,7 @@ static int qoriq_tmu_register_tmu_zone(struct device *dev,
+ return ret;
+ }
+
+- if (devm_thermal_add_hwmon_sysfs(tzd))
++ if (devm_thermal_add_hwmon_sysfs(dev, tzd))
+ dev_warn(dev,
+ "Failed to add hwmon sysfs attributes\n");
+
+diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
+index 31063e82afb69..7517067d6e817 100644
+--- a/drivers/thermal/sun8i_thermal.c
++++ b/drivers/thermal/sun8i_thermal.c
+@@ -468,7 +468,7 @@ static int sun8i_ths_register(struct ths_device *tmdev)
+ if (IS_ERR(tmdev->sensor[i].tzd))
+ return PTR_ERR(tmdev->sensor[i].tzd);
+
+- if (devm_thermal_add_hwmon_sysfs(tmdev->sensor[i].tzd))
++ if (devm_thermal_add_hwmon_sysfs(tmdev->dev, tmdev->sensor[i].tzd))
+ dev_warn(tmdev->dev,
+ "Failed to add hwmon sysfs attributes\n");
+ }
+diff --git a/drivers/thermal/tegra/tegra30-tsensor.c b/drivers/thermal/tegra/tegra30-tsensor.c
+index b3218b71b6d97..823560c82aaee 100644
+--- a/drivers/thermal/tegra/tegra30-tsensor.c
++++ b/drivers/thermal/tegra/tegra30-tsensor.c
+@@ -528,7 +528,7 @@ static int tegra_tsensor_register_channel(struct tegra_tsensor *ts,
+ return 0;
+ }
+
+- if (devm_thermal_add_hwmon_sysfs(tsc->tzd))
++ if (devm_thermal_add_hwmon_sysfs(ts->dev, tsc->tzd))
+ dev_warn(ts->dev, "failed to add hwmon sysfs attributes\n");
+
+ return 0;
+diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c
+index c594c42bea6da..964db7941e310 100644
+--- a/drivers/thermal/thermal_hwmon.c
++++ b/drivers/thermal/thermal_hwmon.c
+@@ -263,7 +263,7 @@ static void devm_thermal_hwmon_release(struct device *dev, void *res)
+ thermal_remove_hwmon_sysfs(*(struct thermal_zone_device **)res);
+ }
+
+-int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
++int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz)
+ {
+ struct thermal_zone_device **ptr;
+ int ret;
+@@ -280,7 +280,7 @@ int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
+ }
+
+ *ptr = tz;
+- devres_add(&tz->device, ptr);
++ devres_add(dev, ptr);
+
+ return ret;
+ }
+diff --git a/drivers/thermal/thermal_hwmon.h b/drivers/thermal/thermal_hwmon.h
+index 1a9d65f6a6a8b..b429f6e7abdb2 100644
+--- a/drivers/thermal/thermal_hwmon.h
++++ b/drivers/thermal/thermal_hwmon.h
+@@ -17,7 +17,7 @@
+
+ #ifdef CONFIG_THERMAL_HWMON
+ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz);
+-int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz);
++int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz);
+ void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz);
+ #else
+ static inline int
+@@ -27,7 +27,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
+ }
+
+ static inline int
+-devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
++devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz)
+ {
+ return 0;
+ }
+diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+index 8a9055bd376ec..42d0ffd82514d 100644
+--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
++++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+@@ -182,7 +182,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
+ ti_bandgap_set_sensor_data(bgp, id, data);
+ ti_bandgap_write_update_interval(bgp, data->sensor_id, interval);
+
+- if (devm_thermal_add_hwmon_sysfs(data->ti_thermal))
++ if (devm_thermal_add_hwmon_sysfs(bgp->dev, data->ti_thermal))
+ dev_warn(bgp->dev, "failed to add hwmon sysfs attributes\n");
+
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From 8859735af4d6e89ae22c633de0f1f3c782ba94bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 May 2023 00:12:53 +0800
+Subject: tick/rcu: Fix bogus ratelimit condition
+
+From: Wen Yang <wenyang.linux@foxmail.com>
+
+[ Upstream commit a7e282c77785c7eabf98836431b1f029481085ad ]
+
+The ratelimit logic in report_idle_softirq() is broken because the
+exit condition is always true:
+
+ static int ratelimit;
+
+ if (ratelimit < 10)
+ return false; ---> always returns here
+
+ ratelimit++; ---> no chance to run
+
+Make it check for >= 10 instead.
+
+Fixes: 0345691b24c0 ("tick/rcu: Stop allowing RCU_SOFTIRQ in idle")
+Signed-off-by: Wen Yang <wenyang.linux@foxmail.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/tencent_5AAA3EEAB42095C9B7740BE62FBF9A67E007@qq.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/tick-sched.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
+index d6fb6a676bbbb..1ad89eec2a55f 100644
+--- a/kernel/time/tick-sched.c
++++ b/kernel/time/tick-sched.c
+@@ -1046,7 +1046,7 @@ static bool report_idle_softirq(void)
+ return false;
+ }
+
+- if (ratelimit < 10)
++ if (ratelimit >= 10)
+ return false;
+
+ /* On RT, softirqs handling may be waiting on some lock */
+--
+2.39.2
+
--- /dev/null
+From a3085a8ea81ab7ce55119f158f4f4b765342f636 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 14:33:52 +0200
+Subject: tools/resolve_btfids: Fix setting HOSTCFLAGS
+
+From: Viktor Malik <vmalik@redhat.com>
+
+[ Upstream commit edd75c802855271c8610f58a2fc9e54aefc49ce5 ]
+
+Building BPF selftests with custom HOSTCFLAGS yields an error:
+
+ # make HOSTCFLAGS="-O2"
+ [...]
+ HOSTCC ./tools/testing/selftests/bpf/tools/build/resolve_btfids/main.o
+ main.c:73:10: fatal error: linux/rbtree.h: No such file or directory
+ 73 | #include <linux/rbtree.h>
+ | ^~~~~~~~~~~~~~~~
+
+The reason is that tools/bpf/resolve_btfids/Makefile passes header
+include paths by extending HOSTCFLAGS which is overridden by setting
+HOSTCFLAGS in the make command (because of Makefile rules [1]).
+
+This patch fixes the above problem by passing the include paths via
+`HOSTCFLAGS_resolve_btfids` which is used by tools/build/Build.include
+and can be combined with overridding HOSTCFLAGS.
+
+[1] https://www.gnu.org/software/make/manual/html_node/Overriding.html
+
+Fixes: 56a2df7615fa ("tools/resolve_btfids: Compile resolve_btfids as host program")
+Signed-off-by: Viktor Malik <vmalik@redhat.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Jiri Olsa <jolsa@kernel.org>
+Link: https://lore.kernel.org/bpf/20230530123352.1308488-1-vmalik@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/resolve_btfids/Makefile | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/bpf/resolve_btfids/Makefile b/tools/bpf/resolve_btfids/Makefile
+index ac548a7baa73e..4b8079f294f65 100644
+--- a/tools/bpf/resolve_btfids/Makefile
++++ b/tools/bpf/resolve_btfids/Makefile
+@@ -67,7 +67,7 @@ $(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OU
+ LIBELF_FLAGS := $(shell $(HOSTPKG_CONFIG) libelf --cflags 2>/dev/null)
+ LIBELF_LIBS := $(shell $(HOSTPKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf)
+
+-HOSTCFLAGS += -g \
++HOSTCFLAGS_resolve_btfids += -g \
+ -I$(srctree)/tools/include \
+ -I$(srctree)/tools/include/uapi \
+ -I$(LIBBPF_INCLUDE) \
+@@ -76,7 +76,7 @@ HOSTCFLAGS += -g \
+
+ LIBS = $(LIBELF_LIBS) -lz
+
+-export srctree OUTPUT HOSTCFLAGS Q HOSTCC HOSTLD HOSTAR
++export srctree OUTPUT HOSTCFLAGS_resolve_btfids Q HOSTCC HOSTLD HOSTAR
+ include $(srctree)/tools/build/Makefile.include
+
+ $(BINARY_IN): fixdep FORCE prepare | $(OUTPUT)
+--
+2.39.2
+
--- /dev/null
+From 7d94d1a5b24c377fc14303479572df0fa31ca9d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Apr 2023 16:38:54 +0200
+Subject: tracing/timer: Add missing hrtimer modes to decode_hrtimer_mode().
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit 2951580ba6adb082bb6b7154a5ecb24e7c1f7569 ]
+
+The trace output for the HRTIMER_MODE_.*_HARD modes is seen as a number
+since these modes are not decoded. The author was not aware of the fancy
+decoding function which makes the life easier.
+
+Extend decode_hrtimer_mode() with the additional HRTIMER_MODE_.*_HARD
+modes.
+
+Fixes: ae6683d815895 ("hrtimer: Introduce HARD expiry mode")
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Mukesh Ojha <quic_mojha@quicinc.com>
+Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Link: https://lore.kernel.org/r/20230418143854.8vHWQKLM@linutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/trace/events/timer.h | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h
+index 3e8619c72f774..b4bc2828fa09f 100644
+--- a/include/trace/events/timer.h
++++ b/include/trace/events/timer.h
+@@ -158,7 +158,11 @@ DEFINE_EVENT(timer_class, timer_cancel,
+ { HRTIMER_MODE_ABS_SOFT, "ABS|SOFT" }, \
+ { HRTIMER_MODE_REL_SOFT, "REL|SOFT" }, \
+ { HRTIMER_MODE_ABS_PINNED_SOFT, "ABS|PINNED|SOFT" }, \
+- { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" })
++ { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" }, \
++ { HRTIMER_MODE_ABS_HARD, "ABS|HARD" }, \
++ { HRTIMER_MODE_REL_HARD, "REL|HARD" }, \
++ { HRTIMER_MODE_ABS_PINNED_HARD, "ABS|PINNED|HARD" }, \
++ { HRTIMER_MODE_REL_PINNED_HARD, "REL|PINNED|HARD" })
+
+ /**
+ * hrtimer_init - called when the hrtimer is initialized
+--
+2.39.2
+
--- /dev/null
+From c853ebfafbbb03940a6df6b46e2f07d1abf78d22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 15:36:42 +0200
+Subject: vfio/mdev: Move the compat_class initialization to module init
+
+From: Eric Farman <farman@linux.ibm.com>
+
+[ Upstream commit ff598081e5b9d0bdd6874bfe340811bbb75b35e4 ]
+
+The pointer to mdev_bus_compat_class is statically defined at the top
+of mdev_core, and was originally (commit 7b96953bc640 ("vfio: Mediated
+device Core driver") serialized by the parent_list_lock. The blamed
+commit removed this mutex, leaving the pointer initialization
+unserialized. As a result, the creation of multiple MDEVs in parallel
+(such as during boot) can encounter errors during the creation of the
+sysfs entries, such as:
+
+ [ 8.337509] sysfs: cannot create duplicate filename '/class/mdev_bus'
+ [ 8.337514] vfio_ccw 0.0.01d8: MDEV: Registered
+ [ 8.337516] CPU: 13 PID: 946 Comm: driverctl Not tainted 6.4.0-rc7 #20
+ [ 8.337522] Hardware name: IBM 3906 M05 780 (LPAR)
+ [ 8.337525] Call Trace:
+ [ 8.337528] [<0000000162b0145a>] dump_stack_lvl+0x62/0x80
+ [ 8.337540] [<00000001622aeb30>] sysfs_warn_dup+0x78/0x88
+ [ 8.337549] [<00000001622aeca6>] sysfs_create_dir_ns+0xe6/0xf8
+ [ 8.337552] [<0000000162b04504>] kobject_add_internal+0xf4/0x340
+ [ 8.337557] [<0000000162b04d48>] kobject_add+0x78/0xd0
+ [ 8.337561] [<0000000162b04e0a>] kobject_create_and_add+0x6a/0xb8
+ [ 8.337565] [<00000001627a110e>] class_compat_register+0x5e/0x90
+ [ 8.337572] [<000003ff7fd815da>] mdev_register_parent+0x102/0x130 [mdev]
+ [ 8.337581] [<000003ff7fdc7f2c>] vfio_ccw_sch_probe+0xe4/0x178 [vfio_ccw]
+ [ 8.337588] [<0000000162a7833c>] css_probe+0x44/0x80
+ [ 8.337599] [<000000016279f4da>] really_probe+0xd2/0x460
+ [ 8.337603] [<000000016279fa08>] driver_probe_device+0x40/0xf0
+ [ 8.337606] [<000000016279fb78>] __device_attach_driver+0xc0/0x140
+ [ 8.337610] [<000000016279cbe0>] bus_for_each_drv+0x90/0xd8
+ [ 8.337618] [<00000001627a00b0>] __device_attach+0x110/0x190
+ [ 8.337621] [<000000016279c7c8>] bus_rescan_devices_helper+0x60/0xb0
+ [ 8.337626] [<000000016279cd48>] drivers_probe_store+0x48/0x80
+ [ 8.337632] [<00000001622ac9b0>] kernfs_fop_write_iter+0x138/0x1f0
+ [ 8.337635] [<00000001621e5e14>] vfs_write+0x1ac/0x2f8
+ [ 8.337645] [<00000001621e61d8>] ksys_write+0x70/0x100
+ [ 8.337650] [<0000000162b2bdc4>] __do_syscall+0x1d4/0x200
+ [ 8.337656] [<0000000162b3c828>] system_call+0x70/0x98
+ [ 8.337664] kobject: kobject_add_internal failed for mdev_bus with -EEXIST, don't try to register things with the same name in the same directory.
+ [ 8.337668] kobject: kobject_create_and_add: kobject_add error: -17
+ [ 8.337674] vfio_ccw: probe of 0.0.01d9 failed with error -12
+ [ 8.342941] vfio_ccw_mdev aeb9ca91-10c6-42bc-a168-320023570aea: Adding to iommu group 2
+
+Move the initialization of the mdev_bus_compat_class pointer to the
+init path, to match the cleanup in module exit. This way the code
+in mdev_register_parent() can simply link the new parent to it,
+rather than determining whether initialization is required first.
+
+Fixes: 89345d5177aa ("vfio/mdev: embedd struct mdev_parent in the parent data structure")
+Reported-by: Alexander Egorenkov <egorenar@linux.ibm.com>
+Signed-off-by: Eric Farman <farman@linux.ibm.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/20230626133642.2939168-1-farman@linux.ibm.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/mdev/mdev_core.c | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
+index 58f91b3bd670c..ed4737de45289 100644
+--- a/drivers/vfio/mdev/mdev_core.c
++++ b/drivers/vfio/mdev/mdev_core.c
+@@ -72,12 +72,6 @@ int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
+ parent->nr_types = nr_types;
+ atomic_set(&parent->available_instances, mdev_driver->max_instances);
+
+- if (!mdev_bus_compat_class) {
+- mdev_bus_compat_class = class_compat_register("mdev_bus");
+- if (!mdev_bus_compat_class)
+- return -ENOMEM;
+- }
+-
+ ret = parent_create_sysfs_files(parent);
+ if (ret)
+ return ret;
+@@ -251,13 +245,24 @@ int mdev_device_remove(struct mdev_device *mdev)
+
+ static int __init mdev_init(void)
+ {
+- return bus_register(&mdev_bus_type);
++ int ret;
++
++ ret = bus_register(&mdev_bus_type);
++ if (ret)
++ return ret;
++
++ mdev_bus_compat_class = class_compat_register("mdev_bus");
++ if (!mdev_bus_compat_class) {
++ bus_unregister(&mdev_bus_type);
++ return -ENOMEM;
++ }
++
++ return 0;
+ }
+
+ static void __exit mdev_exit(void)
+ {
+- if (mdev_bus_compat_class)
+- class_compat_unregister(mdev_bus_compat_class);
++ class_compat_unregister(mdev_bus_compat_class);
+ bus_unregister(&mdev_bus_type);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 03cb6a01c794ea43e7982d250e9d5a6cd48004b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 18:13:56 +0100
+Subject: virt: sevguest: Add CONFIG_CRYPTO dependency
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 84b9b44b99780d35fe72ac63c4724f158771e898 ]
+
+This driver fails to link when CRYPTO is disabled, or in a loadable
+module:
+
+ WARNING: unmet direct dependencies detected for CRYPTO_GCM
+ WARNING: unmet direct dependencies detected for CRYPTO_AEAD2
+ Depends on [m]: CRYPTO [=m]
+ Selected by [y]:
+ - SEV_GUEST [=y] && VIRT_DRIVERS [=y] && AMD_MEM_ENCRYPT [=y]
+
+x86_64-linux-ld: crypto/aead.o: in function `crypto_register_aeads':
+
+Fixes: fce96cf04430 ("virt: Add SEV-SNP guest driver")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/20230117171416.2715125-1-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/virt/coco/sev-guest/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/virt/coco/sev-guest/Kconfig b/drivers/virt/coco/sev-guest/Kconfig
+index f9db0799ae67c..da2d7ca531f0f 100644
+--- a/drivers/virt/coco/sev-guest/Kconfig
++++ b/drivers/virt/coco/sev-guest/Kconfig
+@@ -2,6 +2,7 @@ config SEV_GUEST
+ tristate "AMD SEV Guest driver"
+ default m
+ depends on AMD_MEM_ENCRYPT
++ select CRYPTO
+ select CRYPTO_AEAD2
+ select CRYPTO_GCM
+ help
+--
+2.39.2
+
--- /dev/null
+From a36242583a629d1322bdf9bdb089f0df6c34636b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 May 2023 10:18:25 -0700
+Subject: watchdog/perf: define dummy watchdog_update_hrtimer_threshold() on
+ correct config
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 5e008df11c55228a86a1bae692cc2002503572c9 ]
+
+Patch series "watchdog/hardlockup: Add the buddy hardlockup detector", v5.
+
+This patch series adds the "buddy" hardlockup detector. In brief, the
+buddy hardlockup detector can detect hardlockups without arch-level
+support by having CPUs checkup on a "buddy" CPU periodically.
+
+Given the new design of this patch series, testing all combinations is
+fairly difficult. I've attempted to make sure that all combinations of
+CONFIG_ options are good, but it wouldn't surprise me if I missed
+something. I apologize in advance and I'll do my best to fix any
+problems that are found.
+
+This patch (of 18):
+
+The real watchdog_update_hrtimer_threshold() is defined in
+kernel/watchdog_hld.c. That file is included if
+CONFIG_HARDLOCKUP_DETECTOR_PERF and the function is defined in that file
+if CONFIG_HARDLOCKUP_CHECK_TIMESTAMP.
+
+The dummy version of the function in "nmi.h" didn't get that quite right.
+While this doesn't appear to be a huge deal, it's nice to make it
+consistent.
+
+It doesn't break builds because CHECK_TIMESTAMP is only defined by x86 so
+others don't get a double definition, and x86 uses perf lockup detector,
+so it gets the out of line version.
+
+Link: https://lkml.kernel.org/r/20230519101840.v5.18.Ia44852044cdcb074f387e80df6b45e892965d4a1@changeid
+Link: https://lkml.kernel.org/r/20230519101840.v5.1.I8cbb2f4fa740528fcfade4f5439b6cdcdd059251@changeid
+Fixes: 7edaeb6841df ("kernel/watchdog: Prevent false positives with turbo modes")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Chen-Yu Tsai <wens@csie.org>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Daniel Thompson <daniel.thompson@linaro.org>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Guenter Roeck <groeck@chromium.org>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Lecopzer Chen <lecopzer.chen@mediatek.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Masayoshi Mizuma <msys.mizuma@gmail.com>
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Pingfan Liu <kernelfans@gmail.com>
+Cc: Randy Dunlap <rdunlap@infradead.org>
+Cc: "Ravi V. Shankar" <ravi.v.shankar@intel.com>
+Cc: Ricardo Neri <ricardo.neri@intel.com>
+Cc: Stephane Eranian <eranian@google.com>
+Cc: Stephen Boyd <swboyd@chromium.org>
+Cc: Sumit Garg <sumit.garg@linaro.org>
+Cc: Tzung-Bi Shih <tzungbi@chromium.org>
+Cc: Will Deacon <will@kernel.org>
+Cc: Colin Cross <ccross@android.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/nmi.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/nmi.h b/include/linux/nmi.h
+index 048c0b9aa623d..771d77b62bc10 100644
+--- a/include/linux/nmi.h
++++ b/include/linux/nmi.h
+@@ -197,7 +197,7 @@ u64 hw_nmi_get_sample_period(int watchdog_thresh);
+ #endif
+
+ #if defined(CONFIG_HARDLOCKUP_CHECK_TIMESTAMP) && \
+- defined(CONFIG_HARDLOCKUP_DETECTOR)
++ defined(CONFIG_HARDLOCKUP_DETECTOR_PERF)
+ void watchdog_update_hrtimer_threshold(u64 period);
+ #else
+ static inline void watchdog_update_hrtimer_threshold(u64 period) { }
+--
+2.39.2
+
--- /dev/null
+From f673da6b5c35fa5e850ea970bb642ab8d0557dcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 May 2023 10:18:26 -0700
+Subject: watchdog/perf: more properly prevent false positives with turbo modes
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 4379e59fe5665cfda737e45b8bf2f05321ef049c ]
+
+Currently, in the watchdog_overflow_callback() we first check to see if
+the watchdog had been touched and _then_ we handle the workaround for
+turbo mode. This order should be reversed.
+
+Specifically, "touching" the hardlockup detector's watchdog should avoid
+lockups being detected for one period that should be roughly the same
+regardless of whether we're running turbo or not. That means that we
+should do the extra accounting for turbo _before_ we look at (and clear)
+the global indicating that we've been touched.
+
+NOTE: this fix is made based on code inspection. I am not aware of any
+reports where the old code would have generated false positives. That
+being said, this order seems more correct and also makes it easier down
+the line to share code with the "buddy" hardlockup detector.
+
+Link: https://lkml.kernel.org/r/20230519101840.v5.2.I843b0d1de3e096ba111a179f3adb16d576bef5c7@changeid
+Fixes: 7edaeb6841df ("kernel/watchdog: Prevent false positives with turbo modes")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Chen-Yu Tsai <wens@csie.org>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Colin Cross <ccross@android.com>
+Cc: Daniel Thompson <daniel.thompson@linaro.org>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Guenter Roeck <groeck@chromium.org>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Lecopzer Chen <lecopzer.chen@mediatek.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Masayoshi Mizuma <msys.mizuma@gmail.com>
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Nicholas Piggin <npiggin@gmail.com>
+Cc: Petr Mladek <pmladek@suse.com>
+Cc: Pingfan Liu <kernelfans@gmail.com>
+Cc: Randy Dunlap <rdunlap@infradead.org>
+Cc: "Ravi V. Shankar" <ravi.v.shankar@intel.com>
+Cc: Ricardo Neri <ricardo.neri@intel.com>
+Cc: Stephane Eranian <eranian@google.com>
+Cc: Stephen Boyd <swboyd@chromium.org>
+Cc: Sumit Garg <sumit.garg@linaro.org>
+Cc: Tzung-Bi Shih <tzungbi@chromium.org>
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/watchdog_hld.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c
+index 247bf0b1582ca..1e8a49dc956e2 100644
+--- a/kernel/watchdog_hld.c
++++ b/kernel/watchdog_hld.c
+@@ -114,14 +114,14 @@ static void watchdog_overflow_callback(struct perf_event *event,
+ /* Ensure the watchdog never gets throttled */
+ event->hw.interrupts = 0;
+
++ if (!watchdog_check_timestamp())
++ return;
++
+ if (__this_cpu_read(watchdog_nmi_touch) == true) {
+ __this_cpu_write(watchdog_nmi_touch, false);
+ return;
+ }
+
+- if (!watchdog_check_timestamp())
+- return;
+-
+ /* check for a hardlockup
+ * This is done by making sure our timer interrupt
+ * is incrementing. The timer interrupt should have
+--
+2.39.2
+
--- /dev/null
+From 9a7d6e90539755c902ad7633550e58f5302f11d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 May 2023 12:41:08 +0300
+Subject: wifi: ath10k: Trigger STA disconnect after reconfig complete on
+ hardware restart
+
+From: Youghandhar Chintala <quic_youghand@quicinc.com>
+
+[ Upstream commit 75bd32f5ce94bc365ba0b9b68bcf9de84a391d37 ]
+
+Currently, on WCN3990, the station disconnect after hardware recovery is
+not working as expected. This is because of setting the
+IEEE80211_SDATA_DISCONNECT_HW_RESTART flag very early in the hardware
+recovery process even before the driver invokes ieee80211_hw_restart().
+On the contrary, mac80211 expects this flag to be set after
+ieee80211_hw_restart() is invoked for it to trigger station disconnect.
+
+Set the IEEE80211_SDATA_DISCONNECT_HW_RESTART flag in
+ath10k_reconfig_complete() instead to fix this.
+
+The other targets are not affected by this change, since the hardware
+params flag is not set.
+
+Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.2.2.c10-00754-QCAHLSWMTPL-1
+
+Fixes: 2c3fc50591ff ("ath10k: Trigger sta disconnect on hardware restart")
+Signed-off-by: Youghandhar Chintala <quic_youghand@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230518101515.3820-1-quic_youghand@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/core.c | 9 ---------
+ drivers/net/wireless/ath/ath10k/mac.c | 7 +++++++
+ 2 files changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
+index 5eb131ab916fd..b6052dcc45ebf 100644
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -2504,7 +2504,6 @@ EXPORT_SYMBOL(ath10k_core_napi_sync_disable);
+ static void ath10k_core_restart(struct work_struct *work)
+ {
+ struct ath10k *ar = container_of(work, struct ath10k, restart_work);
+- struct ath10k_vif *arvif;
+ int ret;
+
+ set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
+@@ -2543,14 +2542,6 @@ static void ath10k_core_restart(struct work_struct *work)
+ ar->state = ATH10K_STATE_RESTARTING;
+ ath10k_halt(ar);
+ ath10k_scan_finish(ar);
+- if (ar->hw_params.hw_restart_disconnect) {
+- list_for_each_entry(arvif, &ar->arvifs, list) {
+- if (arvif->is_up &&
+- arvif->vdev_type == WMI_VDEV_TYPE_STA)
+- ieee80211_hw_restart_disconnect(arvif->vif);
+- }
+- }
+-
+ ieee80211_restart_hw(ar->hw);
+ break;
+ case ATH10K_STATE_OFF:
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
+index ec8d5b29bc72c..f0729acdec50a 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -8108,6 +8108,7 @@ static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
+ enum ieee80211_reconfig_type reconfig_type)
+ {
+ struct ath10k *ar = hw->priv;
++ struct ath10k_vif *arvif;
+
+ if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
+ return;
+@@ -8122,6 +8123,12 @@ static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
+ ar->state = ATH10K_STATE_ON;
+ ieee80211_wake_queues(ar->hw);
+ clear_bit(ATH10K_FLAG_RESTARTING, &ar->dev_flags);
++ if (ar->hw_params.hw_restart_disconnect) {
++ list_for_each_entry(arvif, &ar->arvifs, list) {
++ if (arvif->is_up && arvif->vdev_type == WMI_VDEV_TYPE_STA)
++ ieee80211_hw_restart_disconnect(arvif->vif);
++ }
++ }
+ }
+
+ mutex_unlock(&ar->conf_mutex);
+--
+2.39.2
+
--- /dev/null
+From 198cd98bde5bfa16b65ea75741ed40e282eb105d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 12:19:40 +0300
+Subject: wifi: ath11k: Add missing check for ioremap
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 16e0077e14a73866e9b0f4a6bf4ad3d4a5cb0f2a ]
+
+Add check for ioremap() and return the error if it fails in order to
+guarantee the success of ioremap(), same as in
+ath11k_qmi_load_file_target_mem().
+
+Fixes: 6ac04bdc5edb ("ath11k: Use reserved host DDR addresses from DT for PCI devices")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230608022858.27405-1-jiasheng@iscas.ac.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/qmi.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
+index ab923e24b0a9c..2328b9447cf1b 100644
+--- a/drivers/net/wireless/ath/ath11k/qmi.c
++++ b/drivers/net/wireless/ath/ath11k/qmi.c
+@@ -2058,6 +2058,9 @@ static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab)
+ ab->qmi.target_mem[idx].iaddr =
+ ioremap(ab->qmi.target_mem[idx].paddr,
+ ab->qmi.target_mem[i].size);
++ if (!ab->qmi.target_mem[idx].iaddr)
++ return -EIO;
++
+ ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
+ host_ddr_sz = ab->qmi.target_mem[i].size;
+ ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
+@@ -2083,6 +2086,8 @@ static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab)
+ ab->qmi.target_mem[idx].iaddr =
+ ioremap(ab->qmi.target_mem[idx].paddr,
+ ab->qmi.target_mem[i].size);
++ if (!ab->qmi.target_mem[idx].iaddr)
++ return -EIO;
+ } else {
+ ab->qmi.target_mem[idx].paddr =
+ ATH11K_QMI_CALDB_ADDRESS;
+--
+2.39.2
+
--- /dev/null
+From cab0d3cb4b67fcf4887ebf670855448b027f8fac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 14:41:48 +0300
+Subject: wifi: ath11k: Add missing hw_ops->get_ring_selector() for IPQ5018
+
+From: Ziyang Huang <hzyitc@outlook.com>
+
+[ Upstream commit ce282d8de71f07f0056ea319541141152c65f552 ]
+
+During sending data after clients connected, hw_ops->get_ring_selector()
+will be called. But for IPQ5018, this member isn't set, and the
+following NULL pointer exception will be occurred:
+
+ [ 38.840478] 8<--- cut here ---
+ [ 38.840517] Unable to handle kernel NULL pointer dereference at virtual address 00000000
+ ...
+ [ 38.923161] PC is at 0x0
+ [ 38.927930] LR is at ath11k_dp_tx+0x70/0x730 [ath11k]
+ ...
+ [ 39.063264] Process hostapd (pid: 1034, stack limit = 0x801ceb3d)
+ [ 39.068994] Stack: (0x856a9a68 to 0x856aa000)
+ ...
+ [ 39.438467] [<7f323804>] (ath11k_dp_tx [ath11k]) from [<7f314e6c>] (ath11k_mac_op_tx+0x80/0x190 [ath11k])
+ [ 39.446607] [<7f314e6c>] (ath11k_mac_op_tx [ath11k]) from [<7f17dbe0>] (ieee80211_handle_wake_tx_queue+0x7c/0xc0 [mac80211])
+ [ 39.456162] [<7f17dbe0>] (ieee80211_handle_wake_tx_queue [mac80211]) from [<7f174450>] (ieee80211_probereq_get+0x584/0x704 [mac80211])
+ [ 39.467443] [<7f174450>] (ieee80211_probereq_get [mac80211]) from [<7f178c40>] (ieee80211_tx_prepare_skb+0x1f8/0x248 [mac80211])
+ [ 39.479334] [<7f178c40>] (ieee80211_tx_prepare_skb [mac80211]) from [<7f179e28>] (__ieee80211_subif_start_xmit+0x32c/0x3d4 [mac80211])
+ [ 39.491053] [<7f179e28>] (__ieee80211_subif_start_xmit [mac80211]) from [<7f17af08>] (ieee80211_tx_control_port+0x19c/0x288 [mac80211])
+ [ 39.502946] [<7f17af08>] (ieee80211_tx_control_port [mac80211]) from [<7f0fc704>] (nl80211_tx_control_port+0x174/0x1d4 [cfg80211])
+ [ 39.515017] [<7f0fc704>] (nl80211_tx_control_port [cfg80211]) from [<808ceac4>] (genl_rcv_msg+0x154/0x340)
+ [ 39.526814] [<808ceac4>] (genl_rcv_msg) from [<808cdb74>] (netlink_rcv_skb+0xb8/0x11c)
+ [ 39.536446] [<808cdb74>] (netlink_rcv_skb) from [<808ce1d0>] (genl_rcv+0x28/0x34)
+ [ 39.544344] [<808ce1d0>] (genl_rcv) from [<808cd234>] (netlink_unicast+0x174/0x274)
+ [ 39.551895] [<808cd234>] (netlink_unicast) from [<808cd510>] (netlink_sendmsg+0x1dc/0x440)
+ [ 39.559362] [<808cd510>] (netlink_sendmsg) from [<808596e0>] (____sys_sendmsg+0x1a8/0x1fc)
+ [ 39.567697] [<808596e0>] (____sys_sendmsg) from [<8085b1a8>] (___sys_sendmsg+0xa4/0xdc)
+ [ 39.575941] [<8085b1a8>] (___sys_sendmsg) from [<8085b310>] (sys_sendmsg+0x44/0x74)
+ [ 39.583841] [<8085b310>] (sys_sendmsg) from [<80300060>] (ret_fast_syscall+0x0/0x40)
+ ...
+ [ 39.620734] Code: bad PC value
+ [ 39.625869] ---[ end trace 8aef983ad3cbc032 ]---
+
+Fixes: ba60f2793d3a ("wifi: ath11k: initialize hw_ops for IPQ5018")
+Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/TYZPR01MB5556D6E3F63EAB5129D11420C953A@TYZPR01MB5556.apcprd01.prod.exchangelabs.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/hw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c
+index ab8f0ccacc6be..727e6a785bb98 100644
+--- a/drivers/net/wireless/ath/ath11k/hw.c
++++ b/drivers/net/wireless/ath/ath11k/hw.c
+@@ -1165,7 +1165,7 @@ const struct ath11k_hw_ops ipq5018_ops = {
+ .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid,
+ .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid,
+ .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2,
+-
++ .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector,
+ };
+
+ #define ATH11K_TX_RING_MASK_0 BIT(0)
+--
+2.39.2
+
--- /dev/null
+From f076903a2b7146c0af9c7c6f7e5aa2d218cc9ca0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 14:41:47 +0300
+Subject: wifi: ath11k: Add missing ops config for IPQ5018 in
+ ath11k_ahb_probe()
+
+From: Ziyang Huang <hzyitc@outlook.com>
+
+[ Upstream commit 469ddb20cae61cad9c4f208a4c8682305905a511 ]
+
+Without this patch, the IPQ5018 WiFi will fail and print the following
+logs:
+
+ [ 11.033179] ath11k c000000.wifi: unsupported device type 7
+ [ 11.033223] ath11k: probe of c000000.wifi failed with error -95
+
+Fixes: 25edca7bb18a ("wifi: ath11k: add ipq5018 device support")
+Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/TYZPR01MB5556D7AA10ABEDDDD2D8F39EC953A@TYZPR01MB5556.apcprd01.prod.exchangelabs.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/ahb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
+index 5cbba9a8b6ba9..396548e57022f 100644
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -1127,6 +1127,7 @@ static int ath11k_ahb_probe(struct platform_device *pdev)
+ switch (hw_rev) {
+ case ATH11K_HW_IPQ8074:
+ case ATH11K_HW_IPQ6018_HW10:
++ case ATH11K_HW_IPQ5018_HW10:
+ hif_ops = &ath11k_ahb_hif_ops_ipq8074;
+ pci_ops = NULL;
+ break;
+--
+2.39.2
+
--- /dev/null
+From 4c1ed9ed0616c1c7dd2ed929809177407a6b0e9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 14:41:48 +0300
+Subject: wifi: ath11k: Restart firmware after cold boot calibration for
+ IPQ5018
+
+From: Ziyang Huang <hzyitc@outlook.com>
+
+[ Upstream commit 80c5390e1f5e5b16d820512265530ef26073d8e0 ]
+
+Restart is required after cold boot calibration on IPQ5018. Otherwise,
+we get the following exception:
+
+ [ 14.412829] qcom-q6-mpd cd00000.remoteproc: fatal error received: err_smem_ver.2.1:
+ [ 14.412829] QC Image Version : QC_IMAGE_VERSION_STRING=WLAN.HK.2.6.0.1-00974-QCAHKSWPL_SILICONZ-1
+ [ 14.412829] Image Variant : IMAGE_VARIANT_STRING=5018.wlanfw2.map_spr_spr_evalQ
+ [ 14.412829] DALSysLogEvent.c:174 Assertion 0 failed param0 :zero,param1 :zero,param2 :zero
+ [ 14.412829] Thread ID : 0x00000048 Thread name : WLAN RT0 Process ID : 0x00000001 Process name :wlan0
+ [ 14.412829]
+ [ 14.412829] Registers:
+ [ 14.412829] SP : 0x4c81c120
+ [ 14.412829] FP : 0x4c81c138
+ [ 14.412829] PC : 0xb022c590
+ [ 14.412829] SSR : 0x00000000
+ [ 14.412829] BADVA : 0x00000000
+ [ 14.412829] LR : 0xb0008490
+ [ 14.412829]
+ [ 14.412829] StackDump
+ [ 14.412829] from:0x4c81c120
+ [ 14.412829] to: 0x00000000:
+ [ 14.412829]
+ [ 14.463006] remoteproc remoteproc0: crash detected in cd00000.remoteproc: type fatal error
+
+Fixes: 8dfe875aa24a ("wifi: ath11k: update hw params for IPQ5018")
+Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/TYZPR01MB55566969818BD4B49E770445C953A@TYZPR01MB5556.apcprd01.prod.exchangelabs.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
+index 75fdbe4ef83a4..329f0957f9f09 100644
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -671,6 +671,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
+ .hal_params = &ath11k_hw_hal_params_ipq8074,
+ .single_pdev_only = false,
+ .cold_boot_calib = true,
++ .cbcal_restart_fw = true,
+ .fix_l1ss = true,
+ .supports_dynamic_smps_6ghz = false,
+ .alloc_cacheable_memory = true,
+--
+2.39.2
+
--- /dev/null
+From 5f4f15b2cf49b0e928c45b24b2158dc82e96f42a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Apr 2023 17:35:01 +0300
+Subject: wifi: ath9k: avoid referencing uninit memory in ath9k_wmi_ctrl_rx
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit f24292e827088bba8de7158501ac25a59b064953 ]
+
+For the reasons also described in commit b383e8abed41 ("wifi: ath9k: avoid
+uninit memory read in ath9k_htc_rx_msg()"), ath9k_htc_rx_msg() should
+validate pkt_len before accessing the SKB.
+
+For example, the obtained SKB may have been badly constructed with
+pkt_len = 8. In this case, the SKB can only contain a valid htc_frame_hdr
+but after being processed in ath9k_htc_rx_msg() and passed to
+ath9k_wmi_ctrl_rx() endpoint RX handler, it is expected to have a WMI
+command header which should be located inside its data payload.
+
+Implement sanity checking inside ath9k_wmi_ctrl_rx(). Otherwise, uninit
+memory can be referenced.
+
+Tested on Qualcomm Atheros Communications AR9271 802.11n .
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
+Reported-and-tested-by: syzbot+f2cb6e0ffdb961921e4d@syzkaller.appspotmail.com
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230424183348.111355-1-pchelkin@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/wmi.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
+index 19345b8f7bfd5..d652c647d56b5 100644
+--- a/drivers/net/wireless/ath/ath9k/wmi.c
++++ b/drivers/net/wireless/ath/ath9k/wmi.c
+@@ -221,6 +221,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
+ if (unlikely(wmi->stopped))
+ goto free_skb;
+
++ /* Validate the obtained SKB. */
++ if (unlikely(skb->len < sizeof(struct wmi_cmd_hdr)))
++ goto free_skb;
++
+ hdr = (struct wmi_cmd_hdr *) skb->data;
+ cmd_id = be16_to_cpu(hdr->command_id);
+
+--
+2.39.2
+
--- /dev/null
+From a6d984f80478bbe19858ce3939dcf4e093ac3ca6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 16:46:55 +0300
+Subject: wifi: ath9k: convert msecs to jiffies where needed
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 2aa083acea9f61be3280184384551178f510ff51 ]
+
+Since 'ieee80211_queue_delayed_work()' expects timeout in
+jiffies and not milliseconds, 'msecs_to_jiffies()' should
+be used in 'ath_restart_work()' and '__ath9k_flush()'.
+
+Fixes: d63ffc45c5d3 ("ath9k: rename tx_complete_work to hw_check_work")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230613134655.248728-1-dmantipov@yandex.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
+index 7f9f06ea8a05f..6360d3356e256 100644
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -203,7 +203,7 @@ void ath_cancel_work(struct ath_softc *sc)
+ void ath_restart_work(struct ath_softc *sc)
+ {
+ ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
+- ATH_HW_CHECK_POLL_INT);
++ msecs_to_jiffies(ATH_HW_CHECK_POLL_INT));
+
+ if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah))
+ ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
+@@ -2240,7 +2240,7 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
+ }
+
+ ieee80211_queue_delayed_work(hw, &sc->hw_check_work,
+- ATH_HW_CHECK_POLL_INT);
++ msecs_to_jiffies(ATH_HW_CHECK_POLL_INT));
+ }
+
+ static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
+--
+2.39.2
+
--- /dev/null
+From 120dfbef172dd52cc28f62466bb7aecfb96d9417 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 18:03:17 +0300
+Subject: wifi: ath9k: don't allow to overwrite ENDPOINT0 attributes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit 061b0cb9327b80d7a0f63a33e7c3e2a91a71f142 ]
+
+A bad USB device is able to construct a service connection response
+message with target endpoint being ENDPOINT0 which is reserved for
+HTC_CTRL_RSVD_SVC and should not be modified to be used for any other
+services.
+
+Reject such service connection responses.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
+Reported-by: syzbot+b68fbebe56d8362907e8@syzkaller.appspotmail.com
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230516150427.79469-1-pchelkin@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/htc_hst.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
+index fe62ff668f757..99667aba289df 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
++++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
+@@ -114,7 +114,13 @@ static void htc_process_conn_rsp(struct htc_target *target,
+
+ if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
+ epid = svc_rspmsg->endpoint_id;
+- if (epid < 0 || epid >= ENDPOINT_MAX)
++
++ /* Check that the received epid for the endpoint to attach
++ * a new service is valid. ENDPOINT0 can't be used here as it
++ * is already reserved for HTC_CTRL_RSVD_SVC service and thus
++ * should not be modified.
++ */
++ if (epid <= ENDPOINT0 || epid >= ENDPOINT_MAX)
+ return;
+
+ service_id = be16_to_cpu(svc_rspmsg->service_id);
+--
+2.39.2
+
--- /dev/null
+From 9236f3d7c705aafc95dd44257bc915baea65d215 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Apr 2023 17:35:00 +0300
+Subject: wifi: ath9k: fix AR9003 mac hardware hang check register offset
+ calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Peter Seiderer <ps.report@gmx.net>
+
+[ Upstream commit 3e56c80931c7615250fe4bf83f93b57881969266 ]
+
+Fix ath9k_hw_verify_hang()/ar9003_hw_detect_mac_hang() register offset
+calculation (do not overflow the shift for the second register/queues
+above five, use the register layout described in the comments above
+ath9k_hw_verify_hang() instead).
+
+Fixes: 222e04830ff0 ("ath9k: Fix MAC HW hang check for AR9003")
+
+Reported-by: Gregg Wonderly <greggwonderly@seqtechllc.com>
+Link: https://lore.kernel.org/linux-wireless/E3A9C354-0CB7-420C-ADEF-F0177FB722F4@seqtechllc.com/
+Signed-off-by: Peter Seiderer <ps.report@gmx.net>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230422212423.26065-1-ps.report@gmx.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/ar9003_hw.c | 27 ++++++++++++++--------
+ 1 file changed, 18 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+index 4f27a9fb1482b..e9bd13eeee92f 100644
+--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+@@ -1099,17 +1099,22 @@ static bool ath9k_hw_verify_hang(struct ath_hw *ah, unsigned int queue)
+ {
+ u32 dma_dbg_chain, dma_dbg_complete;
+ u8 dcu_chain_state, dcu_complete_state;
++ unsigned int dbg_reg, reg_offset;
+ int i;
+
+- for (i = 0; i < NUM_STATUS_READS; i++) {
+- if (queue < 6)
+- dma_dbg_chain = REG_READ(ah, AR_DMADBG_4);
+- else
+- dma_dbg_chain = REG_READ(ah, AR_DMADBG_5);
++ if (queue < 6) {
++ dbg_reg = AR_DMADBG_4;
++ reg_offset = queue * 5;
++ } else {
++ dbg_reg = AR_DMADBG_5;
++ reg_offset = (queue - 6) * 5;
++ }
+
++ for (i = 0; i < NUM_STATUS_READS; i++) {
++ dma_dbg_chain = REG_READ(ah, dbg_reg);
+ dma_dbg_complete = REG_READ(ah, AR_DMADBG_6);
+
+- dcu_chain_state = (dma_dbg_chain >> (5 * queue)) & 0x1f;
++ dcu_chain_state = (dma_dbg_chain >> reg_offset) & 0x1f;
+ dcu_complete_state = dma_dbg_complete & 0x3;
+
+ if ((dcu_chain_state != 0x6) || (dcu_complete_state != 0x1))
+@@ -1128,6 +1133,7 @@ static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah)
+ u8 dcu_chain_state, dcu_complete_state;
+ bool dcu_wait_frdone = false;
+ unsigned long chk_dcu = 0;
++ unsigned int reg_offset;
+ unsigned int i = 0;
+
+ dma_dbg_4 = REG_READ(ah, AR_DMADBG_4);
+@@ -1139,12 +1145,15 @@ static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah)
+ goto exit;
+
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+- if (i < 6)
++ if (i < 6) {
+ chk_dbg = dma_dbg_4;
+- else
++ reg_offset = i * 5;
++ } else {
+ chk_dbg = dma_dbg_5;
++ reg_offset = (i - 6) * 5;
++ }
+
+- dcu_chain_state = (chk_dbg >> (5 * i)) & 0x1f;
++ dcu_chain_state = (chk_dbg >> reg_offset) & 0x1f;
+ if (dcu_chain_state == 0x6) {
+ dcu_wait_frdone = true;
+ chk_dcu |= BIT(i);
+--
+2.39.2
+
--- /dev/null
+From ab4c5be2d467a00699bcbf4c4928421665b0e180 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 11:37:44 +0200
+Subject: wifi: ath9k: Fix possible stall on ath9k_txq_list_has_key()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Remi Pommarel <repk@triplefau.lt>
+
+[ Upstream commit 75086cc6dee046e3fbb3dba148b376d8802f83bc ]
+
+On EDMA capable hardware, ath9k_txq_list_has_key() can enter infinite
+loop if it is called while all txq_fifos have packets that use different
+key that the one we are looking for. Fix it by exiting the loop if all
+txq_fifos have been checked already.
+
+Because this loop is called under spin_lock_bh() (see ath_txq_lock) it
+causes the following rcu stall:
+
+rcu: INFO: rcu_sched self-detected stall on CPU
+ath10k_pci 0000:01:00.0: failed to read temperature -11
+rcu: 1-....: (5254 ticks this GP) idle=189/1/0x4000000000000002 softirq=8442983/8442984 fqs=2579
+ (t=5257 jiffies g=17983297 q=334)
+Task dump for CPU 1:
+task:hostapd state:R running task stack: 0 pid: 297 ppid: 289 flags:0x0000000a
+Call trace:
+ dump_backtrace+0x0/0x170
+ show_stack+0x1c/0x24
+ sched_show_task+0x140/0x170
+ dump_cpu_task+0x48/0x54
+ rcu_dump_cpu_stacks+0xf0/0x134
+ rcu_sched_clock_irq+0x8d8/0x9fc
+ update_process_times+0xa0/0xec
+ tick_sched_timer+0x5c/0xd0
+ __hrtimer_run_queues+0x154/0x320
+ hrtimer_interrupt+0x120/0x2f0
+ arch_timer_handler_virt+0x38/0x44
+ handle_percpu_devid_irq+0x9c/0x1e0
+ handle_domain_irq+0x64/0x90
+ gic_handle_irq+0x78/0xb0
+ call_on_irq_stack+0x28/0x38
+ do_interrupt_handler+0x54/0x5c
+ el1_interrupt+0x2c/0x4c
+ el1h_64_irq_handler+0x14/0x1c
+ el1h_64_irq+0x74/0x78
+ ath9k_txq_has_key+0x1bc/0x250 [ath9k]
+ ath9k_set_key+0x1cc/0x3dc [ath9k]
+ drv_set_key+0x78/0x170
+ ieee80211_key_replace+0x564/0x6cc
+ ieee80211_key_link+0x174/0x220
+ ieee80211_add_key+0x11c/0x300
+ nl80211_new_key+0x12c/0x330
+ genl_family_rcv_msg_doit+0xbc/0x11c
+ genl_rcv_msg+0xd8/0x1c4
+ netlink_rcv_skb+0x40/0x100
+ genl_rcv+0x3c/0x50
+ netlink_unicast+0x1ec/0x2c0
+ netlink_sendmsg+0x198/0x3c0
+ ____sys_sendmsg+0x210/0x250
+ ___sys_sendmsg+0x78/0xc4
+ __sys_sendmsg+0x4c/0x90
+ __arm64_sys_sendmsg+0x28/0x30
+ invoke_syscall.constprop.0+0x60/0x100
+ do_el0_svc+0x48/0xd0
+ el0_svc+0x14/0x50
+ el0t_64_sync_handler+0xa8/0xb0
+ el0t_64_sync+0x158/0x15c
+
+This rcu stall is hard to reproduce as is, but changing ATH_TXFIFO_DEPTH
+from 8 to 2 makes it reasonably easy to reproduce.
+
+Fixes: ca2848022c12 ("ath9k: Postpone key cache entry deletion for TXQ frames reference it")
+Signed-off-by: Remi Pommarel <repk@triplefau.lt>
+Tested-by: Nicolas Escande <nico.escande@gmail.com>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230609093744.1985-1-repk@triplefau.lt
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/main.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
+index a4197c14f0a92..7f9f06ea8a05f 100644
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -850,7 +850,7 @@ static bool ath9k_txq_list_has_key(struct list_head *txq_list, u32 keyix)
+ static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix)
+ {
+ struct ath_hw *ah = sc->sc_ah;
+- int i;
++ int i, j;
+ struct ath_txq *txq;
+ bool key_in_use = false;
+
+@@ -868,8 +868,9 @@ static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix)
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+ int idx = txq->txq_tailidx;
+
+- while (!key_in_use &&
+- !list_empty(&txq->txq_fifo[idx])) {
++ for (j = 0; !key_in_use &&
++ !list_empty(&txq->txq_fifo[idx]) &&
++ j < ATH_TXFIFO_DEPTH; j++) {
+ key_in_use = ath9k_txq_list_has_key(
+ &txq->txq_fifo[idx], keyix);
+ INCR(idx, ATH_TXFIFO_DEPTH);
+--
+2.39.2
+
--- /dev/null
+From d5c58aaf97940617d38c5e4e529a5f4c11de9fa0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 May 2023 09:53:14 +0200
+Subject: wifi: atmel: Fix an error handling path in atmel_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 6b92e4351a29af52c285fe235e6e4d1a75de04b2 ]
+
+Should atmel_config() fail, some resources need to be released as already
+done in the remove function.
+
+While at it, remove a useless and erroneous comment. The probe is
+atmel_probe(), not atmel_attach().
+
+Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/1e65f174607a83348034197fa7d603bab10ba4a9.1684569156.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/atmel/atmel_cs.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/atmel/atmel_cs.c b/drivers/net/wireless/atmel/atmel_cs.c
+index 453bb84cb3386..58bba9875d366 100644
+--- a/drivers/net/wireless/atmel/atmel_cs.c
++++ b/drivers/net/wireless/atmel/atmel_cs.c
+@@ -72,6 +72,7 @@ struct local_info {
+ static int atmel_probe(struct pcmcia_device *p_dev)
+ {
+ struct local_info *local;
++ int ret;
+
+ dev_dbg(&p_dev->dev, "atmel_attach()\n");
+
+@@ -82,8 +83,16 @@ static int atmel_probe(struct pcmcia_device *p_dev)
+
+ p_dev->priv = local;
+
+- return atmel_config(p_dev);
+-} /* atmel_attach */
++ ret = atmel_config(p_dev);
++ if (ret)
++ goto err_free_priv;
++
++ return 0;
++
++err_free_priv:
++ kfree(p_dev->priv);
++ return ret;
++}
+
+ static void atmel_detach(struct pcmcia_device *link)
+ {
+--
+2.39.2
+
--- /dev/null
+From f6e8f241f530a7db0602605faf58630d32438306 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 09:54:04 +0300
+Subject: wifi: cfg80211: drop incorrect nontransmitted BSS update code
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 39432f8a3752a87a53fd8d5e51824a43aaae5cab ]
+
+The removed code ran for any BSS that was not included in the MBSSID
+element in order to update it. However, instead of using the correct
+inheritance rules, it would simply copy the elements from the
+transmitting AP. The result is that we would report incorrect elements
+in this case.
+
+After some discussions, it seems that there are likely not even APs
+actually using this feature. Either way, removing the code decreases
+complexity and makes the cfg80211 behaviour more correct.
+
+Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230616094949.cfd6d8db1f26.Ia1044902b86cd7d366400a4bfb93691b8f05d68c@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 154 ++++----------------------------------------
+ 1 file changed, 11 insertions(+), 143 deletions(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index bb1b2cd73dd21..68f9b6f7bf584 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -2301,118 +2301,6 @@ cfg80211_inform_bss_data(struct wiphy *wiphy,
+ }
+ EXPORT_SYMBOL(cfg80211_inform_bss_data);
+
+-static void
+-cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy,
+- struct cfg80211_inform_bss *data,
+- struct ieee80211_mgmt *mgmt, size_t len,
+- struct cfg80211_non_tx_bss *non_tx_data,
+- gfp_t gfp)
+-{
+- enum cfg80211_bss_frame_type ftype;
+- const u8 *ie = mgmt->u.probe_resp.variable;
+- size_t ielen = len - offsetof(struct ieee80211_mgmt,
+- u.probe_resp.variable);
+-
+- ftype = ieee80211_is_beacon(mgmt->frame_control) ?
+- CFG80211_BSS_FTYPE_BEACON : CFG80211_BSS_FTYPE_PRESP;
+-
+- cfg80211_parse_mbssid_data(wiphy, data, ftype, mgmt->bssid,
+- le64_to_cpu(mgmt->u.probe_resp.timestamp),
+- le16_to_cpu(mgmt->u.probe_resp.beacon_int),
+- ie, ielen, non_tx_data, gfp);
+-}
+-
+-static void
+-cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
+- struct cfg80211_bss *nontrans_bss,
+- struct ieee80211_mgmt *mgmt, size_t len)
+-{
+- u8 *ie, *new_ie, *pos;
+- const struct element *nontrans_ssid;
+- const u8 *trans_ssid, *mbssid;
+- size_t ielen = len - offsetof(struct ieee80211_mgmt,
+- u.probe_resp.variable);
+- size_t new_ie_len;
+- struct cfg80211_bss_ies *new_ies;
+- const struct cfg80211_bss_ies *old;
+- size_t cpy_len;
+-
+- lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock);
+-
+- ie = mgmt->u.probe_resp.variable;
+-
+- new_ie_len = ielen;
+- trans_ssid = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
+- if (!trans_ssid)
+- return;
+- new_ie_len -= trans_ssid[1];
+- mbssid = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen);
+- /*
+- * It's not valid to have the MBSSID element before SSID
+- * ignore if that happens - the code below assumes it is
+- * after (while copying things inbetween).
+- */
+- if (!mbssid || mbssid < trans_ssid)
+- return;
+- new_ie_len -= mbssid[1];
+-
+- nontrans_ssid = ieee80211_bss_get_elem(nontrans_bss, WLAN_EID_SSID);
+- if (!nontrans_ssid)
+- return;
+-
+- new_ie_len += nontrans_ssid->datalen;
+-
+- /* generate new ie for nontrans BSS
+- * 1. replace SSID with nontrans BSS' SSID
+- * 2. skip MBSSID IE
+- */
+- new_ie = kzalloc(new_ie_len, GFP_ATOMIC);
+- if (!new_ie)
+- return;
+-
+- new_ies = kzalloc(sizeof(*new_ies) + new_ie_len, GFP_ATOMIC);
+- if (!new_ies)
+- goto out_free;
+-
+- pos = new_ie;
+-
+- /* copy the nontransmitted SSID */
+- cpy_len = nontrans_ssid->datalen + 2;
+- memcpy(pos, nontrans_ssid, cpy_len);
+- pos += cpy_len;
+- /* copy the IEs between SSID and MBSSID */
+- cpy_len = trans_ssid[1] + 2;
+- memcpy(pos, (trans_ssid + cpy_len), (mbssid - (trans_ssid + cpy_len)));
+- pos += (mbssid - (trans_ssid + cpy_len));
+- /* copy the IEs after MBSSID */
+- cpy_len = mbssid[1] + 2;
+- memcpy(pos, mbssid + cpy_len, ((ie + ielen) - (mbssid + cpy_len)));
+-
+- /* update ie */
+- new_ies->len = new_ie_len;
+- new_ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
+- new_ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control);
+- memcpy(new_ies->data, new_ie, new_ie_len);
+- if (ieee80211_is_probe_resp(mgmt->frame_control)) {
+- old = rcu_access_pointer(nontrans_bss->proberesp_ies);
+- rcu_assign_pointer(nontrans_bss->proberesp_ies, new_ies);
+- rcu_assign_pointer(nontrans_bss->ies, new_ies);
+- if (old)
+- kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
+- } 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);
+- }
+-
+-out_free:
+- kfree(new_ie);
+-}
+-
+ /* cfg80211_inform_bss_width_frame helper */
+ static struct cfg80211_bss *
+ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
+@@ -2554,51 +2442,31 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
+ struct ieee80211_mgmt *mgmt, size_t len,
+ gfp_t gfp)
+ {
+- struct cfg80211_bss *res, *tmp_bss;
++ struct cfg80211_bss *res;
+ const u8 *ie = mgmt->u.probe_resp.variable;
+- const struct cfg80211_bss_ies *ies1, *ies2;
+ size_t ielen = len - offsetof(struct ieee80211_mgmt,
+ u.probe_resp.variable);
++ enum cfg80211_bss_frame_type ftype;
+ struct cfg80211_non_tx_bss non_tx_data = {};
+
+ res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt,
+ len, gfp);
++ if (!res)
++ return NULL;
+
+ /* 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;
+- if (wiphy->support_only_he_mbssid &&
+- !cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen))
+- return res;
+-
++ ftype = ieee80211_is_beacon(mgmt->frame_control) ?
++ CFG80211_BSS_FTYPE_BEACON : CFG80211_BSS_FTYPE_PRESP;
+ non_tx_data.tx_bss = res;
+- /* process each non-transmitting bss */
+- cfg80211_parse_mbssid_frame_data(wiphy, data, mgmt, len,
+- &non_tx_data, gfp);
+-
+- spin_lock_bh(&wiphy_to_rdev(wiphy)->bss_lock);
+
+- /* check if the res has other nontransmitting bss which is not
+- * in MBSSID IE
+- */
+- ies1 = rcu_access_pointer(res->ies);
+-
+- /* go through nontrans_list, if the timestamp of the BSS is
+- * earlier than the timestamp of the transmitting BSS then
+- * update it
+- */
+- list_for_each_entry(tmp_bss, &res->nontrans_list,
+- nontrans_list) {
+- ies2 = rcu_access_pointer(tmp_bss->ies);
+- if (ies2->tsf < ies1->tsf)
+- cfg80211_update_notlisted_nontrans(wiphy, tmp_bss,
+- mgmt, len);
+- }
+- spin_unlock_bh(&wiphy_to_rdev(wiphy)->bss_lock);
++ /* process each non-transmitting bss */
++ cfg80211_parse_mbssid_data(wiphy, data, ftype, mgmt->bssid,
++ le64_to_cpu(mgmt->u.probe_resp.timestamp),
++ le16_to_cpu(mgmt->u.probe_resp.beacon_int),
++ ie, ielen, &non_tx_data, gfp);
+
+ return res;
+ }
+--
+2.39.2
+
--- /dev/null
+From 99afd1278f539c559d2cdd50972b54d964d2ddb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 22:28:45 +0200
+Subject: wifi: cfg80211: fix regulatory disconnect with OCB/NAN
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit e8c2af660ba0790afd14d5cbc2fd05c6dc85e207 ]
+
+Since regulatory disconnect was added, OCB and NAN interface
+types were added, which made it completely unusable for any
+driver that allowed OCB/NAN. Add OCB/NAN (though NAN doesn't
+do anything, we don't have any info) and also remove all the
+logic that opts out, so it won't be broken again if/when new
+interface types are added.
+
+Fixes: 6e0bd6c35b02 ("cfg80211: 802.11p OCB mode handling")
+Fixes: cb3b7d87652a ("cfg80211: add start / stop NAN commands")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Link: https://lore.kernel.org/r/20230616222844.2794d1625a26.I8e78a3789a29e6149447b3139df724a6f1b46fc3@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/regulatory.h | 13 +------------
+ net/wireless/core.c | 16 ----------------
+ net/wireless/reg.c | 14 ++++++++++----
+ 3 files changed, 11 insertions(+), 32 deletions(-)
+
+diff --git a/include/net/regulatory.h b/include/net/regulatory.h
+index 896191f420d50..b2cb4a9eb04dc 100644
+--- a/include/net/regulatory.h
++++ b/include/net/regulatory.h
+@@ -140,17 +140,6 @@ struct regulatory_request {
+ * otherwise initiating radiation is not allowed. This will enable the
+ * relaxations enabled under the CFG80211_REG_RELAX_NO_IR configuration
+ * option
+- * @REGULATORY_IGNORE_STALE_KICKOFF: the regulatory core will _not_ make sure
+- * all interfaces on this wiphy reside on allowed channels. If this flag
+- * is not set, upon a regdomain change, the interfaces are given a grace
+- * period (currently 60 seconds) to disconnect or move to an allowed
+- * channel. Interfaces on forbidden channels are forcibly disconnected.
+- * Currently these types of interfaces are supported for enforcement:
+- * NL80211_IFTYPE_ADHOC, NL80211_IFTYPE_STATION, NL80211_IFTYPE_AP,
+- * NL80211_IFTYPE_AP_VLAN, NL80211_IFTYPE_MONITOR,
+- * NL80211_IFTYPE_P2P_CLIENT, NL80211_IFTYPE_P2P_GO,
+- * NL80211_IFTYPE_P2P_DEVICE. The flag will be set by default if a device
+- * includes any modes unsupported for enforcement checking.
+ * @REGULATORY_WIPHY_SELF_MANAGED: for devices that employ wiphy-specific
+ * regdom management. These devices will ignore all regdom changes not
+ * originating from their own wiphy.
+@@ -177,7 +166,7 @@ enum ieee80211_regulatory_flags {
+ REGULATORY_COUNTRY_IE_FOLLOW_POWER = BIT(3),
+ REGULATORY_COUNTRY_IE_IGNORE = BIT(4),
+ REGULATORY_ENABLE_RELAX_NO_IR = BIT(5),
+- REGULATORY_IGNORE_STALE_KICKOFF = BIT(6),
++ /* reuse bit 6 next time */
+ REGULATORY_WIPHY_SELF_MANAGED = BIT(7),
+ };
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index b3ec9eaec36b3..609b79fe4a748 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -721,22 +721,6 @@ int wiphy_register(struct wiphy *wiphy)
+ return -EINVAL;
+ }
+
+- /*
+- * if a wiphy has unsupported modes for regulatory channel enforcement,
+- * opt-out of enforcement checking
+- */
+- if (wiphy->interface_modes & ~(BIT(NL80211_IFTYPE_STATION) |
+- BIT(NL80211_IFTYPE_P2P_CLIENT) |
+- BIT(NL80211_IFTYPE_AP) |
+- BIT(NL80211_IFTYPE_MESH_POINT) |
+- BIT(NL80211_IFTYPE_P2P_GO) |
+- BIT(NL80211_IFTYPE_ADHOC) |
+- BIT(NL80211_IFTYPE_P2P_DEVICE) |
+- BIT(NL80211_IFTYPE_NAN) |
+- BIT(NL80211_IFTYPE_AP_VLAN) |
+- BIT(NL80211_IFTYPE_MONITOR)))
+- wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
+-
+ if (WARN_ON((wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) &&
+ (wiphy->regulatory_flags &
+ (REGULATORY_CUSTOM_REG |
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index 26f11e4746c05..c8a1b925413b3 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -2391,9 +2391,17 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
+ case NL80211_IFTYPE_P2P_DEVICE:
+ /* no enforcement required */
+ break;
++ case NL80211_IFTYPE_OCB:
++ if (!wdev->u.ocb.chandef.chan)
++ continue;
++ chandef = wdev->u.ocb.chandef;
++ break;
++ case NL80211_IFTYPE_NAN:
++ /* we have no info, but NAN is also pretty universal */
++ continue;
+ default:
+ /* others not implemented for now */
+- WARN_ON(1);
++ WARN_ON_ONCE(1);
+ break;
+ }
+
+@@ -2452,9 +2460,7 @@ static void reg_check_chans_work(struct work_struct *work)
+ rtnl_lock();
+
+ list_for_each_entry(rdev, &cfg80211_rdev_list, list)
+- if (!(rdev->wiphy.regulatory_flags &
+- REGULATORY_IGNORE_STALE_KICKOFF))
+- reg_leave_invalid_chans(&rdev->wiphy);
++ reg_leave_invalid_chans(&rdev->wiphy);
+
+ rtnl_unlock();
+ }
+--
+2.39.2
+
--- /dev/null
+From 06c4b7ef546dfe2c63f1b06b5927ab246a2c9fdd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 09:54:03 +0300
+Subject: wifi: cfg80211: rewrite merging of inherited elements
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit dfd9aa3e7a456d57b18021d66472ab7ff8373ab7 ]
+
+The cfg80211_gen_new_ie function merges the IEs using inheritance rules.
+Rewrite this function to fix issues around inheritance rules. In
+particular, vendor elements do not require any special handling, as they
+are either all inherited or overridden by the subprofile.
+Also, add fragmentation handling as this may be needed in some cases.
+
+This also changes the function to not require making a copy. The new
+version could be optimized a bit by explicitly tracking which IEs have
+been handled already rather than looking that up again every time.
+
+Note that a small behavioural change is the removal of the SSID special
+handling. This should be fine for the MBSSID element, as the SSID must
+be included in the subelement.
+
+Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230616094949.bc6152e146db.I2b5f3bc45085e1901e5b5192a674436adaf94748@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 213 ++++++++++++++++++++++++++------------------
+ 1 file changed, 124 insertions(+), 89 deletions(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index b3829ed844f84..bb1b2cd73dd21 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -259,117 +259,152 @@ bool cfg80211_is_element_inherited(const struct element *elem,
+ }
+ EXPORT_SYMBOL(cfg80211_is_element_inherited);
+
+-static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
+- const u8 *subelement, size_t subie_len,
+- u8 *new_ie, gfp_t gfp)
++static size_t cfg80211_copy_elem_with_frags(const struct element *elem,
++ const u8 *ie, size_t ie_len,
++ u8 **pos, u8 *buf, size_t buf_len)
+ {
+- u8 *pos, *tmp;
+- const u8 *tmp_old, *tmp_new;
+- const struct element *non_inherit_elem;
+- u8 *sub_copy;
++ if (WARN_ON((u8 *)elem < ie || elem->data > ie + ie_len ||
++ elem->data + elem->datalen > ie + ie_len))
++ return 0;
+
+- /* copy subelement as we need to change its content to
+- * mark an ie after it is processed.
+- */
+- sub_copy = kmemdup(subelement, subie_len, gfp);
+- if (!sub_copy)
++ if (elem->datalen + 2 > buf + buf_len - *pos)
+ return 0;
+
+- pos = &new_ie[0];
++ memcpy(*pos, elem, elem->datalen + 2);
++ *pos += elem->datalen + 2;
+
+- /* set new ssid */
+- tmp_new = cfg80211_find_ie(WLAN_EID_SSID, sub_copy, subie_len);
+- if (tmp_new) {
+- memcpy(pos, tmp_new, tmp_new[1] + 2);
+- pos += (tmp_new[1] + 2);
++ /* Finish if it is not fragmented */
++ if (elem->datalen != 255)
++ return *pos - buf;
++
++ ie_len = ie + ie_len - elem->data - elem->datalen;
++ ie = (const u8 *)elem->data + elem->datalen;
++
++ for_each_element(elem, ie, ie_len) {
++ if (elem->id != WLAN_EID_FRAGMENT)
++ break;
++
++ if (elem->datalen + 2 > buf + buf_len - *pos)
++ return 0;
++
++ memcpy(*pos, elem, elem->datalen + 2);
++ *pos += elem->datalen + 2;
++
++ if (elem->datalen != 255)
++ break;
+ }
+
+- /* get non inheritance list if exists */
+- non_inherit_elem =
+- cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
+- sub_copy, subie_len);
++ return *pos - buf;
++}
+
+- /* go through IEs in ie (skip SSID) and subelement,
+- * merge them into new_ie
++static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
++ const u8 *subie, size_t subie_len,
++ u8 *new_ie, size_t new_ie_len)
++{
++ const struct element *non_inherit_elem, *parent, *sub;
++ u8 *pos = new_ie;
++ u8 id, ext_id;
++ unsigned int match_len;
++
++ non_inherit_elem = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
++ subie, subie_len);
++
++ /* We copy the elements one by one from the parent to the generated
++ * elements.
++ * If they are not inherited (included in subie or in the non
++ * inheritance element), then we copy all occurrences the first time
++ * we see this element type.
+ */
+- tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
+- tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
+-
+- while (tmp_old + 2 - ie <= ielen &&
+- tmp_old + tmp_old[1] + 2 - ie <= ielen) {
+- if (tmp_old[0] == 0) {
+- tmp_old++;
++ for_each_element(parent, ie, ielen) {
++ if (parent->id == WLAN_EID_FRAGMENT)
+ continue;
++
++ if (parent->id == WLAN_EID_EXTENSION) {
++ if (parent->datalen < 1)
++ continue;
++
++ id = WLAN_EID_EXTENSION;
++ ext_id = parent->data[0];
++ match_len = 1;
++ } else {
++ id = parent->id;
++ match_len = 0;
+ }
+
+- if (tmp_old[0] == WLAN_EID_EXTENSION)
+- tmp = (u8 *)cfg80211_find_ext_ie(tmp_old[2], sub_copy,
+- subie_len);
+- else
+- tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy,
+- subie_len);
++ /* Find first occurrence in subie */
++ sub = cfg80211_find_elem_match(id, subie, subie_len,
++ &ext_id, match_len, 0);
+
+- if (!tmp) {
+- const struct element *old_elem = (void *)tmp_old;
++ /* Copy from parent if not in subie and inherited */
++ if (!sub &&
++ cfg80211_is_element_inherited(parent, non_inherit_elem)) {
++ if (!cfg80211_copy_elem_with_frags(parent,
++ ie, ielen,
++ &pos, new_ie,
++ new_ie_len))
++ return 0;
+
+- /* ie in old ie but not in subelement */
+- if (cfg80211_is_element_inherited(old_elem,
+- non_inherit_elem)) {
+- memcpy(pos, tmp_old, tmp_old[1] + 2);
+- pos += tmp_old[1] + 2;
+- }
+- } else {
+- /* ie in transmitting ie also in subelement,
+- * copy from subelement and flag the ie in subelement
+- * as copied (by setting eid field to WLAN_EID_SSID,
+- * which is skipped anyway).
+- * For vendor ie, compare OUI + type + subType to
+- * determine if they are the same ie.
+- */
+- if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
+- if (tmp_old[1] >= 5 && tmp[1] >= 5 &&
+- !memcmp(tmp_old + 2, tmp + 2, 5)) {
+- /* same vendor ie, copy from
+- * subelement
+- */
+- memcpy(pos, tmp, tmp[1] + 2);
+- pos += tmp[1] + 2;
+- tmp[0] = WLAN_EID_SSID;
+- } else {
+- memcpy(pos, tmp_old, tmp_old[1] + 2);
+- pos += tmp_old[1] + 2;
+- }
+- } else {
+- /* copy ie from subelement into new ie */
+- memcpy(pos, tmp, tmp[1] + 2);
+- pos += tmp[1] + 2;
+- tmp[0] = WLAN_EID_SSID;
+- }
++ continue;
+ }
+
+- if (tmp_old + tmp_old[1] + 2 - ie == ielen)
+- break;
++ /* Already copied if an earlier element had the same type */
++ if (cfg80211_find_elem_match(id, ie, (u8 *)parent - ie,
++ &ext_id, match_len, 0))
++ continue;
+
+- tmp_old += tmp_old[1] + 2;
++ /* Not inheriting, copy all similar elements from subie */
++ while (sub) {
++ if (!cfg80211_copy_elem_with_frags(sub,
++ subie, subie_len,
++ &pos, new_ie,
++ new_ie_len))
++ return 0;
++
++ sub = cfg80211_find_elem_match(id,
++ sub->data + sub->datalen,
++ subie_len + subie -
++ (sub->data +
++ sub->datalen),
++ &ext_id, match_len, 0);
++ }
+ }
+
+- /* go through subelement again to check if there is any ie not
+- * copied to new ie, skip ssid, capability, bssid-index ie
++ /* The above misses elements that are included in subie but not in the
++ * parent, so do a pass over subie and append those.
++ * Skip the non-tx BSSID caps and non-inheritance element.
+ */
+- tmp_new = sub_copy;
+- 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);
+- pos += tmp_new[1] + 2;
++ for_each_element(sub, subie, subie_len) {
++ if (sub->id == WLAN_EID_NON_TX_BSSID_CAP)
++ continue;
++
++ if (sub->id == WLAN_EID_FRAGMENT)
++ continue;
++
++ if (sub->id == WLAN_EID_EXTENSION) {
++ if (sub->datalen < 1)
++ continue;
++
++ id = WLAN_EID_EXTENSION;
++ ext_id = sub->data[0];
++ match_len = 1;
++
++ if (ext_id == WLAN_EID_EXT_NON_INHERITANCE)
++ continue;
++ } else {
++ id = sub->id;
++ match_len = 0;
+ }
+- if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len)
+- break;
+- tmp_new += tmp_new[1] + 2;
++
++ /* Processed if one was included in the parent */
++ if (cfg80211_find_elem_match(id, ie, ielen,
++ &ext_id, match_len, 0))
++ continue;
++
++ if (!cfg80211_copy_elem_with_frags(sub, subie, subie_len,
++ &pos, new_ie, new_ie_len))
++ return 0;
+ }
+
+- kfree(sub_copy);
+ return pos - new_ie;
+ }
+
+@@ -2217,7 +2252,7 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
+ new_ie_len = cfg80211_gen_new_ie(ie, ielen,
+ profile,
+ profile_len, new_ie,
+- gfp);
++ IEEE80211_MAX_DATA_LEN);
+ if (!new_ie_len)
+ continue;
+
+--
+2.39.2
+
--- /dev/null
+From c5967a8370cb6df70b98dbba67c4bab3cfe8779a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Jun 2023 21:49:45 +0300
+Subject: wifi: ieee80211: Fix the common size calculation for reconfiguration
+ ML
+
+From: Ilan Peer <ilan.peer@intel.com>
+
+[ Upstream commit ce6e1f600b0cfc563a7d607de702262a58cd835d ]
+
+The common information length is found in the first octet of the common
+information.
+
+Fixes: 0f48b8b88aa9 ("wifi: ieee80211: add definitions for multi-link element")
+Signed-off-by: Ilan Peer <ilan.peer@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230618214435.3c7ed4817338.I42ef706cb827b4dade6e4ffbb6e7f341eaccd398@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/ieee80211.h | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
+index 2463bdd2a382d..1e25c9060225c 100644
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -4592,15 +4592,12 @@ static inline u8 ieee80211_mle_common_size(const u8 *data)
+ case IEEE80211_ML_CONTROL_TYPE_BASIC:
+ case IEEE80211_ML_CONTROL_TYPE_PREQ:
+ case IEEE80211_ML_CONTROL_TYPE_TDLS:
++ case IEEE80211_ML_CONTROL_TYPE_RECONF:
+ /*
+ * The length is the first octet pointed by mle->variable so no
+ * need to add anything
+ */
+ break;
+- case IEEE80211_ML_CONTROL_TYPE_RECONF:
+- if (control & IEEE80211_MLC_RECONF_PRES_MLD_MAC_ADDR)
+- common += ETH_ALEN;
+- return common;
+ case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS:
+ if (control & IEEE80211_MLC_PRIO_ACCESS_PRES_AP_MLD_MAC_ADDR)
+ common += ETH_ALEN;
+--
+2.39.2
+
--- /dev/null
+From 1d9bf790810ab26bb0ca3fef6714619890ee69fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 13:04:01 +0300
+Subject: wifi: iwlwifi: mvm: indicate HW decrypt for beacon protection
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 2db72b8a700943aa54dce0aabe6ff1b72b615162 ]
+
+We've already done the 'decryption' here, so tell
+mac80211 it need not do it again.
+
+Fixes: b1fdc2505abc ("iwlwifi: mvm: advertise BIGTK client support if available")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230620125813.a50cf68fbf2e.Ieceacbe3789d81ea02ae085ad8d1f8813a33c31b@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+index ad410b6efce73..7ebcf0ef29255 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+@@ -274,7 +274,8 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
+ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
+ struct ieee80211_hdr *hdr,
+ struct iwl_rx_mpdu_desc *desc,
+- u32 status)
++ u32 status,
++ struct ieee80211_rx_status *stats)
+ {
+ struct iwl_mvm_sta *mvmsta;
+ struct iwl_mvm_vif *mvmvif;
+@@ -303,8 +304,10 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
+
+ /* good cases */
+ if (likely(status & IWL_RX_MPDU_STATUS_MIC_OK &&
+- !(status & IWL_RX_MPDU_STATUS_REPLAY_ERROR)))
++ !(status & IWL_RX_MPDU_STATUS_REPLAY_ERROR))) {
++ stats->flag |= RX_FLAG_DECRYPTED;
+ return 0;
++ }
+
+ if (!sta)
+ return -1;
+@@ -373,7 +376,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
+
+ if (unlikely(ieee80211_is_mgmt(hdr->frame_control) &&
+ !ieee80211_has_protected(hdr->frame_control)))
+- return iwl_mvm_rx_mgmt_prot(sta, hdr, desc, status);
++ return iwl_mvm_rx_mgmt_prot(sta, hdr, desc, status, stats);
+
+ if (!ieee80211_has_protected(hdr->frame_control) ||
+ (status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
+--
+2.39.2
+
--- /dev/null
+From 1385756205708772d8f69e100c73b44887e88fa2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 12:41:32 +0300
+Subject: wifi: iwlwifi: pcie: fix NULL pointer dereference in
+ iwl_pcie_irq_rx_msix_handler()
+
+From: Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
+
+[ Upstream commit 1902f1953b8ba100ee8705cb8a6f1a9795550eca ]
+
+rxq can be NULL only when trans_pcie->rxq is NULL and entry->entry
+is zero. For the case when entry->entry is not equal to 0, rxq
+won't be NULL even if trans_pcie->rxq is NULL. Modify checker to
+check for trans_pcie->rxq.
+
+Fixes: abc599efa67b ("iwlwifi: pcie: don't crash when rx queues aren't allocated in interrupt")
+Signed-off-by: Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230614123446.5a5eb3889a4a.I375a1d58f16b48cd2044e7b7caddae512d7c86fd@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+index 9c9f87fe83777..b455e981faa1f 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+@@ -1620,14 +1620,14 @@ irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id)
+ struct msix_entry *entry = dev_id;
+ struct iwl_trans_pcie *trans_pcie = iwl_pcie_get_trans_pcie(entry);
+ struct iwl_trans *trans = trans_pcie->trans;
+- struct iwl_rxq *rxq = &trans_pcie->rxq[entry->entry];
++ struct iwl_rxq *rxq;
+
+ trace_iwlwifi_dev_irq_msix(trans->dev, entry, false, 0, 0);
+
+ if (WARN_ON(entry->entry >= trans->num_rx_queues))
+ return IRQ_NONE;
+
+- if (!rxq) {
++ if (!trans_pcie->rxq) {
+ if (net_ratelimit())
+ IWL_ERR(trans,
+ "[%d] Got MSI-X interrupt before we have Rx queues\n",
+@@ -1635,6 +1635,7 @@ irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id)
+ return IRQ_NONE;
+ }
+
++ rxq = &trans_pcie->rxq[entry->entry];
+ lock_map_acquire(&trans->sync_cmd_lockdep_map);
+ IWL_DEBUG_ISR(trans, "[%d] Got interrupt\n", entry->entry);
+
+--
+2.39.2
+
--- /dev/null
+From f94bc795c4fb8d66d74e0844465b444107cff821 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 12:41:22 +0300
+Subject: wifi: iwlwifi: pull from TXQs with softirqs disabled
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 96fb6f47db24a712d650b0a9b9074873f273fb0e ]
+
+In mac80211, it's required that we pull from TXQs by calling
+ieee80211_tx_dequeue() only with softirqs disabled. However,
+in iwl_mvm_queue_state_change() we're often called with them
+enabled, e.g. from flush if anything was flushed, triggering
+a mac80211 warning.
+
+Fix that by disabling the softirqs across the TX call.
+
+Fixes: cfbc6c4c5b91 ("iwlwifi: mvm: support mac80211 TXQs model")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230614123446.0feef7fa81db.I4dd62542d955b40dd8f0af34fa4accb9d0d17c7e@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+index 9711841bb4564..3d91293cc250d 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+@@ -1697,8 +1697,11 @@ static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode,
+ else
+ set_bit(IWL_MVM_TXQ_STATE_STOP_FULL, &mvmtxq->state);
+
+- if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST)
++ if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST) {
++ local_bh_disable();
+ iwl_mvm_mac_itxq_xmit(mvm->hw, txq);
++ local_bh_enable();
++ }
+ }
+
+ out:
+--
+2.39.2
+
--- /dev/null
+From 16d51bed8ee3194a1ec2465c1359781fe570c0ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Jun 2023 12:14:28 +0300
+Subject: wifi: mac80211: Fix permissions for valid_links debugfs entry
+
+From: Ilan Peer <ilan.peer@intel.com>
+
+[ Upstream commit 4cacadc0dbd8013e6161aa8843d8e9d8ad435b47 ]
+
+The entry should be a read only one and not a write only one. Fix it.
+
+Fixes: 3d9011029227 ("wifi: mac80211: implement link switching")
+Signed-off-by: Ilan Peer <ilan.peer@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230611121219.c75316990411.I1565a7fcba8a37f83efffb0cc6b71c572b896e94@changeid
+[remove x16 change since it doesn't work yet]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/debugfs_netdev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
+index 0bac9af3ca966..371add9061f1f 100644
+--- a/net/mac80211/debugfs_netdev.c
++++ b/net/mac80211/debugfs_netdev.c
+@@ -691,7 +691,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
+ DEBUGFS_ADD_MODE(uapsd_queues, 0600);
+ DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600);
+ DEBUGFS_ADD_MODE(tdls_wider_bw, 0600);
+- DEBUGFS_ADD_MODE(valid_links, 0200);
++ DEBUGFS_ADD_MODE(valid_links, 0400);
+ DEBUGFS_ADD_MODE(active_links, 0600);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From b6419f8440a0e5101f9e1e2a8d335bec1a66bde9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Jun 2023 12:11:20 +0300
+Subject: wifi: mac80211: recalc min chandef for new STA links
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit ba7af2654e3b7b810c750b3c6106f6f20b81cc88 ]
+
+When adding a new link to a station, this needs to cause a
+recalculation of the minimum chandef since otherwise we can
+have a higher bandwidth station connected on that link than
+the link is operating at. Do the appropriate recalc.
+
+Fixes: cb71f1d136a6 ("wifi: mac80211: add sta link addition/removal")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230604120651.377adf3c789a.I91bf28f399e16e6ac1f83bacd1029a698b4e6685@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/sta_info.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index 941bda9141faa..2ec9e1ead127e 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -2901,6 +2901,8 @@ int ieee80211_sta_activate_link(struct sta_info *sta, unsigned int link_id)
+ if (!test_sta_flag(sta, WLAN_STA_INSERTED))
+ goto hash;
+
++ ieee80211_recalc_min_chandef(sdata, link_id);
++
+ /* Ensure the values are updated for the driver,
+ * redone by sta_remove_link on failure.
+ */
+--
+2.39.2
+
--- /dev/null
+From b9a55b7e86829a448cf50db3822d679bc89fd0a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 15:26:48 +0200
+Subject: wifi: mac80211: Remove "Missing iftype sband data/EHT cap" spam
+
+From: Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
+
+[ Upstream commit 6e21e7b8cd897193cee3c2649640efceb3004ba5 ]
+
+In mesh mode, ieee80211_chandef_he_6ghz_oper() is called by
+mesh_matches_local() for every received mesh beacon.
+
+On a 6 GHz mesh of a HE-only phy, this spams that the hardware does not
+have EHT capabilities, even if the received mesh beacon does not have an
+EHT element.
+
+Unlike HE, not supporting EHT in the 6 GHz band is not an error so do
+not print anything in this case.
+
+Fixes: 5dca295dd767 ("mac80211: Add initial support for EHT and 320 MHz channels")
+
+Signed-off-by: Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Link: https://lore.kernel.org/r/20230614132648.28995-1-nicolas.cavallari@green-communications.fr
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/util.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index 1a0d38cd46337..ce25d14db4d28 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -3707,10 +3707,8 @@ bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
+ }
+
+ eht_cap = ieee80211_get_eht_iftype_cap(sband, iftype);
+- if (!eht_cap) {
+- sdata_info(sdata, "Missing iftype sband data/EHT cap");
++ if (!eht_cap)
+ eht_oper = NULL;
+- }
+
+ he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);
+
+--
+2.39.2
+
--- /dev/null
+From 05c919d1e15507352e290b98a9eff8f66d1747b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 May 2023 15:53:15 +0200
+Subject: wifi: mwifiex: Fix the size of a memory allocation in
+ mwifiex_ret_802_11_scan()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit d9aef04fcfa81ee4fb2804a21a3712b7bbd936af ]
+
+The type of "mwifiex_adapter->nd_info" is "struct cfg80211_wowlan_nd_info",
+not "struct cfg80211_wowlan_nd_match".
+
+Use struct_size() to ease the computation of the needed size.
+
+The current code over-allocates some memory, so is safe.
+But it wastes 32 bytes.
+
+Fixes: 7d7f07d8c5d3 ("mwifiex: add wowlan net-detect support")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/7a6074fb056d2181e058a3cc6048d8155c20aec7.1683371982.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/scan.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
+index ac8001c842935..644b1e134b01c 100644
+--- a/drivers/net/wireless/marvell/mwifiex/scan.c
++++ b/drivers/net/wireless/marvell/mwifiex/scan.c
+@@ -2187,9 +2187,9 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
+
+ if (nd_config) {
+ adapter->nd_info =
+- kzalloc(sizeof(struct cfg80211_wowlan_nd_match) +
+- sizeof(struct cfg80211_wowlan_nd_match *) *
+- scan_rsp->number_of_sets, GFP_ATOMIC);
++ kzalloc(struct_size(adapter->nd_info, matches,
++ scan_rsp->number_of_sets),
++ GFP_ATOMIC);
+
+ if (adapter->nd_info)
+ adapter->nd_info->n_matches = scan_rsp->number_of_sets;
+--
+2.39.2
+
--- /dev/null
+From ecef6b206475f8d82b0c01b19b66bdd7d0ee6250 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 May 2023 09:38:22 +0200
+Subject: wifi: orinoco: Fix an error handling path in orinoco_cs_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 67a81d911c01225f426cc6bee2373df044c1a9b7 ]
+
+Should orinoco_cs_config() fail, some resources need to be released as
+already done in the remove function.
+
+While at it, remove a useless and erroneous comment. The probe is
+orinoco_cs_probe(), not orinoco_cs_attach().
+
+Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/e24735ce4d82901d5f7ea08419eea53bfdde3d65.1684568286.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/orinoco/orinoco_cs.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_cs.c b/drivers/net/wireless/intersil/orinoco/orinoco_cs.c
+index a956f965a1e5e..03bfd2482656c 100644
+--- a/drivers/net/wireless/intersil/orinoco/orinoco_cs.c
++++ b/drivers/net/wireless/intersil/orinoco/orinoco_cs.c
+@@ -96,6 +96,7 @@ orinoco_cs_probe(struct pcmcia_device *link)
+ {
+ struct orinoco_private *priv;
+ struct orinoco_pccard *card;
++ int ret;
+
+ priv = alloc_orinocodev(sizeof(*card), &link->dev,
+ orinoco_cs_hard_reset, NULL);
+@@ -107,8 +108,16 @@ orinoco_cs_probe(struct pcmcia_device *link)
+ card->p_dev = link;
+ link->priv = priv;
+
+- return orinoco_cs_config(link);
+-} /* orinoco_cs_attach */
++ ret = orinoco_cs_config(link);
++ if (ret)
++ goto err_free_orinocodev;
++
++ return 0;
++
++err_free_orinocodev:
++ free_orinocodev(priv);
++ return ret;
++}
+
+ static void orinoco_cs_detach(struct pcmcia_device *link)
+ {
+--
+2.39.2
+
--- /dev/null
+From bc25fc07a167e239f094036950de6f079481fb62 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 May 2023 09:29:46 +0200
+Subject: wifi: orinoco: Fix an error handling path in spectrum_cs_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 925244325159824385209e3e0e3f91fa6bf0646c ]
+
+Should spectrum_cs_config() fail, some resources need to be released as
+already done in the remove function.
+
+While at it, remove a useless and erroneous comment. The probe is
+spectrum_cs_probe(), not spectrum_cs_attach().
+
+Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/c0bc0c21c58ca477fc5521607615bafbf2aef8eb.1684567733.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/orinoco/spectrum_cs.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/intersil/orinoco/spectrum_cs.c b/drivers/net/wireless/intersil/orinoco/spectrum_cs.c
+index 291ef97ed45ec..841d623c621ac 100644
+--- a/drivers/net/wireless/intersil/orinoco/spectrum_cs.c
++++ b/drivers/net/wireless/intersil/orinoco/spectrum_cs.c
+@@ -157,6 +157,7 @@ spectrum_cs_probe(struct pcmcia_device *link)
+ {
+ struct orinoco_private *priv;
+ struct orinoco_pccard *card;
++ int ret;
+
+ priv = alloc_orinocodev(sizeof(*card), &link->dev,
+ spectrum_cs_hard_reset,
+@@ -169,8 +170,16 @@ spectrum_cs_probe(struct pcmcia_device *link)
+ card->p_dev = link;
+ link->priv = priv;
+
+- return spectrum_cs_config(link);
+-} /* spectrum_cs_attach */
++ ret = spectrum_cs_config(link);
++ if (ret)
++ goto err_free_orinocodev;
++
++ return 0;
++
++err_free_orinocodev:
++ free_orinocodev(priv);
++ return ret;
++}
+
+ static void spectrum_cs_detach(struct pcmcia_device *link)
+ {
+--
+2.39.2
+
--- /dev/null
+From 76368a5f5f7d716cc80f7b4ec63827c59098e8ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 May 2023 10:13:22 +0200
+Subject: wifi: ray_cs: Fix an error handling path in ray_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 4f8d66a9fb2edcd05c1e563456a55a08910bfb37 ]
+
+Should ray_config() fail, some resources need to be released as already
+done in the remove function.
+
+While at it, remove a useless and erroneous comment. The probe is
+ray_probe(), not ray_attach().
+
+Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/8c544d18084f8b37dd108e844f7e79e85ff708ff.1684570373.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ray_cs.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
+index 1f57a0055bbd8..38782d4c4694a 100644
+--- a/drivers/net/wireless/ray_cs.c
++++ b/drivers/net/wireless/ray_cs.c
+@@ -270,13 +270,14 @@ static int ray_probe(struct pcmcia_device *p_dev)
+ {
+ ray_dev_t *local;
+ struct net_device *dev;
++ int ret;
+
+ dev_dbg(&p_dev->dev, "ray_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ dev = alloc_etherdev(sizeof(ray_dev_t));
+ if (!dev)
+- goto fail_alloc_dev;
++ return -ENOMEM;
+
+ local = netdev_priv(dev);
+ local->finder = p_dev;
+@@ -313,11 +314,16 @@ static int ray_probe(struct pcmcia_device *p_dev)
+ timer_setup(&local->timer, NULL, 0);
+
+ this_device = p_dev;
+- return ray_config(p_dev);
++ ret = ray_config(p_dev);
++ if (ret)
++ goto err_free_dev;
++
++ return 0;
+
+-fail_alloc_dev:
+- return -ENOMEM;
+-} /* ray_attach */
++err_free_dev:
++ free_netdev(dev);
++ return ret;
++}
+
+ static void ray_detach(struct pcmcia_device *link)
+ {
+--
+2.39.2
+
--- /dev/null
+From a0eab1cb118fbfa6e27612dd6f79cb7749c2df2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 May 2023 00:28:33 +0200
+Subject: wifi: rsi: Do not configure WoWlan in shutdown hook if not enabled
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit b241e260820b68c09586e8a0ae0fc23c0e3215bd ]
+
+In case WoWlan was never configured during the operation of the system,
+the hw->wiphy->wowlan_config will be NULL. rsi_config_wowlan() checks
+whether wowlan_config is non-NULL and if it is not, then WARNs about it.
+The warning is valid, as during normal operation the rsi_config_wowlan()
+should only ever be called with non-NULL wowlan_config. In shutdown this
+rsi_config_wowlan() should only ever be called if WoWlan was configured
+before by the user.
+
+Add checks for non-NULL wowlan_config into the shutdown hook. While at it,
+check whether the wiphy is also non-NULL before accessing wowlan_config .
+Drop the single-use wowlan_config variable, just inline it into function
+call.
+
+Fixes: 16bbc3eb8372 ("rsi: fix null pointer dereference during rsi_shutdown()")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230527222833.273741-1-marex@denx.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/rsi/rsi_91x_sdio.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
+index d09998796ac08..6e33a2563fdbd 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
++++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
+@@ -1463,10 +1463,8 @@ static void rsi_shutdown(struct device *dev)
+
+ rsi_dbg(ERR_ZONE, "SDIO Bus shutdown =====>\n");
+
+- if (hw) {
+- struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
+-
+- if (rsi_config_wowlan(adapter, wowlan))
++ if (hw && hw->wiphy && hw->wiphy->wowlan_config) {
++ if (rsi_config_wowlan(adapter, hw->wiphy->wowlan_config))
+ rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n");
+ }
+
+--
+2.39.2
+
--- /dev/null
+From fc60fd141051592abce7258c913ed2285186588a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 May 2023 00:28:59 +0200
+Subject: wifi: rsi: Do not set MMC_PM_KEEP_POWER in shutdown
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit e74f562328b03fbe9cf438f958464dff3a644dfc ]
+
+It makes no sense to set MMC_PM_KEEP_POWER in shutdown. The flag
+indicates to the MMC subsystem to keep the slot powered on during
+suspend, but in shutdown the slot should actually be powered off.
+Drop this call.
+
+Fixes: 063848c3e155 ("rsi: sdio: Add WOWLAN support for S5 shutdown state")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230527222859.273768-1-marex@denx.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/rsi/rsi_91x_sdio.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
+index 6e33a2563fdbd..1911fef3bbad6 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
++++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
+@@ -1479,9 +1479,6 @@ static void rsi_shutdown(struct device *dev)
+ if (sdev->write_fail)
+ rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n");
+
+- if (rsi_set_sdio_pm_caps(adapter))
+- rsi_dbg(INFO_ZONE, "Setting power management caps failed\n");
+-
+ rsi_dbg(INFO_ZONE, "***** RSI module shut down *****\n");
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 5673b0a3afd0527669cb0c6c6905521f2e4be8c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 May 2023 12:39:34 +0200
+Subject: wifi: rtw88: usb: silence log flooding error message
+
+From: Sascha Hauer <s.hauer@pengutronix.de>
+
+[ Upstream commit 1f1784a59caf3eefd127908a1a3cf224017ff9c7 ]
+
+When receiving more rx packets than the kernel can handle the driver
+drops the packets and issues an error message. This is bad for two
+reasons. The logs are flooded with myriads of messages, but then time
+consumed for printing messages in that critical code path brings down
+the device. After some time of excessive rx load the driver responds
+with:
+
+rtw_8822cu 1-1:1.2: failed to get tx report from firmware
+rtw_8822cu 1-1:1.2: firmware failed to report density after scan
+rtw_8822cu 1-1:1.2: firmware failed to report density after scan
+
+The device stops working until being replugged.
+
+Fix this by lowering the priority to debug level and also by
+ratelimiting it.
+
+Fixes: a82dfd33d1237 ("wifi: rtw88: Add common USB chip support")
+Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
+Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230524103934.1019096-1-s.hauer@pengutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
+index 44a5fafb99055..976eafa739a2d 100644
+--- a/drivers/net/wireless/realtek/rtw88/usb.c
++++ b/drivers/net/wireless/realtek/rtw88/usb.c
+@@ -535,7 +535,7 @@ static void rtw_usb_rx_handler(struct work_struct *work)
+ }
+
+ if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) {
+- rtw_err(rtwdev, "failed to get rx_queue, overflow\n");
++ dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n");
+ dev_kfree_skb_any(skb);
+ continue;
+ }
+--
+2.39.2
+
--- /dev/null
+From c345047704f80f30e3112daf8daac3c79075f239 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Apr 2023 18:10:20 +0000
+Subject: wifi: wilc1000: fix for absent RSN capabilities WFA testcase
+
+From: Amisha Patel <amisha.patel@microchip.com>
+
+[ Upstream commit 9ce4bb09123e9754996e358bd808d39f5d112899 ]
+
+Mandatory WFA testcase
+CT_Security_WPA2Personal_STA_RSNEBoundsVerification-AbsentRSNCap,
+performs bounds verfication on Beacon and/or Probe response frames. It
+failed and observed the reason to be absence of cipher suite and AKM
+suite in RSN information. To fix this, enable the RSN flag before extracting RSN
+capabilities.
+
+Fixes: cd21d99e595e ("wifi: wilc1000: validate pairwise and authentication suite offsets")
+Signed-off-by: Amisha Patel <amisha.patel@microchip.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230421181005.4865-1-amisha.patel@microchip.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/microchip/wilc1000/hif.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
+index 5adc69d5bcae3..a28da59384813 100644
+--- a/drivers/net/wireless/microchip/wilc1000/hif.c
++++ b/drivers/net/wireless/microchip/wilc1000/hif.c
+@@ -485,6 +485,9 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+ 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 */
+ if (offset < rsn_ie_len) {
+ /* skip over pairwise suites */
+@@ -494,11 +497,8 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+ /* 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;
++ if (offset + 1 < rsn_ie_len)
+ memcpy(param->rsn_cap, &rsn_ie[offset], 2);
+- }
+ }
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From decdbd8d0818a1eb9c020efd30b0c47f07529689 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 May 2023 10:05:08 +0200
+Subject: wifi: wl3501_cs: Fix an error handling path in wl3501_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 391af06a02e7642039ac5f6c4b2c034ab0992b5d ]
+
+Should wl3501_config() fail, some resources need to be released as already
+done in the remove function.
+
+Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/7cc9c9316489b7d69b36aeb0edd3123538500b41.1684569865.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/wl3501_cs.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
+index 7fb2f95134760..c45c4b7cbbaf1 100644
+--- a/drivers/net/wireless/wl3501_cs.c
++++ b/drivers/net/wireless/wl3501_cs.c
+@@ -1862,6 +1862,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
+ {
+ struct net_device *dev;
+ struct wl3501_card *this;
++ int ret;
+
+ /* The io structure describes IO port mapping */
+ p_dev->resource[0]->end = 16;
+@@ -1873,8 +1874,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
+
+ dev = alloc_etherdev(sizeof(struct wl3501_card));
+ if (!dev)
+- goto out_link;
+-
++ return -ENOMEM;
+
+ dev->netdev_ops = &wl3501_netdev_ops;
+ dev->watchdog_timeo = 5 * HZ;
+@@ -1887,9 +1887,15 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
+ netif_stop_queue(dev);
+ p_dev->priv = dev;
+
+- return wl3501_config(p_dev);
+-out_link:
+- return -ENOMEM;
++ ret = wl3501_config(p_dev);
++ if (ret)
++ goto out_free_etherdev;
++
++ return 0;
++
++out_free_etherdev:
++ free_netdev(dev);
++ return ret;
+ }
+
+ static int wl3501_config(struct pcmcia_device *link)
+--
+2.39.2
+
--- /dev/null
+From 1e1044ae0f5da56d411c852c9376da6f2c7a7e43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jun 2023 21:35:19 +0200
+Subject: x86/efi: Make efi_set_virtual_address_map IBT safe
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 0303c9729afc4094ef53e552b7b8cff7436028d6 ]
+
+Niklāvs reported a boot regression on an Alderlake machine and bisected it
+to commit 9df9d2f0471b ("init: Invoke arch_cpu_finalize_init() earlier").
+
+By moving the invocation of arch_cpu_finalize_init() further down he
+identified that efi_enter_virtual_mode() is the function which causes the
+boot hang.
+
+The main difference of the earlier invocation is that the boot CPU is
+already fully initialized and mitigations and alternatives are applied.
+
+But the only really interesting change turned out to be IBT, which is now
+enabled before efi_enter_virtual_mode(). "ibt=off" on the kernel command
+line cured the problem.
+
+Inspection of the involved calls in efi_enter_virtual_mode() unearthed that
+efi_set_virtual_address_map() is the only place in the kernel which invokes
+an EFI call without the IBT safe wrapper. This went obviously unnoticed so
+far as IBT was enabled later.
+
+Use arch_efi_call_virt() instead of efi_call() to cure that.
+
+Fixes: fe379fa4d199 ("x86/ibt: Disable IBT around firmware")
+Fixes: 9df9d2f0471b ("init: Invoke arch_cpu_finalize_init() earlier")
+Reported-by: Niklāvs Koļesņikovs <pinkflames.linux@gmail.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217602
+Link: https://lore.kernel.org/r/87jzvm12q0.ffs@tglx
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/platform/efi/efi_64.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
+index 232acf418cfbe..77f7ac3668cb4 100644
+--- a/arch/x86/platform/efi/efi_64.c
++++ b/arch/x86/platform/efi/efi_64.c
+@@ -853,9 +853,9 @@ efi_set_virtual_address_map(unsigned long memory_map_size,
+
+ /* Disable interrupts around EFI calls: */
+ local_irq_save(flags);
+- status = efi_call(efi.runtime->set_virtual_address_map,
+- memory_map_size, descriptor_size,
+- descriptor_version, virtual_map);
++ status = arch_efi_call_virt(efi.runtime, set_virtual_address_map,
++ memory_map_size, descriptor_size,
++ descriptor_version, virtual_map);
+ local_irq_restore(flags);
+
+ efi_fpu_end();
+--
+2.39.2
+
--- /dev/null
+From 3dd7ae74a6f5f0e6b5f115c7765f044284da6623 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 12:56:20 +0300
+Subject: x86/mm: Allow guest.enc_status_change_prepare() to fail
+
+From: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+
+[ Upstream commit 3f6819dd192ef4f0c568ec3e9d6d408b3fa1ad3d ]
+
+TDX code is going to provide guest.enc_status_change_prepare() that is
+able to fail. TDX will use the call to convert the GPA range from shared
+to private. This operation can fail.
+
+Add a way to return an error from the callback.
+
+Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Link: https://lore.kernel.org/all/20230606095622.1939-2-kirill.shutemov%40linux.intel.com
+Stable-dep-of: 195edce08b63 ("x86/tdx: Fix race between set_memory_encrypted() and load_unaligned_zeropad()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/x86_init.h | 2 +-
+ arch/x86/kernel/x86_init.c | 2 +-
+ arch/x86/mm/mem_encrypt_amd.c | 4 +++-
+ arch/x86/mm/pat/set_memory.c | 3 ++-
+ 4 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
+index c1c8c581759d6..034e62838b284 100644
+--- a/arch/x86/include/asm/x86_init.h
++++ b/arch/x86/include/asm/x86_init.h
+@@ -150,7 +150,7 @@ struct x86_init_acpi {
+ * @enc_cache_flush_required Returns true if a cache flush is needed before changing page encryption status
+ */
+ struct x86_guest {
+- void (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
++ bool (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
+ bool (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
+ bool (*enc_tlb_flush_required)(bool enc);
+ bool (*enc_cache_flush_required)(void);
+diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
+index 10622cf2b30f4..41e5b4cb898c3 100644
+--- a/arch/x86/kernel/x86_init.c
++++ b/arch/x86/kernel/x86_init.c
+@@ -130,7 +130,7 @@ struct x86_cpuinit_ops x86_cpuinit = {
+
+ static void default_nmi_init(void) { };
+
+-static void enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { }
++static bool enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { return true; }
+ static bool enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { return false; }
+ static bool enc_tlb_flush_required_noop(bool enc) { return false; }
+ static bool enc_cache_flush_required_noop(void) { return false; }
+diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
+index 9c4d8dbcb1296..ff6c0462beee7 100644
+--- a/arch/x86/mm/mem_encrypt_amd.c
++++ b/arch/x86/mm/mem_encrypt_amd.c
+@@ -319,7 +319,7 @@ static void enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
+ #endif
+ }
+
+-static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
++static bool amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
+ {
+ /*
+ * To maintain the security guarantees of SEV-SNP guests, make sure
+@@ -327,6 +327,8 @@ static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool
+ */
+ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP) && !enc)
+ snp_set_memory_shared(vaddr, npages);
++
++ return true;
+ }
+
+ /* Return true unconditionally: return value doesn't matter for the SEV side */
+diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
+index 356758b7d4b47..6a167290a1fd1 100644
+--- a/arch/x86/mm/pat/set_memory.c
++++ b/arch/x86/mm/pat/set_memory.c
+@@ -2151,7 +2151,8 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
+ cpa_flush(&cpa, x86_platform.guest.enc_cache_flush_required());
+
+ /* Notify hypervisor that we are about to set/clr encryption attribute. */
+- x86_platform.guest.enc_status_change_prepare(addr, numpages, enc);
++ if (!x86_platform.guest.enc_status_change_prepare(addr, numpages, enc))
++ return -EIO;
+
+ ret = __change_page_attr_set_clr(&cpa, 1);
+
+--
+2.39.2
+
--- /dev/null
+From 90e09d4719f559be9ffa988d55d13556e0bd8c77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Mar 2023 13:32:59 +0100
+Subject: x86/mm: Fix __swp_entry_to_pte() for Xen PV guests
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit 0f88130e8a6fd185b0aeb5d8e286083735f2585a ]
+
+Normally __swp_entry_to_pte() is never called with a value translating
+to a valid PTE. The only known exception is pte_swap_tests(), resulting
+in a WARN splat in Xen PV guests, as __pte_to_swp_entry() did
+translate the PFN of the valid PTE to a guest local PFN, while
+__swp_entry_to_pte() doesn't do the opposite translation.
+
+Fix that by using __pte() in __swp_entry_to_pte() instead of open
+coding the native variant of it.
+
+For correctness do the similar conversion for __swp_entry_to_pmd().
+
+Fixes: 05289402d717 ("mm/debug_vm_pgtable: add tests validating arch helpers for core MM features")
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/20230306123259.12461-1-jgross@suse.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/pgtable_64.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
+index 7929327abe009..a629b1b9f65a6 100644
+--- a/arch/x86/include/asm/pgtable_64.h
++++ b/arch/x86/include/asm/pgtable_64.h
+@@ -237,8 +237,8 @@ static inline void native_pgd_clear(pgd_t *pgd)
+
+ #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) })
+ #define __pmd_to_swp_entry(pmd) ((swp_entry_t) { pmd_val((pmd)) })
+-#define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val })
+-#define __swp_entry_to_pmd(x) ((pmd_t) { .pmd = (x).val })
++#define __swp_entry_to_pte(x) (__pte((x).val))
++#define __swp_entry_to_pmd(x) (__pmd((x).val))
+
+ extern void cleanup_highmap(void);
+
+--
+2.39.2
+
--- /dev/null
+From 7e8bc20dabf23ac055a16f5d02ac6de793fc7e36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 May 2023 14:09:16 +0200
+Subject: x86/mtrr: Remove physical address size calculation
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit f6b980646b93a8c585b4ed991b8a34e8fc6ef847 ]
+
+The physical address width calculation in mtrr_bp_init() can easily be
+replaced with using the already available value x86_phys_bits from
+struct cpuinfo_x86.
+
+The same information source can be used in mtrr/cleanup.c, removing the
+need to pass that value on to mtrr_cleanup().
+
+In print_mtrr_state() use x86_phys_bits instead of recalculating it
+from size_or_mask.
+
+Move setting of size_or_mask and size_and_mask into a dedicated new
+function in mtrr/generic.c, enabling to make those 2 variables static,
+as they are used in generic.c only now.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Tested-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/20230502120931.20719-2-jgross@suse.com
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Stable-dep-of: a153f254e5cd ("x86/xen: Set MTRR state when running as Xen PV initial domain")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/mtrr/cleanup.c | 16 ++++----
+ arch/x86/kernel/cpu/mtrr/generic.c | 12 +++++-
+ arch/x86/kernel/cpu/mtrr/mtrr.c | 61 ++++--------------------------
+ arch/x86/kernel/cpu/mtrr/mtrr.h | 4 +-
+ 4 files changed, 29 insertions(+), 64 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
+index b5f43049fa5f7..70314093bb9b5 100644
+--- a/arch/x86/kernel/cpu/mtrr/cleanup.c
++++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
+@@ -173,7 +173,7 @@ early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup);
+
+ static void __init
+ set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
+- unsigned char type, unsigned int address_bits)
++ unsigned char type)
+ {
+ u32 base_lo, base_hi, mask_lo, mask_hi;
+ u64 base, mask;
+@@ -183,7 +183,7 @@ set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
+ return;
+ }
+
+- mask = (1ULL << address_bits) - 1;
++ mask = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
+ mask &= ~((((u64)sizek) << 10) - 1);
+
+ base = ((u64)basek) << 10;
+@@ -209,7 +209,7 @@ save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
+ range_state[reg].type = type;
+ }
+
+-static void __init set_var_mtrr_all(unsigned int address_bits)
++static void __init set_var_mtrr_all(void)
+ {
+ unsigned long basek, sizek;
+ unsigned char type;
+@@ -220,7 +220,7 @@ static void __init set_var_mtrr_all(unsigned int address_bits)
+ sizek = range_state[reg].size_pfn << (PAGE_SHIFT - 10);
+ type = range_state[reg].type;
+
+- set_var_mtrr(reg, basek, sizek, type, address_bits);
++ set_var_mtrr(reg, basek, sizek, type);
+ }
+ }
+
+@@ -680,7 +680,7 @@ static int __init mtrr_search_optimal_index(void)
+ return index_good;
+ }
+
+-int __init mtrr_cleanup(unsigned address_bits)
++int __init mtrr_cleanup(void)
+ {
+ unsigned long x_remove_base, x_remove_size;
+ unsigned long base, size, def, dummy;
+@@ -742,7 +742,7 @@ int __init mtrr_cleanup(unsigned address_bits)
+ mtrr_print_out_one_result(i);
+
+ if (!result[i].bad) {
+- set_var_mtrr_all(address_bits);
++ set_var_mtrr_all();
+ pr_debug("New variable MTRRs\n");
+ print_out_mtrr_range_state();
+ return 1;
+@@ -786,7 +786,7 @@ int __init mtrr_cleanup(unsigned address_bits)
+ gran_size = result[i].gran_sizek;
+ gran_size <<= 10;
+ x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
+- set_var_mtrr_all(address_bits);
++ set_var_mtrr_all();
+ pr_debug("New variable MTRRs\n");
+ print_out_mtrr_range_state();
+ return 1;
+@@ -802,7 +802,7 @@ int __init mtrr_cleanup(unsigned address_bits)
+ return 0;
+ }
+ #else
+-int __init mtrr_cleanup(unsigned address_bits)
++int __init mtrr_cleanup(void)
+ {
+ return 0;
+ }
+diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
+index ee09d359e08f0..3922552340b13 100644
+--- a/arch/x86/kernel/cpu/mtrr/generic.c
++++ b/arch/x86/kernel/cpu/mtrr/generic.c
+@@ -38,6 +38,16 @@ u64 mtrr_tom2;
+ struct mtrr_state_type mtrr_state;
+ EXPORT_SYMBOL_GPL(mtrr_state);
+
++static u64 size_or_mask, size_and_mask;
++
++void __init mtrr_set_mask(void)
++{
++ unsigned int phys_addr = boot_cpu_data.x86_phys_bits;
++
++ size_or_mask = ~GENMASK_ULL(phys_addr - PAGE_SHIFT - 1, 0);
++ size_and_mask = ~size_or_mask & GENMASK_ULL(39, 20);
++}
++
+ /*
+ * BIOS is expected to clear MtrrFixDramModEn bit, see for example
+ * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
+@@ -422,7 +432,7 @@ static void __init print_mtrr_state(void)
+ }
+ pr_debug("MTRR variable ranges %sabled:\n",
+ mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED ? "en" : "dis");
+- high_width = (__ffs64(size_or_mask) - (32 - PAGE_SHIFT) + 3) / 4;
++ high_width = (boot_cpu_data.x86_phys_bits - (32 - PAGE_SHIFT) + 3) / 4;
+
+ for (i = 0; i < num_var_ranges; ++i) {
+ if (mtrr_state.var_ranges[i].mask_lo & (1 << 11))
+diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c
+index 783f3210d5827..1bdab16f16bdc 100644
+--- a/arch/x86/kernel/cpu/mtrr/mtrr.c
++++ b/arch/x86/kernel/cpu/mtrr/mtrr.c
+@@ -67,8 +67,6 @@ static bool mtrr_enabled(void)
+ unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
+ static DEFINE_MUTEX(mtrr_mutex);
+
+-u64 size_or_mask, size_and_mask;
+-
+ const struct mtrr_ops *mtrr_if;
+
+ /* Returns non-zero if we have the write-combining memory type */
+@@ -619,77 +617,34 @@ static struct syscore_ops mtrr_syscore_ops = {
+
+ int __initdata changed_by_mtrr_cleanup;
+
+-#define SIZE_OR_MASK_BITS(n) (~((1ULL << ((n) - PAGE_SHIFT)) - 1))
+ /**
+- * mtrr_bp_init - initialize mtrrs on the boot CPU
++ * mtrr_bp_init - initialize MTRRs on the boot CPU
+ *
+ * This needs to be called early; before any of the other CPUs are
+ * initialized (i.e. before smp_init()).
+- *
+ */
+ void __init mtrr_bp_init(void)
+ {
+ const char *why = "(not available)";
+- u32 phys_addr;
+
+- phys_addr = 32;
++ mtrr_set_mask();
+
+- if (boot_cpu_has(X86_FEATURE_MTRR)) {
++ if (cpu_feature_enabled(X86_FEATURE_MTRR)) {
+ mtrr_if = &generic_mtrr_ops;
+- size_or_mask = SIZE_OR_MASK_BITS(36);
+- size_and_mask = 0x00f00000;
+- phys_addr = 36;
+-
+- /*
+- * This is an AMD specific MSR, but we assume(hope?) that
+- * Intel will implement it too when they extend the address
+- * bus of the Xeon.
+- */
+- if (cpuid_eax(0x80000000) >= 0x80000008) {
+- phys_addr = cpuid_eax(0x80000008) & 0xff;
+- /* CPUID workaround for Intel 0F33/0F34 CPU */
+- if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+- boot_cpu_data.x86 == 0xF &&
+- boot_cpu_data.x86_model == 0x3 &&
+- (boot_cpu_data.x86_stepping == 0x3 ||
+- boot_cpu_data.x86_stepping == 0x4))
+- phys_addr = 36;
+-
+- size_or_mask = SIZE_OR_MASK_BITS(phys_addr);
+- size_and_mask = ~size_or_mask & 0xfffff00000ULL;
+- } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
+- boot_cpu_data.x86 == 6) {
+- /*
+- * VIA C* family have Intel style MTRRs,
+- * but don't support PAE
+- */
+- size_or_mask = SIZE_OR_MASK_BITS(32);
+- size_and_mask = 0;
+- phys_addr = 32;
+- }
+ } else {
+ switch (boot_cpu_data.x86_vendor) {
+ case X86_VENDOR_AMD:
+- if (cpu_feature_enabled(X86_FEATURE_K6_MTRR)) {
+- /* Pre-Athlon (K6) AMD CPU MTRRs */
++ /* Pre-Athlon (K6) AMD CPU MTRRs */
++ if (cpu_feature_enabled(X86_FEATURE_K6_MTRR))
+ mtrr_if = &amd_mtrr_ops;
+- size_or_mask = SIZE_OR_MASK_BITS(32);
+- size_and_mask = 0;
+- }
+ break;
+ case X86_VENDOR_CENTAUR:
+- if (cpu_feature_enabled(X86_FEATURE_CENTAUR_MCR)) {
++ if (cpu_feature_enabled(X86_FEATURE_CENTAUR_MCR))
+ mtrr_if = ¢aur_mtrr_ops;
+- size_or_mask = SIZE_OR_MASK_BITS(32);
+- size_and_mask = 0;
+- }
+ break;
+ case X86_VENDOR_CYRIX:
+- if (cpu_feature_enabled(X86_FEATURE_CYRIX_ARR)) {
++ if (cpu_feature_enabled(X86_FEATURE_CYRIX_ARR))
+ mtrr_if = &cyrix_mtrr_ops;
+- size_or_mask = SIZE_OR_MASK_BITS(32);
+- size_and_mask = 0;
+- }
+ break;
+ default:
+ break;
+@@ -703,7 +658,7 @@ void __init mtrr_bp_init(void)
+ /* BIOS may override */
+ if (get_mtrr_state()) {
+ memory_caching_control |= CACHE_MTRR;
+- changed_by_mtrr_cleanup = mtrr_cleanup(phys_addr);
++ changed_by_mtrr_cleanup = mtrr_cleanup();
+ } else {
+ mtrr_if = NULL;
+ why = "by BIOS";
+diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h
+index 02eb5871492d0..a00987e6cc1c1 100644
+--- a/arch/x86/kernel/cpu/mtrr/mtrr.h
++++ b/arch/x86/kernel/cpu/mtrr/mtrr.h
+@@ -51,7 +51,6 @@ void fill_mtrr_var_range(unsigned int index,
+ u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi);
+ bool get_mtrr_state(void);
+
+-extern u64 size_or_mask, size_and_mask;
+ extern const struct mtrr_ops *mtrr_if;
+
+ #define is_cpu(vnd) (mtrr_if && mtrr_if->vendor == X86_VENDOR_##vnd)
+@@ -60,6 +59,7 @@ extern unsigned int num_var_ranges;
+ extern u64 mtrr_tom2;
+ extern struct mtrr_state_type mtrr_state;
+
++void mtrr_set_mask(void);
+ void mtrr_state_warn(void);
+ const char *mtrr_attrib_to_str(int x);
+ void mtrr_wrmsr(unsigned, unsigned, unsigned);
+@@ -70,4 +70,4 @@ extern const struct mtrr_ops cyrix_mtrr_ops;
+ extern const struct mtrr_ops centaur_mtrr_ops;
+
+ extern int changed_by_mtrr_cleanup;
+-extern int mtrr_cleanup(unsigned address_bits);
++extern int mtrr_cleanup(void);
+--
+2.39.2
+
--- /dev/null
+From 7cfa53e7a69f1f27e7c1546a8946a2f2ce7cf64d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 May 2023 14:09:17 +0200
+Subject: x86/mtrr: Replace size_or_mask and size_and_mask with a much easier
+ concept
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit d053b481a5f16dbd4f020c6b3ebdf9173fdef0e2 ]
+
+Replace size_or_mask and size_and_mask with the much easier concept of
+high reserved bits.
+
+While at it, instead of using constants in the MTRR code, use some new
+
+ [ bp:
+ - Drop mtrr_set_mask()
+ - Unbreak long lines
+ - Move struct mtrr_state_type out of the uapi header as it doesn't
+ belong there. It also fixes a HDRTEST breakage "unknown type name ‘bool’"
+ as Reported-by: kernel test robot <lkp@intel.com>
+ - Massage.
+ ]
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/20230502120931.20719-3-jgross@suse.com
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Stable-dep-of: a153f254e5cd ("x86/xen: Set MTRR state when running as Xen PV initial domain")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/mtrr.h | 32 +++++++++++++-
+ arch/x86/include/uapi/asm/mtrr.h | 8 ----
+ arch/x86/kernel/cpu/mtrr/cleanup.c | 2 +-
+ arch/x86/kernel/cpu/mtrr/generic.c | 70 +++++++++++++-----------------
+ arch/x86/kernel/cpu/mtrr/mtrr.c | 4 +-
+ arch/x86/kernel/cpu/mtrr/mtrr.h | 2 +-
+ 6 files changed, 65 insertions(+), 53 deletions(-)
+
+diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
+index f0eeaf6e5f5f7..1421fe811401e 100644
+--- a/arch/x86/include/asm/mtrr.h
++++ b/arch/x86/include/asm/mtrr.h
+@@ -23,8 +23,35 @@
+ #ifndef _ASM_X86_MTRR_H
+ #define _ASM_X86_MTRR_H
+
++#include <linux/bits.h>
+ #include <uapi/asm/mtrr.h>
+
++/* Defines for hardware MTRR registers. */
++#define MTRR_CAP_VCNT GENMASK(7, 0)
++#define MTRR_CAP_FIX BIT_MASK(8)
++#define MTRR_CAP_WC BIT_MASK(10)
++
++#define MTRR_DEF_TYPE_TYPE GENMASK(7, 0)
++#define MTRR_DEF_TYPE_FE BIT_MASK(10)
++#define MTRR_DEF_TYPE_E BIT_MASK(11)
++
++#define MTRR_DEF_TYPE_ENABLE (MTRR_DEF_TYPE_FE | MTRR_DEF_TYPE_E)
++#define MTRR_DEF_TYPE_DISABLE ~(MTRR_DEF_TYPE_TYPE | MTRR_DEF_TYPE_ENABLE)
++
++#define MTRR_PHYSBASE_TYPE GENMASK(7, 0)
++#define MTRR_PHYSBASE_RSVD GENMASK(11, 8)
++
++#define MTRR_PHYSMASK_RSVD GENMASK(10, 0)
++#define MTRR_PHYSMASK_V BIT_MASK(11)
++
++struct mtrr_state_type {
++ struct mtrr_var_range var_ranges[MTRR_MAX_VAR_RANGES];
++ mtrr_type fixed_ranges[MTRR_NUM_FIXED_RANGES];
++ unsigned char enabled;
++ bool have_fixed;
++ mtrr_type def_type;
++};
++
+ /*
+ * The following functions are for use by other drivers that cannot use
+ * arch_phys_wc_add and arch_phys_wc_del.
+@@ -121,7 +148,8 @@ struct mtrr_gentry32 {
+ #endif /* CONFIG_COMPAT */
+
+ /* Bit fields for enabled in struct mtrr_state_type */
+-#define MTRR_STATE_MTRR_FIXED_ENABLED 0x01
+-#define MTRR_STATE_MTRR_ENABLED 0x02
++#define MTRR_STATE_SHIFT 10
++#define MTRR_STATE_MTRR_FIXED_ENABLED (MTRR_DEF_TYPE_FE >> MTRR_STATE_SHIFT)
++#define MTRR_STATE_MTRR_ENABLED (MTRR_DEF_TYPE_E >> MTRR_STATE_SHIFT)
+
+ #endif /* _ASM_X86_MTRR_H */
+diff --git a/arch/x86/include/uapi/asm/mtrr.h b/arch/x86/include/uapi/asm/mtrr.h
+index 376563f2bac1f..ab194c8316259 100644
+--- a/arch/x86/include/uapi/asm/mtrr.h
++++ b/arch/x86/include/uapi/asm/mtrr.h
+@@ -81,14 +81,6 @@ typedef __u8 mtrr_type;
+ #define MTRR_NUM_FIXED_RANGES 88
+ #define MTRR_MAX_VAR_RANGES 256
+
+-struct mtrr_state_type {
+- struct mtrr_var_range var_ranges[MTRR_MAX_VAR_RANGES];
+- mtrr_type fixed_ranges[MTRR_NUM_FIXED_RANGES];
+- unsigned char enabled;
+- unsigned char have_fixed;
+- mtrr_type def_type;
+-};
+-
+ #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
+ #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
+
+diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
+index 70314093bb9b5..ca2d567e729e2 100644
+--- a/arch/x86/kernel/cpu/mtrr/cleanup.c
++++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
+@@ -890,7 +890,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
+ return 0;
+
+ rdmsr(MSR_MTRRdefType, def, dummy);
+- def &= 0xff;
++ def &= MTRR_DEF_TYPE_TYPE;
+ if (def != MTRR_TYPE_UNCACHABLE)
+ return 0;
+
+diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
+index 3922552340b13..08ba558321825 100644
+--- a/arch/x86/kernel/cpu/mtrr/generic.c
++++ b/arch/x86/kernel/cpu/mtrr/generic.c
+@@ -38,15 +38,8 @@ u64 mtrr_tom2;
+ struct mtrr_state_type mtrr_state;
+ EXPORT_SYMBOL_GPL(mtrr_state);
+
+-static u64 size_or_mask, size_and_mask;
+-
+-void __init mtrr_set_mask(void)
+-{
+- unsigned int phys_addr = boot_cpu_data.x86_phys_bits;
+-
+- size_or_mask = ~GENMASK_ULL(phys_addr - PAGE_SHIFT - 1, 0);
+- size_and_mask = ~size_or_mask & GENMASK_ULL(39, 20);
+-}
++/* Reserved bits in the high portion of the MTRRphysBaseN MSR. */
++u32 phys_hi_rsvd;
+
+ /*
+ * BIOS is expected to clear MtrrFixDramModEn bit, see for example
+@@ -79,10 +72,9 @@ static u64 get_mtrr_size(u64 mask)
+ {
+ u64 size;
+
+- mask >>= PAGE_SHIFT;
+- mask |= size_or_mask;
++ mask |= (u64)phys_hi_rsvd << 32;
+ size = -mask;
+- size <<= PAGE_SHIFT;
++
+ return size;
+ }
+
+@@ -181,7 +173,7 @@ static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end,
+ for (i = 0; i < num_var_ranges; ++i) {
+ unsigned short start_state, end_state, inclusive;
+
+- if (!(mtrr_state.var_ranges[i].mask_lo & (1 << 11)))
++ if (!(mtrr_state.var_ranges[i].mask_lo & MTRR_PHYSMASK_V))
+ continue;
+
+ base = (((u64)mtrr_state.var_ranges[i].base_hi) << 32) +
+@@ -233,7 +225,7 @@ static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end,
+ if ((start & mask) != (base & mask))
+ continue;
+
+- curr_match = mtrr_state.var_ranges[i].base_lo & 0xff;
++ curr_match = mtrr_state.var_ranges[i].base_lo & MTRR_PHYSBASE_TYPE;
+ if (prev_match == MTRR_TYPE_INVALID) {
+ prev_match = curr_match;
+ continue;
+@@ -435,7 +427,7 @@ static void __init print_mtrr_state(void)
+ high_width = (boot_cpu_data.x86_phys_bits - (32 - PAGE_SHIFT) + 3) / 4;
+
+ for (i = 0; i < num_var_ranges; ++i) {
+- if (mtrr_state.var_ranges[i].mask_lo & (1 << 11))
++ if (mtrr_state.var_ranges[i].mask_lo & MTRR_PHYSMASK_V)
+ pr_debug(" %u base %0*X%05X000 mask %0*X%05X000 %s\n",
+ i,
+ high_width,
+@@ -444,7 +436,8 @@ static void __init print_mtrr_state(void)
+ high_width,
+ mtrr_state.var_ranges[i].mask_hi,
+ mtrr_state.var_ranges[i].mask_lo >> 12,
+- mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff));
++ mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo &
++ MTRR_PHYSBASE_TYPE));
+ else
+ pr_debug(" %u disabled\n", i);
+ }
+@@ -462,7 +455,7 @@ bool __init get_mtrr_state(void)
+ vrs = mtrr_state.var_ranges;
+
+ rdmsr(MSR_MTRRcap, lo, dummy);
+- mtrr_state.have_fixed = (lo >> 8) & 1;
++ mtrr_state.have_fixed = lo & MTRR_CAP_FIX;
+
+ for (i = 0; i < num_var_ranges; i++)
+ get_mtrr_var_range(i, &vrs[i]);
+@@ -470,8 +463,8 @@ bool __init get_mtrr_state(void)
+ get_fixed_ranges(mtrr_state.fixed_ranges);
+
+ rdmsr(MSR_MTRRdefType, lo, dummy);
+- mtrr_state.def_type = (lo & 0xff);
+- mtrr_state.enabled = (lo & 0xc00) >> 10;
++ mtrr_state.def_type = lo & MTRR_DEF_TYPE_TYPE;
++ mtrr_state.enabled = (lo & MTRR_DEF_TYPE_ENABLE) >> MTRR_STATE_SHIFT;
+
+ if (amd_special_default_mtrr()) {
+ unsigned low, high;
+@@ -584,7 +577,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
+
+ rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
+
+- if ((mask_lo & 0x800) == 0) {
++ if (!(mask_lo & MTRR_PHYSMASK_V)) {
+ /* Invalid (i.e. free) range */
+ *base = 0;
+ *size = 0;
+@@ -595,8 +588,8 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
+ rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi);
+
+ /* Work out the shifted address mask: */
+- tmp = (u64)mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT;
+- mask = size_or_mask | tmp;
++ tmp = (u64)mask_hi << 32 | (mask_lo & PAGE_MASK);
++ mask = (u64)phys_hi_rsvd << 32 | tmp;
+
+ /* Expand tmp with high bits to all 1s: */
+ hi = fls64(tmp);
+@@ -614,9 +607,9 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
+ * This works correctly if size is a power of two, i.e. a
+ * contiguous range:
+ */
+- *size = -mask;
++ *size = -mask >> PAGE_SHIFT;
+ *base = (u64)base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
+- *type = base_lo & 0xff;
++ *type = base_lo & MTRR_PHYSBASE_TYPE;
+
+ out_put_cpu:
+ put_cpu();
+@@ -654,9 +647,8 @@ static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
+ bool changed = false;
+
+ rdmsr(MTRRphysBase_MSR(index), lo, hi);
+- if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
+- || (vr->base_hi & (size_and_mask >> (32 - PAGE_SHIFT))) !=
+- (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) {
++ if ((vr->base_lo & ~MTRR_PHYSBASE_RSVD) != (lo & ~MTRR_PHYSBASE_RSVD)
++ || (vr->base_hi & ~phys_hi_rsvd) != (hi & ~phys_hi_rsvd)) {
+
+ mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
+ changed = true;
+@@ -664,9 +656,8 @@ static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
+
+ rdmsr(MTRRphysMask_MSR(index), lo, hi);
+
+- if ((vr->mask_lo & 0xfffff800UL) != (lo & 0xfffff800UL)
+- || (vr->mask_hi & (size_and_mask >> (32 - PAGE_SHIFT))) !=
+- (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) {
++ if ((vr->mask_lo & ~MTRR_PHYSMASK_RSVD) != (lo & ~MTRR_PHYSMASK_RSVD)
++ || (vr->mask_hi & ~phys_hi_rsvd) != (hi & ~phys_hi_rsvd)) {
+ mtrr_wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
+ changed = true;
+ }
+@@ -701,11 +692,12 @@ static unsigned long set_mtrr_state(void)
+ * Set_mtrr_restore restores the old value of MTRRdefType,
+ * so to set it we fiddle with the saved value:
+ */
+- if ((deftype_lo & 0xff) != mtrr_state.def_type
+- || ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) {
++ if ((deftype_lo & MTRR_DEF_TYPE_TYPE) != mtrr_state.def_type ||
++ ((deftype_lo & MTRR_DEF_TYPE_ENABLE) >> MTRR_STATE_SHIFT) != mtrr_state.enabled) {
+
+- deftype_lo = (deftype_lo & ~0xcff) | mtrr_state.def_type |
+- (mtrr_state.enabled << 10);
++ deftype_lo = (deftype_lo & MTRR_DEF_TYPE_DISABLE) |
++ mtrr_state.def_type |
++ (mtrr_state.enabled << MTRR_STATE_SHIFT);
+ change_mask |= MTRR_CHANGE_MASK_DEFTYPE;
+ }
+
+@@ -718,7 +710,7 @@ void mtrr_disable(void)
+ rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
+
+ /* Disable MTRRs, and set the default type to uncached */
+- mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi);
++ mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & MTRR_DEF_TYPE_DISABLE, deftype_hi);
+ }
+
+ void mtrr_enable(void)
+@@ -772,9 +764,9 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base,
+ memset(vr, 0, sizeof(struct mtrr_var_range));
+ } else {
+ vr->base_lo = base << PAGE_SHIFT | type;
+- vr->base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT);
+- vr->mask_lo = -size << PAGE_SHIFT | 0x800;
+- vr->mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT);
++ vr->base_hi = (base >> (32 - PAGE_SHIFT)) & ~phys_hi_rsvd;
++ vr->mask_lo = -size << PAGE_SHIFT | MTRR_PHYSMASK_V;
++ vr->mask_hi = (-size >> (32 - PAGE_SHIFT)) & ~phys_hi_rsvd;
+
+ mtrr_wrmsr(MTRRphysBase_MSR(reg), vr->base_lo, vr->base_hi);
+ mtrr_wrmsr(MTRRphysMask_MSR(reg), vr->mask_lo, vr->mask_hi);
+@@ -827,7 +819,7 @@ static int generic_have_wrcomb(void)
+ {
+ unsigned long config, dummy;
+ rdmsr(MSR_MTRRcap, config, dummy);
+- return config & (1 << 10);
++ return config & MTRR_CAP_WC;
+ }
+
+ int positive_have_wrcomb(void)
+diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c
+index 1bdab16f16bdc..1067f128bded1 100644
+--- a/arch/x86/kernel/cpu/mtrr/mtrr.c
++++ b/arch/x86/kernel/cpu/mtrr/mtrr.c
+@@ -115,7 +115,7 @@ static void __init set_num_var_ranges(bool use_generic)
+ else if (is_cpu(CYRIX) || is_cpu(CENTAUR))
+ config = 8;
+
+- num_var_ranges = config & 0xff;
++ num_var_ranges = config & MTRR_CAP_VCNT;
+ }
+
+ static void __init init_table(void)
+@@ -627,7 +627,7 @@ void __init mtrr_bp_init(void)
+ {
+ const char *why = "(not available)";
+
+- mtrr_set_mask();
++ phys_hi_rsvd = GENMASK(31, boot_cpu_data.x86_phys_bits - 32);
+
+ if (cpu_feature_enabled(X86_FEATURE_MTRR)) {
+ mtrr_if = &generic_mtrr_ops;
+diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h
+index a00987e6cc1c1..59e8fb26bf9dd 100644
+--- a/arch/x86/kernel/cpu/mtrr/mtrr.h
++++ b/arch/x86/kernel/cpu/mtrr/mtrr.h
+@@ -58,8 +58,8 @@ extern const struct mtrr_ops *mtrr_if;
+ extern unsigned int num_var_ranges;
+ extern u64 mtrr_tom2;
+ extern struct mtrr_state_type mtrr_state;
++extern u32 phys_hi_rsvd;
+
+-void mtrr_set_mask(void);
+ void mtrr_state_warn(void);
+ const char *mtrr_attrib_to_str(int x);
+ void mtrr_wrmsr(unsigned, unsigned, unsigned);
+--
+2.39.2
+
--- /dev/null
+From f40a44e5e209a5c4a8559f0fec0a663a64ae89eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 May 2023 14:09:18 +0200
+Subject: x86/mtrr: Support setting MTRR state for software defined MTRRs
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit 29055dc74287467bd7a053d60b4afe753832960d ]
+
+When running virtualized, MTRR access can be reduced (e.g. in Xen PV
+guests or when running as a SEV-SNP guest under Hyper-V). Typically, the
+hypervisor will not advertize the MTRR feature in CPUID data, resulting
+in no MTRR memory type information being available for the kernel.
+
+This has turned out to result in problems (Link tags below):
+
+- Hyper-V SEV-SNP guests using uncached mappings where they shouldn't
+- Xen PV dom0 mapping memory as WB which should be UC- instead
+
+Solve those problems by allowing an MTRR static state override,
+overwriting the empty state used today. In case such a state has been
+set, don't call get_mtrr_state() in mtrr_bp_init().
+
+The set state will only be used by mtrr_type_lookup(), as in all other
+cases mtrr_enabled() is being checked, which will return false. Accept
+the overwrite call only for selected cases when running as a guest.
+Disable X86_FEATURE_MTRR in order to avoid any MTRR modifications by
+just refusing them.
+
+ [ bp: Massage. ]
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Tested-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/all/4fe9541e-4d4c-2b2a-f8c8-2d34a7284930@nerdbynature.de/
+Link: https://lore.kernel.org/lkml/BYAPR21MB16883ABC186566BD4D2A1451D7FE9@BYAPR21MB1688.namprd21.prod.outlook.com
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Stable-dep-of: a153f254e5cd ("x86/xen: Set MTRR state when running as Xen PV initial domain")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/mtrr.h | 8 ++++
+ arch/x86/kernel/cpu/mtrr/generic.c | 60 +++++++++++++++++++++++++++++-
+ arch/x86/kernel/cpu/mtrr/mtrr.c | 14 ++++++-
+ arch/x86/kernel/setup.c | 2 +
+ 4 files changed, 82 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
+index 1421fe811401e..1bae790a553a5 100644
+--- a/arch/x86/include/asm/mtrr.h
++++ b/arch/x86/include/asm/mtrr.h
+@@ -58,6 +58,8 @@ struct mtrr_state_type {
+ */
+ # ifdef CONFIG_MTRR
+ void mtrr_bp_init(void);
++void mtrr_overwrite_state(struct mtrr_var_range *var, unsigned int num_var,
++ mtrr_type def_type);
+ extern u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform);
+ extern void mtrr_save_fixed_ranges(void *);
+ extern void mtrr_save_state(void);
+@@ -75,6 +77,12 @@ void mtrr_disable(void);
+ void mtrr_enable(void);
+ void mtrr_generic_set_state(void);
+ # else
++static inline void mtrr_overwrite_state(struct mtrr_var_range *var,
++ unsigned int num_var,
++ mtrr_type def_type)
++{
++}
++
+ static inline u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform)
+ {
+ /*
+diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
+index 08ba558321825..e81d832475a1f 100644
+--- a/arch/x86/kernel/cpu/mtrr/generic.c
++++ b/arch/x86/kernel/cpu/mtrr/generic.c
+@@ -8,10 +8,12 @@
+ #include <linux/init.h>
+ #include <linux/io.h>
+ #include <linux/mm.h>
+-
++#include <linux/cc_platform.h>
+ #include <asm/processor-flags.h>
+ #include <asm/cacheinfo.h>
+ #include <asm/cpufeature.h>
++#include <asm/hypervisor.h>
++#include <asm/mshyperv.h>
+ #include <asm/tlbflush.h>
+ #include <asm/mtrr.h>
+ #include <asm/msr.h>
+@@ -242,6 +244,62 @@ static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end,
+ return mtrr_state.def_type;
+ }
+
++/**
++ * mtrr_overwrite_state - set static MTRR state
++ *
++ * Used to set MTRR state via different means (e.g. with data obtained from
++ * a hypervisor).
++ * Is allowed only for special cases when running virtualized. Must be called
++ * from the x86_init.hyper.init_platform() hook. It can be called only once.
++ * The MTRR state can't be changed afterwards. To ensure that, X86_FEATURE_MTRR
++ * is cleared.
++ */
++void mtrr_overwrite_state(struct mtrr_var_range *var, unsigned int num_var,
++ mtrr_type def_type)
++{
++ unsigned int i;
++
++ /* Only allowed to be called once before mtrr_bp_init(). */
++ if (WARN_ON_ONCE(mtrr_state_set))
++ return;
++
++ /* Only allowed when running virtualized. */
++ if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
++ return;
++
++ /*
++ * Only allowed for special virtualization cases:
++ * - when running as Hyper-V, SEV-SNP guest using vTOM
++ * - when running as Xen PV guest
++ * - when running as SEV-SNP or TDX guest to avoid unnecessary
++ * VMM communication/Virtualization exceptions (#VC, #VE)
++ */
++ if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP) &&
++ !hv_is_isolation_supported() &&
++ !cpu_feature_enabled(X86_FEATURE_XENPV) &&
++ !cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
++ return;
++
++ /* Disable MTRR in order to disable MTRR modifications. */
++ setup_clear_cpu_cap(X86_FEATURE_MTRR);
++
++ if (var) {
++ if (num_var > MTRR_MAX_VAR_RANGES) {
++ pr_warn("Trying to overwrite MTRR state with %u variable entries\n",
++ num_var);
++ num_var = MTRR_MAX_VAR_RANGES;
++ }
++ for (i = 0; i < num_var; i++)
++ mtrr_state.var_ranges[i] = var[i];
++ num_var_ranges = num_var;
++ }
++
++ mtrr_state.def_type = def_type;
++ mtrr_state.enabled |= MTRR_STATE_MTRR_ENABLED;
++
++ mtrr_state_set = 1;
++}
++
+ /**
+ * mtrr_type_lookup - look up memory type in MTRR
+ *
+diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c
+index 1067f128bded1..be35a0b09604d 100644
+--- a/arch/x86/kernel/cpu/mtrr/mtrr.c
++++ b/arch/x86/kernel/cpu/mtrr/mtrr.c
+@@ -625,11 +625,23 @@ int __initdata changed_by_mtrr_cleanup;
+ */
+ void __init mtrr_bp_init(void)
+ {
++ bool generic_mtrrs = cpu_feature_enabled(X86_FEATURE_MTRR);
+ const char *why = "(not available)";
+
+ phys_hi_rsvd = GENMASK(31, boot_cpu_data.x86_phys_bits - 32);
+
+- if (cpu_feature_enabled(X86_FEATURE_MTRR)) {
++ if (!generic_mtrrs && mtrr_state.enabled) {
++ /*
++ * Software overwrite of MTRR state, only for generic case.
++ * Note that X86_FEATURE_MTRR has been reset in this case.
++ */
++ init_table();
++ pr_info("MTRRs set to read-only\n");
++
++ return;
++ }
++
++ if (generic_mtrrs) {
+ mtrr_if = &generic_mtrr_ops;
+ } else {
+ switch (boot_cpu_data.x86_vendor) {
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index 16babff771bdf..0cccfeb67c3ad 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -1037,6 +1037,8 @@ void __init setup_arch(char **cmdline_p)
+ /*
+ * VMware detection requires dmi to be available, so this
+ * needs to be done after dmi_setup(), for the boot CPU.
++ * For some guest types (Xen PV, SEV-SNP, TDX) it is required to be
++ * called before cache_bp_init() for setting up MTRR state.
+ */
+ init_hypervisor_platform();
+
+--
+2.39.2
+
--- /dev/null
+From 05d129210f519ccd435702946fcffbf4721fd246 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 14:04:48 +0800
+Subject: x86/resctrl: Only show tasks' pid in current pid namespace
+
+From: Shawn Wang <shawnwang@linux.alibaba.com>
+
+[ Upstream commit 2997d94b5dd0e8b10076f5e0b6f18410c73e28bd ]
+
+When writing a task id to the "tasks" file in an rdtgroup,
+rdtgroup_tasks_write() treats the pid as a number in the current pid
+namespace. But when reading the "tasks" file, rdtgroup_tasks_show() shows
+the list of global pids from the init namespace, which is confusing and
+incorrect.
+
+To be more robust, let the "tasks" file only show pids in the current pid
+namespace.
+
+Fixes: e02737d5b826 ("x86/intel_rdt: Add tasks files")
+Signed-off-by: Shawn Wang <shawnwang@linux.alibaba.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Acked-by: Reinette Chatre <reinette.chatre@intel.com>
+Acked-by: Fenghua Yu <fenghua.yu@intel.com>
+Tested-by: Reinette Chatre <reinette.chatre@intel.com>
+Link: https://lore.kernel.org/all/20230116071246.97717-1-shawnwang@linux.alibaba.com/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/resctrl/rdtgroup.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+index 6ad33f355861f..61cdd9b1bb6d8 100644
+--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
++++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+@@ -726,11 +726,15 @@ static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of,
+ static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s)
+ {
+ struct task_struct *p, *t;
++ pid_t pid;
+
+ rcu_read_lock();
+ for_each_process_thread(p, t) {
+- if (is_closid_match(t, r) || is_rmid_match(t, r))
+- seq_printf(s, "%d\n", t->pid);
++ if (is_closid_match(t, r) || is_rmid_match(t, r)) {
++ pid = task_pid_vnr(t);
++ if (pid)
++ seq_printf(s, "%d\n", pid);
++ }
+ }
+ rcu_read_unlock();
+ }
+--
+2.39.2
+
--- /dev/null
+From 64fb37bee211e67d01cb9e48c64e03e0efbcb640 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 09:51:22 -0500
+Subject: x86/sev: Fix calculation of end address based on number of pages
+
+From: Tom Lendacky <thomas.lendacky@amd.com>
+
+[ Upstream commit 5dee19b6b2b194216919b99a1f5af2949a754016 ]
+
+When calculating an end address based on an unsigned int number of pages,
+any value greater than or equal to 0x100000 that is shift PAGE_SHIFT bits
+results in a 0 value, resulting in an invalid end address. Change the
+number of pages variable in various routines from an unsigned int to an
+unsigned long to calculate the end address correctly.
+
+Fixes: 5e5ccff60a29 ("x86/sev: Add helper for validating pages in early enc attribute changes")
+Fixes: dc3f3d2474b8 ("x86/mm: Validate memory when changing the C-bit")
+Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/6a6e4eea0e1414402bac747744984fa4e9c01bb6.1686063086.git.thomas.lendacky@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/sev.h | 16 ++++++++--------
+ arch/x86/kernel/sev.c | 14 +++++++-------
+ 2 files changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
+index ebc271bb6d8ed..a0a58c4122ec3 100644
+--- a/arch/x86/include/asm/sev.h
++++ b/arch/x86/include/asm/sev.h
+@@ -187,12 +187,12 @@ static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate)
+ }
+ void setup_ghcb(void);
+ void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
+- unsigned int npages);
++ unsigned long npages);
+ void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr,
+- unsigned int npages);
++ unsigned long npages);
+ void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op);
+-void snp_set_memory_shared(unsigned long vaddr, unsigned int npages);
+-void snp_set_memory_private(unsigned long vaddr, unsigned int npages);
++void snp_set_memory_shared(unsigned long vaddr, unsigned long npages);
++void snp_set_memory_private(unsigned long vaddr, unsigned long npages);
+ void snp_set_wakeup_secondary_cpu(void);
+ bool snp_init(struct boot_params *bp);
+ void __init __noreturn snp_abort(void);
+@@ -207,12 +207,12 @@ static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate)
+ static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs) { return 0; }
+ static inline void setup_ghcb(void) { }
+ static inline void __init
+-early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, unsigned int npages) { }
++early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, unsigned long npages) { }
+ static inline void __init
+-early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned int npages) { }
++early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned long npages) { }
+ static inline void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op) { }
+-static inline void snp_set_memory_shared(unsigned long vaddr, unsigned int npages) { }
+-static inline void snp_set_memory_private(unsigned long vaddr, unsigned int npages) { }
++static inline void snp_set_memory_shared(unsigned long vaddr, unsigned long npages) { }
++static inline void snp_set_memory_private(unsigned long vaddr, unsigned long npages) { }
+ static inline void snp_set_wakeup_secondary_cpu(void) { }
+ static inline bool snp_init(struct boot_params *bp) { return false; }
+ static inline void snp_abort(void) { }
+diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
+index 3f664ab277c49..45ef3926381f8 100644
+--- a/arch/x86/kernel/sev.c
++++ b/arch/x86/kernel/sev.c
+@@ -643,7 +643,7 @@ static u64 __init get_jump_table_addr(void)
+ return ret;
+ }
+
+-static void pvalidate_pages(unsigned long vaddr, unsigned int npages, bool validate)
++static void pvalidate_pages(unsigned long vaddr, unsigned long npages, bool validate)
+ {
+ unsigned long vaddr_end;
+ int rc;
+@@ -660,7 +660,7 @@ static void pvalidate_pages(unsigned long vaddr, unsigned int npages, bool valid
+ }
+ }
+
+-static void __init early_set_pages_state(unsigned long paddr, unsigned int npages, enum psc_op op)
++static void __init early_set_pages_state(unsigned long paddr, unsigned long npages, enum psc_op op)
+ {
+ unsigned long paddr_end;
+ u64 val;
+@@ -699,7 +699,7 @@ static void __init early_set_pages_state(unsigned long paddr, unsigned int npage
+ }
+
+ void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
+- unsigned int npages)
++ unsigned long npages)
+ {
+ /*
+ * This can be invoked in early boot while running identity mapped, so
+@@ -721,7 +721,7 @@ void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long padd
+ }
+
+ void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr,
+- unsigned int npages)
++ unsigned long npages)
+ {
+ /*
+ * This can be invoked in early boot while running identity mapped, so
+@@ -877,7 +877,7 @@ static void __set_pages_state(struct snp_psc_desc *data, unsigned long vaddr,
+ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);
+ }
+
+-static void set_pages_state(unsigned long vaddr, unsigned int npages, int op)
++static void set_pages_state(unsigned long vaddr, unsigned long npages, int op)
+ {
+ unsigned long vaddr_end, next_vaddr;
+ struct snp_psc_desc *desc;
+@@ -902,7 +902,7 @@ static void set_pages_state(unsigned long vaddr, unsigned int npages, int op)
+ kfree(desc);
+ }
+
+-void snp_set_memory_shared(unsigned long vaddr, unsigned int npages)
++void snp_set_memory_shared(unsigned long vaddr, unsigned long npages)
+ {
+ if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
+ return;
+@@ -912,7 +912,7 @@ void snp_set_memory_shared(unsigned long vaddr, unsigned int npages)
+ set_pages_state(vaddr, npages, SNP_PAGE_STATE_SHARED);
+ }
+
+-void snp_set_memory_private(unsigned long vaddr, unsigned int npages)
++void snp_set_memory_private(unsigned long vaddr, unsigned long npages)
+ {
+ if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
+ return;
+--
+2.39.2
+
--- /dev/null
+From 15b710b9f67eac60ce3958f6601170182aa42432 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 12:56:21 +0300
+Subject: x86/tdx: Fix race between set_memory_encrypted() and
+ load_unaligned_zeropad()
+
+From: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+
+[ Upstream commit 195edce08b63d293377f615f4f7f086715d2d212 ]
+
+tl;dr: There is a race in the TDX private<=>shared conversion code
+ which could kill the TDX guest. Fix it by changing conversion
+ ordering to eliminate the window.
+
+TDX hardware maintains metadata to track which pages are private and
+shared. Additionally, TDX guests use the guest x86 page tables to
+specify whether a given mapping is intended to be private or shared.
+Bad things happen when the intent and metadata do not match.
+
+So there are two thing in play:
+ 1. "the page" -- the physical TDX page metadata
+ 2. "the mapping" -- the guest-controlled x86 page table intent
+
+For instance, an unrecoverable exit to VMM occurs if a guest touches a
+private mapping that points to a shared physical page.
+
+In summary:
+ * Private mapping => Private Page == OK (obviously)
+ * Shared mapping => Shared Page == OK (obviously)
+ * Private mapping => Shared Page == BIG BOOM!
+ * Shared mapping => Private Page == OK-ish
+ (It will read generate a recoverable #VE via handle_mmio())
+
+Enter load_unaligned_zeropad(). It can touch memory that is adjacent but
+otherwise unrelated to the memory it needs to touch. It will cause one
+of those unrecoverable exits (aka. BIG BOOM) if it blunders into a
+shared mapping pointing to a private page.
+
+This is a problem when __set_memory_enc_pgtable() converts pages from
+shared to private. It first changes the mapping and second modifies
+the TDX page metadata. It's moving from:
+
+ * Shared mapping => Shared Page == OK
+to:
+ * Private mapping => Shared Page == BIG BOOM!
+
+This means that there is a window with a shared mapping pointing to a
+private page where load_unaligned_zeropad() can strike.
+
+Add a TDX handler for guest.enc_status_change_prepare(). This converts
+the page from shared to private *before* the page becomes private. This
+ensures that there is never a private mapping to a shared page.
+
+Leave a guest.enc_status_change_finish() in place but only use it for
+private=>shared conversions. This will delay updating the TDX metadata
+marking the page private until *after* the mapping matches the metadata.
+This also ensures that there is never a private mapping to a shared page.
+
+[ dhansen: rewrite changelog ]
+
+Fixes: 7dbde7631629 ("x86/mm/cpa: Add support for TDX shared memory")
+Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Link: https://lore.kernel.org/all/20230606095622.1939-3-kirill.shutemov%40linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/coco/tdx/tdx.c | 51 ++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 48 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
+index 055300e08fb38..3d191ec036fb7 100644
+--- a/arch/x86/coco/tdx/tdx.c
++++ b/arch/x86/coco/tdx/tdx.c
+@@ -840,6 +840,30 @@ static bool tdx_enc_status_changed(unsigned long vaddr, int numpages, bool enc)
+ return true;
+ }
+
++static bool tdx_enc_status_change_prepare(unsigned long vaddr, int numpages,
++ bool enc)
++{
++ /*
++ * Only handle shared->private conversion here.
++ * See the comment in tdx_early_init().
++ */
++ if (enc)
++ return tdx_enc_status_changed(vaddr, numpages, enc);
++ return true;
++}
++
++static bool tdx_enc_status_change_finish(unsigned long vaddr, int numpages,
++ bool enc)
++{
++ /*
++ * Only handle private->shared conversion here.
++ * See the comment in tdx_early_init().
++ */
++ if (!enc)
++ return tdx_enc_status_changed(vaddr, numpages, enc);
++ return true;
++}
++
+ void __init tdx_early_init(void)
+ {
+ u64 cc_mask;
+@@ -867,9 +891,30 @@ void __init tdx_early_init(void)
+ */
+ physical_mask &= cc_mask - 1;
+
+- x86_platform.guest.enc_cache_flush_required = tdx_cache_flush_required;
+- x86_platform.guest.enc_tlb_flush_required = tdx_tlb_flush_required;
+- x86_platform.guest.enc_status_change_finish = tdx_enc_status_changed;
++ /*
++ * The kernel mapping should match the TDX metadata for the page.
++ * load_unaligned_zeropad() can touch memory *adjacent* to that which is
++ * owned by the caller and can catch even _momentary_ mismatches. Bad
++ * things happen on mismatch:
++ *
++ * - Private mapping => Shared Page == Guest shutdown
++ * - Shared mapping => Private Page == Recoverable #VE
++ *
++ * guest.enc_status_change_prepare() converts the page from
++ * shared=>private before the mapping becomes private.
++ *
++ * guest.enc_status_change_finish() converts the page from
++ * private=>shared after the mapping becomes private.
++ *
++ * In both cases there is a temporary shared mapping to a private page,
++ * which can result in a #VE. But, there is never a private mapping to
++ * a shared page.
++ */
++ x86_platform.guest.enc_status_change_prepare = tdx_enc_status_change_prepare;
++ x86_platform.guest.enc_status_change_finish = tdx_enc_status_change_finish;
++
++ x86_platform.guest.enc_cache_flush_required = tdx_cache_flush_required;
++ x86_platform.guest.enc_tlb_flush_required = tdx_tlb_flush_required;
+
+ pr_info("Guest detected\n");
+ }
+--
+2.39.2
+
--- /dev/null
+From 22aa133bd32a604b2b06af017af76dcd9d30d96e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 May 2023 14:09:20 +0200
+Subject: x86/xen: Set MTRR state when running as Xen PV initial domain
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit a153f254e5cdf8fa3a1df90a6ffed3063fede154 ]
+
+When running as Xen PV initial domain (aka dom0), MTRRs are disabled
+by the hypervisor, but the system should nevertheless use correct
+cache memory types. This has always kind of worked, as disabled MTRRs
+resulted in disabled PAT, too, so that the kernel avoided code paths
+resulting in inconsistencies. This bypassed all of the sanity checks
+the kernel is doing with enabled MTRRs in order to avoid memory
+mappings with conflicting memory types.
+
+This has been changed recently, leading to PAT being accepted to be
+enabled, while MTRRs stayed disabled. The result is that
+mtrr_type_lookup() no longer is accepting all memory type requests,
+but started to return WB even if UC- was requested. This led to
+driver failures during initialization of some devices.
+
+In reality MTRRs are still in effect, but they are under complete
+control of the Xen hypervisor. It is possible, however, to retrieve
+the MTRR settings from the hypervisor.
+
+In order to fix those problems, overwrite the MTRR state via
+mtrr_overwrite_state() with the MTRR data from the hypervisor, if the
+system is running as a Xen dom0.
+
+Fixes: 72cbc8f04fe2 ("x86/PAT: Have pat_enabled() properly reflect state when running on Xen")
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Tested-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/20230502120931.20719-6-jgross@suse.com
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/xen/enlighten_pv.c | 52 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 52 insertions(+)
+
+diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
+index 093b78c8bbec0..8732b85d56505 100644
+--- a/arch/x86/xen/enlighten_pv.c
++++ b/arch/x86/xen/enlighten_pv.c
+@@ -68,6 +68,7 @@
+ #include <asm/reboot.h>
+ #include <asm/hypervisor.h>
+ #include <asm/mach_traps.h>
++#include <asm/mtrr.h>
+ #include <asm/mwait.h>
+ #include <asm/pci_x86.h>
+ #include <asm/cpu.h>
+@@ -119,6 +120,54 @@ static int __init parse_xen_msr_safe(char *str)
+ }
+ early_param("xen_msr_safe", parse_xen_msr_safe);
+
++/* Get MTRR settings from Xen and put them into mtrr_state. */
++static void __init xen_set_mtrr_data(void)
++{
++#ifdef CONFIG_MTRR
++ struct xen_platform_op op = {
++ .cmd = XENPF_read_memtype,
++ .interface_version = XENPF_INTERFACE_VERSION,
++ };
++ unsigned int reg;
++ unsigned long mask;
++ uint32_t eax, width;
++ static struct mtrr_var_range var[MTRR_MAX_VAR_RANGES] __initdata;
++
++ /* Get physical address width (only 64-bit cpus supported). */
++ width = 36;
++ eax = cpuid_eax(0x80000000);
++ if ((eax >> 16) == 0x8000 && eax >= 0x80000008) {
++ eax = cpuid_eax(0x80000008);
++ width = eax & 0xff;
++ }
++
++ for (reg = 0; reg < MTRR_MAX_VAR_RANGES; reg++) {
++ op.u.read_memtype.reg = reg;
++ if (HYPERVISOR_platform_op(&op))
++ break;
++
++ /*
++ * Only called in dom0, which has all RAM PFNs mapped at
++ * RAM MFNs, and all PCI space etc. is identity mapped.
++ * This means we can treat MFN == PFN regarding MTRR settings.
++ */
++ var[reg].base_lo = op.u.read_memtype.type;
++ var[reg].base_lo |= op.u.read_memtype.mfn << PAGE_SHIFT;
++ var[reg].base_hi = op.u.read_memtype.mfn >> (32 - PAGE_SHIFT);
++ mask = ~((op.u.read_memtype.nr_mfns << PAGE_SHIFT) - 1);
++ mask &= (1UL << width) - 1;
++ if (mask)
++ mask |= MTRR_PHYSMASK_V;
++ var[reg].mask_lo = mask;
++ var[reg].mask_hi = mask >> 32;
++ }
++
++ /* Only overwrite MTRR state if any MTRR could be got from Xen. */
++ if (reg)
++ mtrr_overwrite_state(var, reg, MTRR_TYPE_UNCACHABLE);
++#endif
++}
++
+ static void __init xen_pv_init_platform(void)
+ {
+ /* PV guests can't operate virtio devices without grants. */
+@@ -135,6 +184,9 @@ static void __init xen_pv_init_platform(void)
+
+ /* pvclock is in shared info area */
+ xen_init_time_ops();
++
++ if (xen_initial_domain())
++ xen_set_mtrr_data();
+ }
+
+ static void __init xen_pv_guest_late_init(void)
+--
+2.39.2
+