--- /dev/null
+From 0af6a1b9044476e5ad9c34d741e5741709f84afd 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 cd66632bf1c37..e18572eae5e01 100644
+--- a/sound/pci/ac97/ac97_codec.c
++++ b/sound/pci/ac97/ac97_codec.c
+@@ -2007,8 +2007,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 1ed239d912921f435b657c5d88bd0cc7922ec0a2 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 c705ce11c436f..8445bb7ae06ab 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -2229,14 +2229,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;
+
+@@ -2295,14 +2295,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 7314034f30c496f14f37bf02080bc0cfd2b1702f 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 fc3a16cdbee65e0e36cb30850783dad860098922 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 e513d8a467760..c0ed172893787 100644
+--- a/arch/arm/probes/kprobes/core.c
++++ b/arch/arm/probes/kprobes/core.c
+@@ -231,7 +231,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 c78180172120f..e20304f1d8bc9 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 19a5b2add41e1..805116c2ec27c 100644
+--- a/arch/arm/probes/kprobes/test-core.h
++++ b/arch/arm/probes/kprobes/test-core.h
+@@ -453,3 +453,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 baf7c9520a86c610580f05f4cae54be25411b863 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 9fdad20c40d17..4e9bb10f37d0f 100644
+--- a/arch/arm/boot/dts/bcm5301x.dtsi
++++ b/arch/arm/boot/dts/bcm5301x.dtsi
+@@ -532,7 +532,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 fd40889163228b90e7bfca9c062a8318660eadf2 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 577a4dc604d93..edf9910100b02 100644
+--- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
++++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
+@@ -212,7 +212,7 @@ port@5 {
+
+ fixed-link {
+ speed = <1000>;
+- duplex-full;
++ full-duplex;
+ };
+ };
+ };
+--
+2.39.2
+
--- /dev/null
+From d0fe8327a81ceb5ee6aa2aad320725b3ead8933c 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 e3e315614609204c57a5787c1db753b9080191b2 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 63cafd220dba1..358f5477deef6 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 9bda67cb6f5f0f5b9bae89dd2488bee6b473f966 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 08533116a39ce..0d045add81658 100644
+--- a/arch/arm/boot/dts/meson8.dtsi
++++ b/arch/arm/boot/dts/meson8.dtsi
+@@ -611,13 +611,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 9404dffef384060d37931f035a204d95f5bfcd54 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 f6eb7c803174e..af2454c9f77a4 100644
+--- a/arch/arm/boot/dts/meson8b.dtsi
++++ b/arch/arm/boot/dts/meson8b.dtsi
+@@ -599,13 +599,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 b8857474a15c897b535a459cb4f9530894cbb2d9 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 fd0cd10cb0931..2c391065135e3 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
+@@ -120,10 +120,13 @@ lcd_panel_in: endpoint {
+
+ 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 b05d681909193bd51074e065d153f90a003504ad 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 47df8ac67cf1a..75869d6a1ab24 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
+@@ -406,7 +406,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 c3dd4ab3693fcf8c7dff8540cf49ad57f2804bfe 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-som.dtsi | 6 ------
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+index 723b39bb2129c..c43cf62736a6f 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+@@ -232,6 +232,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-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
+index 5af32140e128b..7dba02e9ba6da 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
+@@ -167,12 +167,6 @@ watchdog {
+ status = "disabled";
+ };
+ };
+-
+- eeprom@53 {
+- compatible = "atmel,24c02";
+- reg = <0x53>;
+- pagesize = <16>;
+- };
+ };
+
+ &iwdg2 {
+--
+2.39.2
+
--- /dev/null
+From 53501329971e3103e2dde5d1429b1a075499c011 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 c43cf62736a6f..d8547307a9505 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+@@ -88,7 +88,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 7aae886b3f612ffa04fca5a31b5d7f5d3f6824db 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 6e3d57b85f098052588fbf9c7ad47e8aef55d20d 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 1a947d6626d6818c1d38c4f92628b2d8e42d66e7 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 3cb01c39c3c80..8dd679fbeed1c 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 62ce48d1057d4ae0796fc65ad7208fe9743be84b 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 f6ddf17ada81b..861b356a982b7 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 4fb0c9a2f753870d97e5e56ba840b4737abd159d 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 c32e4a3833f23..5b79e4a373311 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -1006,7 +1006,7 @@ dsi_phy0: dsi-phy@1a98300 {
+ };
+ };
+
+- camss: camss@1b00000 {
++ camss: camss@1b0ac00 {
+ compatible = "qcom,msm8916-camss";
+ reg = <0x01b0ac00 0x200>,
+ <0x01b00030 0x4>,
+--
+2.39.2
+
--- /dev/null
+From 33b79243b2edf485e2f82baf817115544d98d28f 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 aeb5762566e91..caaf7102f5798 100644
+--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
+@@ -489,7 +489,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 d0821629c9f64b66aa49daaa893f10aa9e457e0c 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 159cdd03e7c01..73f7490911c92 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -956,7 +956,7 @@ ufsphy_lane: lanes@627400 {
+ };
+ };
+
+- camss: camss@a00000 {
++ camss: camss@a34000 {
+ compatible = "qcom,msm8996-camss";
+ reg = <0x00a34000 0x1000>,
+ <0x00a00030 0x4>,
+--
+2.39.2
+
--- /dev/null
+From 13e3bed1a94f30724d4c5d95df0ccedd229604cd 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 05e64bfad0235..24d0a1337ae1c 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -270,7 +270,7 @@ hscif0_pins: hscif0 {
+ };
+
+ scif1_pins: scif1 {
+- groups = "scif1_data_b", "scif1_ctrl";
++ groups = "scif1_data_b";
+ function = "scif1";
+ };
+
+@@ -330,7 +330,6 @@ rsnd_for_pcm3168a_capture: endpoint {
+ &scif1 {
+ pinctrl-0 = <&scif1_pins>;
+ pinctrl-names = "default";
+- uart-has-rtscts;
+
+ status = "okay";
+ };
+--
+2.39.2
+
--- /dev/null
+From 7e38e22db56bffebe882e21234734c1281a78505 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 909ab6661aef5..4ec5e955c33c2 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
+@@ -19,25 +19,25 @@ chosen {
+ &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 655481753870665c78cce54b03c30f0105e93f37 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 423d9ce2df266..03ad34a275da2 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 c0fee8503ffb0dbaec8bdf6ee059ced74d68ad7f 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 bc3d46617a113..423d9ce2df266 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 3eb6dfc1692123ab3d624af63151fa201b2ad317 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 cbdc0a2c09c54..77d8234c7ac49 100644
+--- a/sound/soc/fsl/imx-audmix.c
++++ b/sound/soc/fsl/imx-audmix.c
+@@ -230,6 +230,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);
+
+@@ -238,6 +240,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];
+@@ -268,6 +272,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];
+@@ -295,6 +301,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 bf9fbf24f51f4d96ce8ee9987e7ffcf8c6b293c7 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 105ad23dff063..7ba7c4e4e4c93 100644
+--- a/block/blk-iocost.c
++++ b/block/blk-iocost.c
+@@ -2426,6 +2426,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;
+@@ -2444,11 +2445,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;
+ }
+
+@@ -2469,7 +2470,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 d82326d769a6b7e0c3a9867d90c73f1600134169 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jan 2021 08:34:59 -0800
+Subject: bpf: Remove extra lock_sock for TCP_ZEROCOPY_RECEIVE
+
+From: Stanislav Fomichev <sdf@google.com>
+
+[ Upstream commit 9cacf81f8161111db25f98e78a7a0e32ae142b3f ]
+
+Add custom implementation of getsockopt hook for TCP_ZEROCOPY_RECEIVE.
+We skip generic hooks for TCP_ZEROCOPY_RECEIVE and have a custom
+call in do_tcp_getsockopt using the on-stack data. This removes
+3% overhead for locking/unlocking the socket.
+
+Without this patch:
+ 3.38% 0.07% tcp_mmap [kernel.kallsyms] [k] __cgroup_bpf_run_filter_getsockopt
+ |
+ --3.30%--__cgroup_bpf_run_filter_getsockopt
+ |
+ --0.81%--__kmalloc
+
+With the patch applied:
+ 0.52% 0.12% tcp_mmap [kernel.kallsyms] [k] __cgroup_bpf_run_filter_getsockopt_kern
+
+Note, exporting uapi/tcp.h requires removing netinet/tcp.h
+from test_progs.h because those headers have confliciting
+definitions.
+
+Signed-off-by: Stanislav Fomichev <sdf@google.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Martin KaFai Lau <kafai@fb.com>
+Link: https://lore.kernel.org/bpf/20210115163501.805133-2-sdf@google.com
+Stable-dep-of: 2598619e012c ("sctp: add bpf_bypass_getsockopt proto callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bpf-cgroup.h | 27 +-
+ include/linux/indirect_call_wrapper.h | 6 +
+ include/net/sock.h | 2 +
+ include/net/tcp.h | 1 +
+ kernel/bpf/cgroup.c | 46 +++
+ net/ipv4/tcp.c | 14 +
+ net/ipv4/tcp_ipv4.c | 1 +
+ net/ipv6/tcp_ipv6.c | 1 +
+ net/socket.c | 3 +
+ tools/include/uapi/linux/tcp.h | 357 ++++++++++++++++++
+ .../selftests/bpf/prog_tests/bpf_tcp_ca.c | 1 +
+ .../selftests/bpf/prog_tests/cls_redirect.c | 1 +
+ .../selftests/bpf/prog_tests/sockmap_basic.c | 1 +
+ .../selftests/bpf/prog_tests/sockopt_sk.c | 28 ++
+ .../testing/selftests/bpf/progs/sockopt_sk.c | 23 +-
+ tools/testing/selftests/bpf/test_progs.h | 1 -
+ 16 files changed, 506 insertions(+), 7 deletions(-)
+ create mode 100644 tools/include/uapi/linux/tcp.h
+
+diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
+index 91b9669785418..53702b83ce5f1 100644
+--- a/include/linux/bpf-cgroup.h
++++ b/include/linux/bpf-cgroup.h
+@@ -158,6 +158,10 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
+ int __user *optlen, int max_optlen,
+ int retval);
+
++int __cgroup_bpf_run_filter_getsockopt_kern(struct sock *sk, int level,
++ int optname, void *optval,
++ int *optlen, int retval);
++
+ static inline enum bpf_cgroup_storage_type cgroup_storage_type(
+ struct bpf_map *map)
+ {
+@@ -404,10 +408,23 @@ int bpf_percpu_cgroup_storage_update(struct bpf_map *map, void *key,
+ ({ \
+ int __ret = retval; \
+ if (cgroup_bpf_enabled) \
+- __ret = __cgroup_bpf_run_filter_getsockopt(sock, level, \
+- optname, optval, \
+- optlen, max_optlen, \
+- retval); \
++ if (!(sock)->sk_prot->bpf_bypass_getsockopt || \
++ !INDIRECT_CALL_INET_1((sock)->sk_prot->bpf_bypass_getsockopt, \
++ tcp_bpf_bypass_getsockopt, \
++ level, optname)) \
++ __ret = __cgroup_bpf_run_filter_getsockopt( \
++ sock, level, optname, optval, optlen, \
++ max_optlen, retval); \
++ __ret; \
++})
++
++#define BPF_CGROUP_RUN_PROG_GETSOCKOPT_KERN(sock, level, optname, optval, \
++ optlen, retval) \
++({ \
++ int __ret = retval; \
++ if (cgroup_bpf_enabled) \
++ __ret = __cgroup_bpf_run_filter_getsockopt_kern( \
++ sock, level, optname, optval, optlen, retval); \
+ __ret; \
+ })
+
+@@ -493,6 +510,8 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,
+ #define BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen) ({ 0; })
+ #define BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock, level, optname, optval, \
+ optlen, max_optlen, retval) ({ retval; })
++#define BPF_CGROUP_RUN_PROG_GETSOCKOPT_KERN(sock, level, optname, optval, \
++ optlen, retval) ({ retval; })
+ #define BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock, level, optname, optval, optlen, \
+ kernel_optval) ({ 0; })
+
+diff --git a/include/linux/indirect_call_wrapper.h b/include/linux/indirect_call_wrapper.h
+index 54c02c84906ab..cfcfef37b2f1a 100644
+--- a/include/linux/indirect_call_wrapper.h
++++ b/include/linux/indirect_call_wrapper.h
+@@ -60,4 +60,10 @@
+ #define INDIRECT_CALL_INET(f, f2, f1, ...) f(__VA_ARGS__)
+ #endif
+
++#if IS_ENABLED(CONFIG_INET)
++#define INDIRECT_CALL_INET_1(f, f1, ...) INDIRECT_CALL_1(f, f1, __VA_ARGS__)
++#else
++#define INDIRECT_CALL_INET_1(f, f1, ...) f(__VA_ARGS__)
++#endif
++
+ #endif
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 51b499d745499..03e7f7581559d 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1207,6 +1207,8 @@ struct proto {
+
+ int (*backlog_rcv) (struct sock *sk,
+ struct sk_buff *skb);
++ bool (*bpf_bypass_getsockopt)(int level,
++ int optname);
+
+ void (*release_cb)(struct sock *sk);
+
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index d213b86a48227..e231101e5001b 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -389,6 +389,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock,
+ struct poll_table_struct *wait);
+ int tcp_getsockopt(struct sock *sk, int level, int optname,
+ char __user *optval, int __user *optlen);
++bool tcp_bpf_bypass_getsockopt(int level, int optname);
+ int tcp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
+ unsigned int optlen);
+ void tcp_set_keepalive(struct sock *sk, int val);
+diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
+index d3593a520bb72..85927c2aa3433 100644
+--- a/kernel/bpf/cgroup.c
++++ b/kernel/bpf/cgroup.c
+@@ -1546,6 +1546,52 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
+ sockopt_free_buf(&ctx);
+ return ret;
+ }
++
++int __cgroup_bpf_run_filter_getsockopt_kern(struct sock *sk, int level,
++ int optname, void *optval,
++ int *optlen, int retval)
++{
++ struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
++ struct bpf_sockopt_kern ctx = {
++ .sk = sk,
++ .level = level,
++ .optname = optname,
++ .retval = retval,
++ .optlen = *optlen,
++ .optval = optval,
++ .optval_end = optval + *optlen,
++ };
++ int ret;
++
++ /* Note that __cgroup_bpf_run_filter_getsockopt doesn't copy
++ * user data back into BPF buffer when reval != 0. This is
++ * done as an optimization to avoid extra copy, assuming
++ * kernel won't populate the data in case of an error.
++ * Here we always pass the data and memset() should
++ * be called if that data shouldn't be "exported".
++ */
++
++ ret = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[BPF_CGROUP_GETSOCKOPT],
++ &ctx, BPF_PROG_RUN);
++ if (!ret)
++ return -EPERM;
++
++ if (ctx.optlen > *optlen)
++ return -EFAULT;
++
++ /* BPF programs only allowed to set retval to 0, not some
++ * arbitrary value.
++ */
++ if (ctx.retval != 0 && ctx.retval != retval)
++ return -EFAULT;
++
++ /* BPF programs can shrink the buffer, export the modifications.
++ */
++ if (ctx.optlen != 0)
++ *optlen = ctx.optlen;
++
++ return ctx.retval;
++}
+ #endif
+
+ static ssize_t sysctl_cpy_dir(const struct ctl_dir *dir, char **bufp,
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 82abbf1929851..cc42ceadc1127 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3970,6 +3970,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
+ return -EFAULT;
+ lock_sock(sk);
+ err = tcp_zerocopy_receive(sk, &zc);
++ err = BPF_CGROUP_RUN_PROG_GETSOCKOPT_KERN(sk, level, optname,
++ &zc, &len, err);
+ release_sock(sk);
+ if (len >= offsetofend(struct tcp_zerocopy_receive, err))
+ goto zerocopy_rcv_sk_err;
+@@ -4004,6 +4006,18 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
+ return 0;
+ }
+
++bool tcp_bpf_bypass_getsockopt(int level, int optname)
++{
++ /* TCP do_tcp_getsockopt has optimized getsockopt implementation
++ * to avoid extra socket lock for TCP_ZEROCOPY_RECEIVE.
++ */
++ if (level == SOL_TCP && optname == TCP_ZEROCOPY_RECEIVE)
++ return true;
++
++ return false;
++}
++EXPORT_SYMBOL(tcp_bpf_bypass_getsockopt);
++
+ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
+ int __user *optlen)
+ {
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index 270b20e0907c2..d62d5d7764ade 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -2805,6 +2805,7 @@ struct proto tcp_prot = {
+ .shutdown = tcp_shutdown,
+ .setsockopt = tcp_setsockopt,
+ .getsockopt = tcp_getsockopt,
++ .bpf_bypass_getsockopt = tcp_bpf_bypass_getsockopt,
+ .keepalive = tcp_set_keepalive,
+ .recvmsg = tcp_recvmsg,
+ .sendmsg = tcp_sendmsg,
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index fe29bc66aeac7..5392aebd48f1e 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -2135,6 +2135,7 @@ struct proto tcpv6_prot = {
+ .shutdown = tcp_shutdown,
+ .setsockopt = tcp_setsockopt,
+ .getsockopt = tcp_getsockopt,
++ .bpf_bypass_getsockopt = tcp_bpf_bypass_getsockopt,
+ .keepalive = tcp_set_keepalive,
+ .recvmsg = tcp_recvmsg,
+ .sendmsg = tcp_sendmsg,
+diff --git a/net/socket.c b/net/socket.c
+index 84223419da862..f2172b756c0f7 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -2137,6 +2137,9 @@ SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
+ return __sys_setsockopt(fd, level, optname, optval, optlen);
+ }
+
++INDIRECT_CALLABLE_DECLARE(bool tcp_bpf_bypass_getsockopt(int level,
++ int optname));
++
+ /*
+ * Get a socket option. Because we don't know the option lengths we have
+ * to pass a user mode parameter for the protocols to sort out.
+diff --git a/tools/include/uapi/linux/tcp.h b/tools/include/uapi/linux/tcp.h
+new file mode 100644
+index 0000000000000..13ceeb395eb8f
+--- /dev/null
++++ b/tools/include/uapi/linux/tcp.h
+@@ -0,0 +1,357 @@
++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
++/*
++ * INET An implementation of the TCP/IP protocol suite for the LINUX
++ * operating system. INET is implemented using the BSD Socket
++ * interface as the means of communication with the user level.
++ *
++ * Definitions for the TCP protocol.
++ *
++ * Version: @(#)tcp.h 1.0.2 04/28/93
++ *
++ * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#ifndef _UAPI_LINUX_TCP_H
++#define _UAPI_LINUX_TCP_H
++
++#include <linux/types.h>
++#include <asm/byteorder.h>
++#include <linux/socket.h>
++
++struct tcphdr {
++ __be16 source;
++ __be16 dest;
++ __be32 seq;
++ __be32 ack_seq;
++#if defined(__LITTLE_ENDIAN_BITFIELD)
++ __u16 res1:4,
++ doff:4,
++ fin:1,
++ syn:1,
++ rst:1,
++ psh:1,
++ ack:1,
++ urg:1,
++ ece:1,
++ cwr:1;
++#elif defined(__BIG_ENDIAN_BITFIELD)
++ __u16 doff:4,
++ res1:4,
++ cwr:1,
++ ece:1,
++ urg:1,
++ ack:1,
++ psh:1,
++ rst:1,
++ syn:1,
++ fin:1;
++#else
++#error "Adjust your <asm/byteorder.h> defines"
++#endif
++ __be16 window;
++ __sum16 check;
++ __be16 urg_ptr;
++};
++
++/*
++ * The union cast uses a gcc extension to avoid aliasing problems
++ * (union is compatible to any of its members)
++ * This means this part of the code is -fstrict-aliasing safe now.
++ */
++union tcp_word_hdr {
++ struct tcphdr hdr;
++ __be32 words[5];
++};
++
++#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3])
++
++enum {
++ TCP_FLAG_CWR = __constant_cpu_to_be32(0x00800000),
++ TCP_FLAG_ECE = __constant_cpu_to_be32(0x00400000),
++ TCP_FLAG_URG = __constant_cpu_to_be32(0x00200000),
++ TCP_FLAG_ACK = __constant_cpu_to_be32(0x00100000),
++ TCP_FLAG_PSH = __constant_cpu_to_be32(0x00080000),
++ TCP_FLAG_RST = __constant_cpu_to_be32(0x00040000),
++ TCP_FLAG_SYN = __constant_cpu_to_be32(0x00020000),
++ TCP_FLAG_FIN = __constant_cpu_to_be32(0x00010000),
++ TCP_RESERVED_BITS = __constant_cpu_to_be32(0x0F000000),
++ TCP_DATA_OFFSET = __constant_cpu_to_be32(0xF0000000)
++};
++
++/*
++ * TCP general constants
++ */
++#define TCP_MSS_DEFAULT 536U /* IPv4 (RFC1122, RFC2581) */
++#define TCP_MSS_DESIRED 1220U /* IPv6 (tunneled), EDNS0 (RFC3226) */
++
++/* TCP socket options */
++#define TCP_NODELAY 1 /* Turn off Nagle's algorithm. */
++#define TCP_MAXSEG 2 /* Limit MSS */
++#define TCP_CORK 3 /* Never send partially complete segments */
++#define TCP_KEEPIDLE 4 /* Start keeplives after this period */
++#define TCP_KEEPINTVL 5 /* Interval between keepalives */
++#define TCP_KEEPCNT 6 /* Number of keepalives before death */
++#define TCP_SYNCNT 7 /* Number of SYN retransmits */
++#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */
++#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */
++#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */
++#define TCP_INFO 11 /* Information about this connection. */
++#define TCP_QUICKACK 12 /* Block/reenable quick acks */
++#define TCP_CONGESTION 13 /* Congestion control algorithm */
++#define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */
++#define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/
++#define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */
++#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */
++#define TCP_REPAIR 19 /* TCP sock is under repair right now */
++#define TCP_REPAIR_QUEUE 20
++#define TCP_QUEUE_SEQ 21
++#define TCP_REPAIR_OPTIONS 22
++#define TCP_FASTOPEN 23 /* Enable FastOpen on listeners */
++#define TCP_TIMESTAMP 24
++#define TCP_NOTSENT_LOWAT 25 /* limit number of unsent bytes in write queue */
++#define TCP_CC_INFO 26 /* Get Congestion Control (optional) info */
++#define TCP_SAVE_SYN 27 /* Record SYN headers for new connections */
++#define TCP_SAVED_SYN 28 /* Get SYN headers recorded for connection */
++#define TCP_REPAIR_WINDOW 29 /* Get/set window parameters */
++#define TCP_FASTOPEN_CONNECT 30 /* Attempt FastOpen with connect */
++#define TCP_ULP 31 /* Attach a ULP to a TCP connection */
++#define TCP_MD5SIG_EXT 32 /* TCP MD5 Signature with extensions */
++#define TCP_FASTOPEN_KEY 33 /* Set the key for Fast Open (cookie) */
++#define TCP_FASTOPEN_NO_COOKIE 34 /* Enable TFO without a TFO cookie */
++#define TCP_ZEROCOPY_RECEIVE 35
++#define TCP_INQ 36 /* Notify bytes available to read as a cmsg on read */
++
++#define TCP_CM_INQ TCP_INQ
++
++#define TCP_TX_DELAY 37 /* delay outgoing packets by XX usec */
++
++
++#define TCP_REPAIR_ON 1
++#define TCP_REPAIR_OFF 0
++#define TCP_REPAIR_OFF_NO_WP -1 /* Turn off without window probes */
++
++struct tcp_repair_opt {
++ __u32 opt_code;
++ __u32 opt_val;
++};
++
++struct tcp_repair_window {
++ __u32 snd_wl1;
++ __u32 snd_wnd;
++ __u32 max_window;
++
++ __u32 rcv_wnd;
++ __u32 rcv_wup;
++};
++
++enum {
++ TCP_NO_QUEUE,
++ TCP_RECV_QUEUE,
++ TCP_SEND_QUEUE,
++ TCP_QUEUES_NR,
++};
++
++/* why fastopen failed from client perspective */
++enum tcp_fastopen_client_fail {
++ TFO_STATUS_UNSPEC, /* catch-all */
++ TFO_COOKIE_UNAVAILABLE, /* if not in TFO_CLIENT_NO_COOKIE mode */
++ TFO_DATA_NOT_ACKED, /* SYN-ACK did not ack SYN data */
++ TFO_SYN_RETRANSMITTED, /* SYN-ACK did not ack SYN data after timeout */
++};
++
++/* for TCP_INFO socket option */
++#define TCPI_OPT_TIMESTAMPS 1
++#define TCPI_OPT_SACK 2
++#define TCPI_OPT_WSCALE 4
++#define TCPI_OPT_ECN 8 /* ECN was negociated at TCP session init */
++#define TCPI_OPT_ECN_SEEN 16 /* we received at least one packet with ECT */
++#define TCPI_OPT_SYN_DATA 32 /* SYN-ACK acked data in SYN sent or rcvd */
++
++/*
++ * Sender's congestion state indicating normal or abnormal situations
++ * in the last round of packets sent. The state is driven by the ACK
++ * information and timer events.
++ */
++enum tcp_ca_state {
++ /*
++ * Nothing bad has been observed recently.
++ * No apparent reordering, packet loss, or ECN marks.
++ */
++ TCP_CA_Open = 0,
++#define TCPF_CA_Open (1<<TCP_CA_Open)
++ /*
++ * The sender enters disordered state when it has received DUPACKs or
++ * SACKs in the last round of packets sent. This could be due to packet
++ * loss or reordering but needs further information to confirm packets
++ * have been lost.
++ */
++ TCP_CA_Disorder = 1,
++#define TCPF_CA_Disorder (1<<TCP_CA_Disorder)
++ /*
++ * The sender enters Congestion Window Reduction (CWR) state when it
++ * has received ACKs with ECN-ECE marks, or has experienced congestion
++ * or packet discard on the sender host (e.g. qdisc).
++ */
++ TCP_CA_CWR = 2,
++#define TCPF_CA_CWR (1<<TCP_CA_CWR)
++ /*
++ * The sender is in fast recovery and retransmitting lost packets,
++ * typically triggered by ACK events.
++ */
++ TCP_CA_Recovery = 3,
++#define TCPF_CA_Recovery (1<<TCP_CA_Recovery)
++ /*
++ * The sender is in loss recovery triggered by retransmission timeout.
++ */
++ TCP_CA_Loss = 4
++#define TCPF_CA_Loss (1<<TCP_CA_Loss)
++};
++
++struct tcp_info {
++ __u8 tcpi_state;
++ __u8 tcpi_ca_state;
++ __u8 tcpi_retransmits;
++ __u8 tcpi_probes;
++ __u8 tcpi_backoff;
++ __u8 tcpi_options;
++ __u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
++ __u8 tcpi_delivery_rate_app_limited:1, tcpi_fastopen_client_fail:2;
++
++ __u32 tcpi_rto;
++ __u32 tcpi_ato;
++ __u32 tcpi_snd_mss;
++ __u32 tcpi_rcv_mss;
++
++ __u32 tcpi_unacked;
++ __u32 tcpi_sacked;
++ __u32 tcpi_lost;
++ __u32 tcpi_retrans;
++ __u32 tcpi_fackets;
++
++ /* Times. */
++ __u32 tcpi_last_data_sent;
++ __u32 tcpi_last_ack_sent; /* Not remembered, sorry. */
++ __u32 tcpi_last_data_recv;
++ __u32 tcpi_last_ack_recv;
++
++ /* Metrics. */
++ __u32 tcpi_pmtu;
++ __u32 tcpi_rcv_ssthresh;
++ __u32 tcpi_rtt;
++ __u32 tcpi_rttvar;
++ __u32 tcpi_snd_ssthresh;
++ __u32 tcpi_snd_cwnd;
++ __u32 tcpi_advmss;
++ __u32 tcpi_reordering;
++
++ __u32 tcpi_rcv_rtt;
++ __u32 tcpi_rcv_space;
++
++ __u32 tcpi_total_retrans;
++
++ __u64 tcpi_pacing_rate;
++ __u64 tcpi_max_pacing_rate;
++ __u64 tcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */
++ __u64 tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */
++ __u32 tcpi_segs_out; /* RFC4898 tcpEStatsPerfSegsOut */
++ __u32 tcpi_segs_in; /* RFC4898 tcpEStatsPerfSegsIn */
++
++ __u32 tcpi_notsent_bytes;
++ __u32 tcpi_min_rtt;
++ __u32 tcpi_data_segs_in; /* RFC4898 tcpEStatsDataSegsIn */
++ __u32 tcpi_data_segs_out; /* RFC4898 tcpEStatsDataSegsOut */
++
++ __u64 tcpi_delivery_rate;
++
++ __u64 tcpi_busy_time; /* Time (usec) busy sending data */
++ __u64 tcpi_rwnd_limited; /* Time (usec) limited by receive window */
++ __u64 tcpi_sndbuf_limited; /* Time (usec) limited by send buffer */
++
++ __u32 tcpi_delivered;
++ __u32 tcpi_delivered_ce;
++
++ __u64 tcpi_bytes_sent; /* RFC4898 tcpEStatsPerfHCDataOctetsOut */
++ __u64 tcpi_bytes_retrans; /* RFC4898 tcpEStatsPerfOctetsRetrans */
++ __u32 tcpi_dsack_dups; /* RFC4898 tcpEStatsStackDSACKDups */
++ __u32 tcpi_reord_seen; /* reordering events seen */
++
++ __u32 tcpi_rcv_ooopack; /* Out-of-order packets received */
++
++ __u32 tcpi_snd_wnd; /* peer's advertised receive window after
++ * scaling (bytes)
++ */
++};
++
++/* netlink attributes types for SCM_TIMESTAMPING_OPT_STATS */
++enum {
++ TCP_NLA_PAD,
++ TCP_NLA_BUSY, /* Time (usec) busy sending data */
++ TCP_NLA_RWND_LIMITED, /* Time (usec) limited by receive window */
++ TCP_NLA_SNDBUF_LIMITED, /* Time (usec) limited by send buffer */
++ TCP_NLA_DATA_SEGS_OUT, /* Data pkts sent including retransmission */
++ TCP_NLA_TOTAL_RETRANS, /* Data pkts retransmitted */
++ TCP_NLA_PACING_RATE, /* Pacing rate in bytes per second */
++ TCP_NLA_DELIVERY_RATE, /* Delivery rate in bytes per second */
++ TCP_NLA_SND_CWND, /* Sending congestion window */
++ TCP_NLA_REORDERING, /* Reordering metric */
++ TCP_NLA_MIN_RTT, /* minimum RTT */
++ TCP_NLA_RECUR_RETRANS, /* Recurring retransmits for the current pkt */
++ TCP_NLA_DELIVERY_RATE_APP_LMT, /* delivery rate application limited ? */
++ TCP_NLA_SNDQ_SIZE, /* Data (bytes) pending in send queue */
++ TCP_NLA_CA_STATE, /* ca_state of socket */
++ TCP_NLA_SND_SSTHRESH, /* Slow start size threshold */
++ TCP_NLA_DELIVERED, /* Data pkts delivered incl. out-of-order */
++ TCP_NLA_DELIVERED_CE, /* Like above but only ones w/ CE marks */
++ TCP_NLA_BYTES_SENT, /* Data bytes sent including retransmission */
++ TCP_NLA_BYTES_RETRANS, /* Data bytes retransmitted */
++ TCP_NLA_DSACK_DUPS, /* DSACK blocks received */
++ TCP_NLA_REORD_SEEN, /* reordering events seen */
++ TCP_NLA_SRTT, /* smoothed RTT in usecs */
++ TCP_NLA_TIMEOUT_REHASH, /* Timeout-triggered rehash attempts */
++ TCP_NLA_BYTES_NOTSENT, /* Bytes in write queue not yet sent */
++ TCP_NLA_EDT, /* Earliest departure time (CLOCK_MONOTONIC) */
++};
++
++/* for TCP_MD5SIG socket option */
++#define TCP_MD5SIG_MAXKEYLEN 80
++
++/* tcp_md5sig extension flags for TCP_MD5SIG_EXT */
++#define TCP_MD5SIG_FLAG_PREFIX 0x1 /* address prefix length */
++#define TCP_MD5SIG_FLAG_IFINDEX 0x2 /* ifindex set */
++
++struct tcp_md5sig {
++ struct __kernel_sockaddr_storage tcpm_addr; /* address associated */
++ __u8 tcpm_flags; /* extension flags */
++ __u8 tcpm_prefixlen; /* address prefix */
++ __u16 tcpm_keylen; /* key length */
++ int tcpm_ifindex; /* device index for scope */
++ __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */
++};
++
++/* INET_DIAG_MD5SIG */
++struct tcp_diag_md5sig {
++ __u8 tcpm_family;
++ __u8 tcpm_prefixlen;
++ __u16 tcpm_keylen;
++ __be32 tcpm_addr[4];
++ __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN];
++};
++
++/* setsockopt(fd, IPPROTO_TCP, TCP_ZEROCOPY_RECEIVE, ...) */
++
++#define TCP_RECEIVE_ZEROCOPY_FLAG_TLB_CLEAN_HINT 0x1
++struct tcp_zerocopy_receive {
++ __u64 address; /* in: address of mapping */
++ __u32 length; /* in/out: number of bytes to map/mapped */
++ __u32 recv_skip_hint; /* out: amount of bytes to skip */
++ __u32 inq; /* out: amount of bytes in read queue */
++ __s32 err; /* out: socket error */
++ __u64 copybuf_address; /* in: copybuf address (small reads) */
++ __s32 copybuf_len; /* in/out: copybuf bytes avail/used or error */
++ __u32 flags; /* in: flags */
++};
++#endif /* _UAPI_LINUX_TCP_H */
+diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
+index 9a8f47fc0b91e..37c5494a0381b 100644
+--- a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
++++ b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
+@@ -2,6 +2,7 @@
+ /* Copyright (c) 2019 Facebook */
+
+ #include <linux/err.h>
++#include <netinet/tcp.h>
+ #include <test_progs.h>
+ #include "bpf_dctcp.skel.h"
+ #include "bpf_cubic.skel.h"
+diff --git a/tools/testing/selftests/bpf/prog_tests/cls_redirect.c b/tools/testing/selftests/bpf/prog_tests/cls_redirect.c
+index 9781d85cb2239..e075d03ab630a 100644
+--- a/tools/testing/selftests/bpf/prog_tests/cls_redirect.c
++++ b/tools/testing/selftests/bpf/prog_tests/cls_redirect.c
+@@ -7,6 +7,7 @@
+ #include <string.h>
+
+ #include <linux/pkt_cls.h>
++#include <netinet/tcp.h>
+
+ #include <test_progs.h>
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
+index 85f73261fab0a..b8b48cac2ac3d 100644
+--- a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
++++ b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0
+ // Copyright (c) 2020 Cloudflare
+ #include <error.h>
++#include <netinet/tcp.h>
+
+ #include "test_progs.h"
+ #include "test_skmsg_load_helpers.skel.h"
+diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
+index b25c9c45c1484..d5b44b135c00d 100644
+--- a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
++++ b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
+@@ -2,6 +2,12 @@
+ #include <test_progs.h>
+ #include "cgroup_helpers.h"
+
++#include <linux/tcp.h>
++
++#ifndef SOL_TCP
++#define SOL_TCP IPPROTO_TCP
++#endif
++
+ #define SOL_CUSTOM 0xdeadbeef
+
+ static int getsetsockopt(void)
+@@ -11,6 +17,7 @@ static int getsetsockopt(void)
+ char u8[4];
+ __u32 u32;
+ char cc[16]; /* TCP_CA_NAME_MAX */
++ struct tcp_zerocopy_receive zc;
+ } buf = {};
+ socklen_t optlen;
+ char *big_buf = NULL;
+@@ -154,6 +161,27 @@ static int getsetsockopt(void)
+ goto err;
+ }
+
++ /* TCP_ZEROCOPY_RECEIVE triggers */
++ memset(&buf, 0, sizeof(buf));
++ optlen = sizeof(buf.zc);
++ err = getsockopt(fd, SOL_TCP, TCP_ZEROCOPY_RECEIVE, &buf, &optlen);
++ if (err) {
++ log_err("Unexpected getsockopt(TCP_ZEROCOPY_RECEIVE) err=%d errno=%d",
++ err, errno);
++ goto err;
++ }
++
++ memset(&buf, 0, sizeof(buf));
++ buf.zc.address = 12345; /* rejected by BPF */
++ optlen = sizeof(buf.zc);
++ errno = 0;
++ err = getsockopt(fd, SOL_TCP, TCP_ZEROCOPY_RECEIVE, &buf, &optlen);
++ if (errno != EPERM) {
++ log_err("Unexpected getsockopt(TCP_ZEROCOPY_RECEIVE) err=%d errno=%d",
++ err, errno);
++ goto err;
++ }
++
+ free(big_buf);
+ close(fd);
+ return 0;
+diff --git a/tools/testing/selftests/bpf/progs/sockopt_sk.c b/tools/testing/selftests/bpf/progs/sockopt_sk.c
+index 712df7b49cb1a..d3597f81e6e94 100644
+--- a/tools/testing/selftests/bpf/progs/sockopt_sk.c
++++ b/tools/testing/selftests/bpf/progs/sockopt_sk.c
+@@ -1,8 +1,8 @@
+ // SPDX-License-Identifier: GPL-2.0
+ #include <string.h>
+-#include <netinet/in.h>
+-#include <netinet/tcp.h>
++#include <linux/tcp.h>
+ #include <linux/bpf.h>
++#include <netinet/in.h>
+ #include <bpf/bpf_helpers.h>
+
+ char _license[] SEC("license") = "GPL";
+@@ -12,6 +12,10 @@ __u32 _version SEC("version") = 1;
+ #define PAGE_SIZE 4096
+ #endif
+
++#ifndef SOL_TCP
++#define SOL_TCP IPPROTO_TCP
++#endif
++
+ #define SOL_CUSTOM 0xdeadbeef
+
+ struct sockopt_sk {
+@@ -57,6 +61,21 @@ int _getsockopt(struct bpf_sockopt *ctx)
+ return 1;
+ }
+
++ if (ctx->level == SOL_TCP && ctx->optname == TCP_ZEROCOPY_RECEIVE) {
++ /* Verify that TCP_ZEROCOPY_RECEIVE triggers.
++ * It has a custom implementation for performance
++ * reasons.
++ */
++
++ if (optval + sizeof(struct tcp_zerocopy_receive) > optval_end)
++ return 0; /* EPERM, bounds check */
++
++ if (((struct tcp_zerocopy_receive *)optval)->address != 0)
++ return 0; /* EPERM, unexpected data */
++
++ return 1;
++ }
++
+ if (ctx->level == SOL_IP && ctx->optname == IP_FREEBIND) {
+ if (optval + 1 > optval_end)
+ return 0; /* EPERM, bounds check */
+diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h
+index 238f5f61189ee..1d429d67f8ddc 100644
+--- a/tools/testing/selftests/bpf/test_progs.h
++++ b/tools/testing/selftests/bpf/test_progs.h
+@@ -16,7 +16,6 @@ typedef __u16 __sum16;
+ #include <linux/if_packet.h>
+ #include <linux/ip.h>
+ #include <linux/ipv6.h>
+-#include <netinet/tcp.h>
+ #include <linux/filter.h>
+ #include <linux/perf_event.h>
+ #include <linux/socket.h>
+--
+2.39.2
+
--- /dev/null
+From 552d2c67c3b8477e01cbb07b789aaae37bd66863 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 359960a8f1def..5f0b1397798ed 100644
+--- a/tools/bpf/bpftool/feature.c
++++ b/tools/bpf/bpftool/feature.c
+@@ -135,12 +135,12 @@ static void print_end_section(void)
+
+ /* Probing functions */
+
+-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)
+@@ -162,7 +162,7 @@ static int read_procfs(const char *path)
+
+ static void probe_unprivileged_disabled(void)
+ {
+- int res;
++ long res;
+
+ /* No support for C-style ouptut */
+
+@@ -181,14 +181,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 */
+
+@@ -210,7 +210,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);
+ }
+ }
+@@ -218,7 +218,7 @@ static void probe_jit_enable(void)
+
+ static void probe_jit_harden(void)
+ {
+- int res;
++ long res;
+
+ /* No support for C-style ouptut */
+
+@@ -240,7 +240,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);
+ }
+ }
+@@ -248,7 +248,7 @@ static void probe_jit_harden(void)
+
+ static void probe_jit_kallsyms(void)
+ {
+- int res;
++ long res;
+
+ /* No support for C-style ouptut */
+
+@@ -267,14 +267,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 */
+
+@@ -287,7 +287,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 ff4847484ae3b5eb9ac1390f182dff68fdaab0aa 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 4ee20be76508f..4b1641fe30dba 100644
+--- a/drivers/bus/ti-sysc.c
++++ b/drivers/bus/ti-sysc.c
+@@ -1748,7 +1748,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;
+@@ -1760,7 +1760,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 044a8ff057a9b3d1ff97ba96cfca052621d1835a 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 308b353815e17..470d91d7314db 100644
+--- a/drivers/clk/clk-cdce925.c
++++ b/drivers/clk/clk-cdce925.c
+@@ -705,6 +705,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;
+@@ -746,6 +750,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;
+@@ -764,6 +772,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 a02b3d5010c517e881d73b28bbe34f450366e80f 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 8a49e072d6e86..23f37a2cdf3a8 100644
+--- a/drivers/clk/imx/clk-imx8mn.c
++++ b/drivers/clk/imx/clk-imx8mn.c
+@@ -291,7 +291,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;
+@@ -308,10 +308,10 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
+ hws[IMX8MN_CLK_EXT4] = imx_obtain_fixed_clk_hw(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 b3cfbe253f4de2f4d8fffae02cb832da07838317 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 72592e35836b3..98a4711ef38d0 100644
+--- a/drivers/clk/imx/clk-imx8mp.c
++++ b/drivers/clk/imx/clk-imx8mp.c
+@@ -425,25 +425,22 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ 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;
+@@ -743,7 +740,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(4);
+
+--
+2.39.2
+
--- /dev/null
+From d82ed942109925470546dc25c31ed4b0ad684cb8 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 7e1b136e71ae0..8af2a9faa805a 100644
+--- a/drivers/clk/keystone/sci-clk.c
++++ b/drivers/clk/keystone/sci-clk.c
+@@ -302,6 +302,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 1abc625eb25744d6a221c6b4f63ea0bb963602eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 13:26:43 -0600
+Subject: clk: si5341: Add sysfs properties to allow checking/resetting device
+ faults
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 9b13ff4340dff30f361462999a6a122fcc4e473f ]
+
+Add sysfs property files to allow viewing the current and latched states of
+the input present and PLL lock bits, and allow resetting the latched fault
+state. This allows manual checks or automated userspace polling for faults
+occurring after initialization.
+
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Link: https://lore.kernel.org/r/20210325192643.2190069-10-robert.hancock@calian.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: 2560114c06d7 ("clk: si5341: return error if one synth clock registration fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-si5341.c | 96 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 96 insertions(+)
+
+diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
+index 64d962c54bba5..5175b3024f060 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -1450,6 +1450,94 @@ static int si5341_clk_select_active_input(struct clk_si5341 *data)
+ return res;
+ }
+
++static ssize_t input_present_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct clk_si5341 *data = dev_get_drvdata(dev);
++ u32 status;
++ int res = regmap_read(data->regmap, SI5341_STATUS, &status);
++
++ if (res < 0)
++ return res;
++ res = !(status & SI5341_STATUS_LOSREF);
++ return snprintf(buf, PAGE_SIZE, "%d\n", res);
++}
++static DEVICE_ATTR_RO(input_present);
++
++static ssize_t input_present_sticky_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct clk_si5341 *data = dev_get_drvdata(dev);
++ u32 status;
++ int res = regmap_read(data->regmap, SI5341_STATUS_STICKY, &status);
++
++ if (res < 0)
++ return res;
++ res = !(status & SI5341_STATUS_LOSREF);
++ return snprintf(buf, PAGE_SIZE, "%d\n", res);
++}
++static DEVICE_ATTR_RO(input_present_sticky);
++
++static ssize_t pll_locked_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct clk_si5341 *data = dev_get_drvdata(dev);
++ u32 status;
++ int res = regmap_read(data->regmap, SI5341_STATUS, &status);
++
++ if (res < 0)
++ return res;
++ res = !(status & SI5341_STATUS_LOL);
++ return snprintf(buf, PAGE_SIZE, "%d\n", res);
++}
++static DEVICE_ATTR_RO(pll_locked);
++
++static ssize_t pll_locked_sticky_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct clk_si5341 *data = dev_get_drvdata(dev);
++ u32 status;
++ int res = regmap_read(data->regmap, SI5341_STATUS_STICKY, &status);
++
++ if (res < 0)
++ return res;
++ res = !(status & SI5341_STATUS_LOL);
++ return snprintf(buf, PAGE_SIZE, "%d\n", res);
++}
++static DEVICE_ATTR_RO(pll_locked_sticky);
++
++static ssize_t clear_sticky_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct clk_si5341 *data = dev_get_drvdata(dev);
++ long val;
++
++ if (kstrtol(buf, 10, &val))
++ return -EINVAL;
++ if (val) {
++ int res = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0);
++
++ if (res < 0)
++ return res;
++ }
++ return count;
++}
++static DEVICE_ATTR_WO(clear_sticky);
++
++static const struct attribute *si5341_attributes[] = {
++ &dev_attr_input_present.attr,
++ &dev_attr_input_present_sticky.attr,
++ &dev_attr_pll_locked.attr,
++ &dev_attr_pll_locked_sticky.attr,
++ &dev_attr_clear_sticky.attr,
++ NULL
++};
++
+ static int si5341_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+ {
+@@ -1676,6 +1764,12 @@ static int si5341_probe(struct i2c_client *client,
+ goto cleanup;
+ }
+
++ err = sysfs_create_files(&client->dev.kobj, si5341_attributes);
++ if (err) {
++ dev_err(&client->dev, "unable to create sysfs files\n");
++ goto cleanup;
++ }
++
+ /* Free the names, clk framework makes copies */
+ for (i = 0; i < data->num_synth; ++i)
+ devm_kfree(&client->dev, (void *)synth_clock_names[i]);
+@@ -1695,6 +1789,8 @@ static int si5341_remove(struct i2c_client *client)
+ struct clk_si5341 *data = i2c_get_clientdata(client);
+ int i;
+
++ sysfs_remove_files(&client->dev.kobj, si5341_attributes);
++
+ for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
+ if (data->clk[i].vddo_reg)
+ regulator_disable(data->clk[i].vddo_reg);
+--
+2.39.2
+
--- /dev/null
+From ee26487342854537b9936e6cd4e8d071acc4d932 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 13:26:40 -0600
+Subject: clk: si5341: Allow different output VDD_SEL values
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit b7bbf6ec4940d1a69811ec354edeeb9751fa8e85 ]
+
+The driver was not previously programming the VDD_SEL values for each
+output to indicate what external VDDO voltage was used for each. Add
+ability to specify a regulator supplying the VDDO pin for each output of
+the device. The voltage of the regulator is used to automatically set the
+VDD_SEL value appropriately. If no regulator is specified and the chip is
+being reconfigured, assume 2.5V which appears to be the chip default.
+
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Link: https://lore.kernel.org/r/20210325192643.2190069-7-robert.hancock@calian.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: 2560114c06d7 ("clk: si5341: return error if one synth clock registration fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-si5341.c | 136 +++++++++++++++++++++++++++++++--------
+ 1 file changed, 110 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
+index 382a0619a0488..64d962c54bba5 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -19,6 +19,7 @@
+ #include <linux/i2c.h>
+ #include <linux/module.h>
+ #include <linux/regmap.h>
++#include <linux/regulator/consumer.h>
+ #include <linux/slab.h>
+ #include <asm/unaligned.h>
+
+@@ -59,6 +60,7 @@ struct clk_si5341_synth {
+ struct clk_si5341_output {
+ struct clk_hw hw;
+ struct clk_si5341 *data;
++ struct regulator *vddo_reg;
+ u8 index;
+ };
+ #define to_clk_si5341_output(_hw) \
+@@ -84,6 +86,7 @@ struct clk_si5341 {
+ struct clk_si5341_output_config {
+ u8 out_format_drv_bits;
+ u8 out_cm_ampl_bits;
++ u8 vdd_sel_bits;
+ bool synth_master;
+ bool always_on;
+ };
+@@ -136,6 +139,8 @@ struct clk_si5341_output_config {
+ #define SI5341_OUT_R_REG(output) \
+ ((output)->data->reg_rdiv_offset[(output)->index])
+
++#define SI5341_OUT_MUX_VDD_SEL_MASK 0x38
++
+ /* Synthesize N divider */
+ #define SI5341_SYNTH_N_NUM(x) (0x0302 + ((x) * 11))
+ #define SI5341_SYNTH_N_DEN(x) (0x0308 + ((x) * 11))
+@@ -1250,11 +1255,11 @@ static const struct regmap_config si5341_regmap_config = {
+ .volatile_table = &si5341_regmap_volatile,
+ };
+
+-static int si5341_dt_parse_dt(struct i2c_client *client,
+- struct clk_si5341_output_config *config)
++static int si5341_dt_parse_dt(struct clk_si5341 *data,
++ struct clk_si5341_output_config *config)
+ {
+ struct device_node *child;
+- struct device_node *np = client->dev.of_node;
++ struct device_node *np = data->i2c_client->dev.of_node;
+ u32 num;
+ u32 val;
+
+@@ -1263,13 +1268,13 @@ static int si5341_dt_parse_dt(struct i2c_client *client,
+
+ for_each_child_of_node(np, child) {
+ if (of_property_read_u32(child, "reg", &num)) {
+- dev_err(&client->dev, "missing reg property of %s\n",
++ dev_err(&data->i2c_client->dev, "missing reg property of %s\n",
+ child->name);
+ goto put_child;
+ }
+
+ if (num >= SI5341_MAX_NUM_OUTPUTS) {
+- dev_err(&client->dev, "invalid clkout %d\n", num);
++ dev_err(&data->i2c_client->dev, "invalid clkout %d\n", num);
+ goto put_child;
+ }
+
+@@ -1288,7 +1293,7 @@ static int si5341_dt_parse_dt(struct i2c_client *client,
+ config[num].out_format_drv_bits |= 0xc0;
+ break;
+ default:
+- dev_err(&client->dev,
++ dev_err(&data->i2c_client->dev,
+ "invalid silabs,format %u for %u\n",
+ val, num);
+ goto put_child;
+@@ -1301,7 +1306,7 @@ static int si5341_dt_parse_dt(struct i2c_client *client,
+
+ if (!of_property_read_u32(child, "silabs,common-mode", &val)) {
+ if (val > 0xf) {
+- dev_err(&client->dev,
++ dev_err(&data->i2c_client->dev,
+ "invalid silabs,common-mode %u\n",
+ val);
+ goto put_child;
+@@ -1312,7 +1317,7 @@ static int si5341_dt_parse_dt(struct i2c_client *client,
+
+ if (!of_property_read_u32(child, "silabs,amplitude", &val)) {
+ if (val > 0xf) {
+- dev_err(&client->dev,
++ dev_err(&data->i2c_client->dev,
+ "invalid silabs,amplitude %u\n",
+ val);
+ goto put_child;
+@@ -1329,6 +1334,34 @@ static int si5341_dt_parse_dt(struct i2c_client *client,
+
+ config[num].always_on =
+ of_property_read_bool(child, "always-on");
++
++ config[num].vdd_sel_bits = 0x08;
++ if (data->clk[num].vddo_reg) {
++ int vdd = regulator_get_voltage(data->clk[num].vddo_reg);
++
++ switch (vdd) {
++ case 3300000:
++ config[num].vdd_sel_bits |= 0 << 4;
++ break;
++ case 1800000:
++ config[num].vdd_sel_bits |= 1 << 4;
++ break;
++ case 2500000:
++ config[num].vdd_sel_bits |= 2 << 4;
++ break;
++ default:
++ dev_err(&data->i2c_client->dev,
++ "unsupported vddo voltage %d for %s\n",
++ vdd, child->name);
++ goto put_child;
++ }
++ } else {
++ /* chip seems to default to 2.5V when not set */
++ dev_warn(&data->i2c_client->dev,
++ "no regulator set, defaulting vdd_sel to 2.5V for %s\n",
++ child->name);
++ config[num].vdd_sel_bits |= 2 << 4;
++ }
+ }
+
+ return 0;
+@@ -1454,9 +1487,33 @@ static int si5341_probe(struct i2c_client *client,
+ }
+ }
+
+- err = si5341_dt_parse_dt(client, config);
++ for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
++ char reg_name[10];
++
++ snprintf(reg_name, sizeof(reg_name), "vddo%d", i);
++ data->clk[i].vddo_reg = devm_regulator_get_optional(
++ &client->dev, reg_name);
++ if (IS_ERR(data->clk[i].vddo_reg)) {
++ err = PTR_ERR(data->clk[i].vddo_reg);
++ data->clk[i].vddo_reg = NULL;
++ if (err == -ENODEV)
++ continue;
++ goto cleanup;
++ } else {
++ err = regulator_enable(data->clk[i].vddo_reg);
++ if (err) {
++ dev_err(&client->dev,
++ "failed to enable %s regulator: %d\n",
++ reg_name, err);
++ data->clk[i].vddo_reg = NULL;
++ goto cleanup;
++ }
++ }
++ }
++
++ err = si5341_dt_parse_dt(data, config);
+ if (err)
+- return err;
++ goto cleanup;
+
+ if (of_property_read_string(client->dev.of_node, "clock-output-names",
+ &init.name))
+@@ -1464,21 +1521,23 @@ static int si5341_probe(struct i2c_client *client,
+ root_clock_name = init.name;
+
+ data->regmap = devm_regmap_init_i2c(client, &si5341_regmap_config);
+- if (IS_ERR(data->regmap))
+- return PTR_ERR(data->regmap);
++ if (IS_ERR(data->regmap)) {
++ err = PTR_ERR(data->regmap);
++ goto cleanup;
++ }
+
+ i2c_set_clientdata(client, data);
+
+ err = si5341_probe_chip_id(data);
+ if (err < 0)
+- return err;
++ goto cleanup;
+
+ if (of_property_read_bool(client->dev.of_node, "silabs,reprogram")) {
+ initialization_required = true;
+ } else {
+ err = si5341_is_programmed_already(data);
+ if (err < 0)
+- return err;
++ goto cleanup;
+
+ initialization_required = !err;
+ }
+@@ -1487,11 +1546,11 @@ static int si5341_probe(struct i2c_client *client,
+ /* Populate the regmap cache in preparation for "cache only" */
+ err = si5341_read_settings(data);
+ if (err < 0)
+- return err;
++ goto cleanup;
+
+ err = si5341_send_preamble(data);
+ if (err < 0)
+- return err;
++ goto cleanup;
+
+ /*
+ * We intend to send all 'final' register values in a single
+@@ -1504,19 +1563,19 @@ static int si5341_probe(struct i2c_client *client,
+ err = si5341_write_multiple(data, si5341_reg_defaults,
+ ARRAY_SIZE(si5341_reg_defaults));
+ if (err < 0)
+- return err;
++ goto cleanup;
+ }
+
+ /* Input must be up and running at this point */
+ err = si5341_clk_select_active_input(data);
+ if (err < 0)
+- return err;
++ goto cleanup;
+
+ if (initialization_required) {
+ /* PLL configuration is required */
+ err = si5341_initialize_pll(data);
+ if (err < 0)
+- return err;
++ goto cleanup;
+ }
+
+ /* Register the PLL */
+@@ -1529,7 +1588,7 @@ static int si5341_probe(struct i2c_client *client,
+ err = devm_clk_hw_register(&client->dev, &data->hw);
+ if (err) {
+ dev_err(&client->dev, "clock registration failed\n");
+- return err;
++ goto cleanup;
+ }
+
+ init.num_parents = 1;
+@@ -1566,13 +1625,17 @@ static int si5341_probe(struct i2c_client *client,
+ regmap_write(data->regmap,
+ SI5341_OUT_CM(&data->clk[i]),
+ config[i].out_cm_ampl_bits);
++ regmap_update_bits(data->regmap,
++ SI5341_OUT_MUX_SEL(&data->clk[i]),
++ SI5341_OUT_MUX_VDD_SEL_MASK,
++ config[i].vdd_sel_bits);
+ }
+ err = devm_clk_hw_register(&client->dev, &data->clk[i].hw);
+ kfree(init.name); /* clock framework made a copy of the name */
+ if (err) {
+ dev_err(&client->dev,
+ "output %u registration failed\n", i);
+- return err;
++ goto cleanup;
+ }
+ if (config[i].always_on)
+ clk_prepare(data->clk[i].hw.clk);
+@@ -1582,7 +1645,7 @@ static int si5341_probe(struct i2c_client *client,
+ data);
+ if (err) {
+ dev_err(&client->dev, "unable to add clk provider\n");
+- return err;
++ goto cleanup;
+ }
+
+ if (initialization_required) {
+@@ -1590,11 +1653,11 @@ static int si5341_probe(struct i2c_client *client,
+ regcache_cache_only(data->regmap, false);
+ err = regcache_sync(data->regmap);
+ if (err < 0)
+- return err;
++ goto cleanup;
+
+ err = si5341_finalize_defaults(data);
+ if (err < 0)
+- return err;
++ goto cleanup;
+ }
+
+ /* wait for device to report input clock present and PLL lock */
+@@ -1603,14 +1666,14 @@ 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");
+- return err;
++ goto cleanup;
+ }
+
+ /* 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");
+- return err;
++ goto cleanup;
+ }
+
+ /* Free the names, clk framework makes copies */
+@@ -1618,6 +1681,26 @@ static int si5341_probe(struct i2c_client *client,
+ 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);
++ }
++ return err;
++}
++
++static int si5341_remove(struct i2c_client *client)
++{
++ struct clk_si5341 *data = i2c_get_clientdata(client);
++ int i;
++
++ for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) {
++ if (data->clk[i].vddo_reg)
++ regulator_disable(data->clk[i].vddo_reg);
++ }
++
++ return 0;
+ }
+
+ static const struct i2c_device_id si5341_id[] = {
+@@ -1646,6 +1729,7 @@ static struct i2c_driver si5341_driver = {
+ .of_match_table = clk_si5341_of_match,
+ },
+ .probe = si5341_probe,
++ .remove = si5341_remove,
+ .id_table = si5341_id,
+ };
+ module_i2c_driver(si5341_driver);
+--
+2.39.2
+
--- /dev/null
+From 6bcfafc4b1d1d99f7361400dd58c4fb1f4f85571 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 baa5e2ad22668..af66097f9ac5a 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -1685,6 +1685,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;
+@@ -1703,6 +1707,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 70553cedf5ed7a3a4ba42f7457003a334857985b 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 af66097f9ac5a..4dea29fa901d4 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -1732,7 +1732,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);
+@@ -1742,7 +1742,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) {
+@@ -1750,11 +1750,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 */
+@@ -1763,21 +1763,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 f6434fceb5acbeb28a940987bdb58497420200aa 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 5175b3024f060..baa5e2ad22668 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -1545,7 +1545,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];
+@@ -1693,6 +1693,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;
+ }
+ }
+
+@@ -1770,16 +1771,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 d127b02234e27efcf36a6d05e056fa2cb1105221 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 733a962ff521a..15f728edc54b5 100644
+--- a/drivers/clk/tegra/clk-tegra124-emc.c
++++ b/drivers/clk/tegra/clk-tegra124-emc.c
+@@ -455,6 +455,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;
+ }
+
+@@ -506,6 +507,7 @@ struct clk *tegra_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 0b0905dce23bac25a37e895555b3e287cc441826 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 864c484bde1b4..157abc46dcf44 100644
+--- a/drivers/clk/ti/clkctrl.c
++++ b/drivers/clk/ti/clkctrl.c
+@@ -267,6 +267,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;
+@@ -598,6 +601,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 a1ad4455ef9c2f886f6ff162cc021cb377d1c606 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 eb597ea7bb87b..3ddb974da039a 100644
+--- a/drivers/clk/clk-versaclock5.c
++++ b/drivers/clk/clk-versaclock5.c
+@@ -906,6 +906,11 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ }
+
+ 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;
+@@ -920,6 +925,10 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ 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;
+@@ -935,6 +944,10 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ /* 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;
+@@ -952,6 +965,10 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ /* 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;
+@@ -971,6 +988,10 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ 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;
+@@ -989,6 +1010,10 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ 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;
+@@ -1015,6 +1040,10 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ 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 d0ff9ace7ccea518d20a089b587a8bfbc400389a 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 dd4c8bdc925f6e679059f6ea0d764a970b9169af 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 1686705bee7bd..4b06b81d8bb0a 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -777,6 +777,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 7054e4ed6a8821523d6531ec5781bcce6c6541e8 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 596a8c74e40a5..8dc10f9988948 100644
+--- a/drivers/crypto/marvell/cesa/cipher.c
++++ b/drivers/crypto/marvell/cesa/cipher.c
+@@ -287,7 +287,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 1ae406b6e6e6d3d04d7554c3c0dd1e6cd1e8514c 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 bc89a20e5d9d8..351822a598f97 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 9a86c330020ffbca3302df39d89d21c55cc73129 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 a02777c93c07b..48b7f0a64eb81 100644
+--- a/drivers/dax/bus.c
++++ b/drivers/dax/bus.c
+@@ -592,10 +592,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)
+@@ -735,6 +737,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 74f4ebc32571fd49939ef6daeae9a6fccf960b36 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 48b7f0a64eb81..0541b7e4d5c66 100644
+--- a/drivers/dax/bus.c
++++ b/drivers/dax/bus.c
+@@ -403,18 +403,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;
+ }
+@@ -430,6 +446,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)
+ {
+@@ -517,20 +547,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;
+@@ -1270,12 +1286,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);
+ }
+@@ -1299,6 +1313,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")) {
+@@ -1314,13 +1329,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);
+@@ -1358,7 +1371,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 f3dcb75dc0bf8e09cc4c8318c974898a9d3f7c33 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 fff92e2f39744..090a326664756 100644
+--- a/drivers/soc/amlogic/meson-secure-pwrc.c
++++ b/drivers/soc/amlogic/meson-secure-pwrc.c
+@@ -103,7 +103,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 278372e7469268193cdfccf91890613ad17bfb17 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 7e0a55aa2b180..099542dd31544 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -1855,9 +1855,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 79a2612e7068c6b93bf1ef8481ee09330ff42a4d 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 3b6f5963180d5..dadeb2013fd9a 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
+@@ -113,18 +113,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 fd2056366630021dadcb7550b0263923140cc6a0 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 facd4dab433b1..f6c0300090ecd 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>
+@@ -871,6 +872,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,
+@@ -878,6 +917,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 4d7f8fa9e1bc9a27f3e895604e670f2d10389bed 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 8ed8302d6bbb4..e65af025a771f 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -819,8 +819,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 (!(dsi_dev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
+ val |= TC358768_DSI_CONTROL_HSCKMD;
+--
+2.39.2
+
--- /dev/null
+From 1c11fb6a17896c23936a34d91bef9ebde9703fba 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 e65af025a771f..d9021e750940f 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -329,13 +329,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 d04690d7a6b60e39f8bd9815fb73c2c009465349 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 d9021e750940f..4aec4b428189c 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -147,6 +147,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 */
+@@ -279,12 +280,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,
+@@ -421,6 +422,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;
+@@ -432,7 +434,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 b3754f2dbf429eb626e0186a8127a6c97ec76c7f 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 f6c0300090ecd..b7372c5b0b819 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>
+@@ -633,6 +634,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+ struct tc358768_priv *priv = bridge_to_tc358768(bridge);
+ struct mipi_dsi_device *dsi_dev = priv->output.dev;
+ 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;
+@@ -733,9 +735,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 e676e8ed72ee4d91498e2214a3980d9b38066a6a 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 4aec4b428189c..facd4dab433b1 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -725,10 +725,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 0b6eb1d98682f44cb5271e6ab297c0d96cbf1fc7 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 40fffce680c5a..b4a69b2104514 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -763,9 +763,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 ad16fef912b6163abbf04cd5ea44db500f280800 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 b7372c5b0b819..a35674b6ff244 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -744,9 +744,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 a940446d16f88f79b943931d621d75e8901d14ef 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 a35674b6ff244..40fffce680c5a 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -779,7 +779,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 |= val2 << 16;
+--
+2.39.2
+
--- /dev/null
+From 1acb777e45ad88004940dcd829fe2a65b51a7f08 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 0bcccf422192c..4da8cea76a115 100644
+--- a/drivers/gpu/drm/msm/dp/dp_display.c
++++ b/drivers/gpu/drm/msm/dp/dp_display.c
+@@ -1267,9 +1267,9 @@ static int dp_display_remove(struct platform_device *pdev)
+ dp = container_of(g_dp_display,
+ struct dp_display_private, dp_display);
+
++ 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 8df3562b9b9ae2ba5777508cfdbd198e07615dbf 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 5afb3c544653c..4c64e2d4f6500 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+@@ -1262,6 +1262,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;
+@@ -1293,7 +1295,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 e54d4b78d05e92130a6e564d04dc8cf98a358d1b 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 16dbf0f353eda..1f5fb1547730d 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_EOT_PACKET;
+--
+2.39.2
+
--- /dev/null
+From 171b3aadf5ae340e6bdac7d79f1d8f1393739b42 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 1a87cc445b5e1..b0b92f436879a 100644
+--- a/drivers/gpu/drm/panel/panel-simple.c
++++ b/drivers/gpu/drm/panel/panel-simple.c
+@@ -704,8 +704,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 c768db2787e212f78099874d3a216788cb842325 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 35b177d777913..7120710d188fa 100644
+--- a/drivers/gpu/drm/radeon/cypress_dpm.c
++++ b/drivers/gpu/drm/radeon/cypress_dpm.c
+@@ -559,8 +559,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 a5218747742ba..f79b348d36ad9 100644
+--- a/drivers/gpu/drm/radeon/ni_dpm.c
++++ b/drivers/gpu/drm/radeon/ni_dpm.c
+@@ -2240,8 +2240,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 327d65a76e1f4..79b2de65e905e 100644
+--- a/drivers/gpu/drm/radeon/rv740_dpm.c
++++ b/drivers/gpu/drm/radeon/rv740_dpm.c
+@@ -250,8 +250,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 95a4e460842959182b838e89f0cb5d0e20a87b8c 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 9f06dec0fc61d..bb43196d5d83e 100644
+--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
+@@ -777,21 +777,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");
+@@ -804,12 +802,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)
+ {
+@@ -1224,14 +1216,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;
+ }
+ }
+
+@@ -1294,8 +1286,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;
+@@ -1309,7 +1299,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 7a77cc705d8a4dc02c0fa265dabfea0cbadedf96 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 375c79e23ca59..eb104de16fa73 100644
+--- a/drivers/gpu/drm/drm_gem_vram_helper.c
++++ b/drivers/gpu/drm/drm_gem_vram_helper.c
+@@ -41,7 +41,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
+@@ -69,7 +69,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;
+@@ -82,7 +82,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 5cd5aea2d5e6a839d8f3e0daeb312d089c38f7a8 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 0033364ac404f..8cfc49fa4df5b 100644
+--- a/security/integrity/evm/evm_main.c
++++ b/security/integrity/evm/evm_main.c
+@@ -472,7 +472,9 @@ void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
+
+ /**
+ * 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 8a1e222bddaa49697f6e2a74003c86ea9109a884 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 a75ae0c9b14c7..d1cd8785d011d 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 int mipid_spi_remove(struct spi_device *spi)
+--
+2.39.2
+
--- /dev/null
+From 60ae9568ce89cb13304827df3196c9453cdc3644 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 c0b6ec6bf65b7..ef236dbaa2945 100644
+--- a/include/linux/pipe_fs_i.h
++++ b/include/linux/pipe_fs_i.h
+@@ -256,18 +256,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 d8ca0703cf886f4147a599fb6b5ac5edf0f67e8a 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 1c46bc4d27058..05ea3a18552b6 100644
+--- a/drivers/net/gtp.c
++++ b/drivers/net/gtp.c
+@@ -291,7 +291,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 6dce6ecfd6901dba4cf79b2165da2facac6240d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Mar 2022 20:38:16 +0800
+Subject: hwmon: (adm1275) Allow setting sample averaging
+
+From: Potin Lai <potin.lai@quantatw.com>
+
+[ Upstream commit a3cd66d7cbadcc0c29884f25b754fd22699c719c ]
+
+Current driver assume PWR_AVG and VI_AVG as 1 by default, and user needs
+to set sample averaging via sysfs manually.
+
+This patch parses the properties "adi,power-sample-average" and
+"adi,volt-curr-sample-average" from device tree, and setting sample
+averaging during probe. Input value must be one of value in the
+list [1, 2, 4, 8, 16, 32, 64, 128].
+
+Signed-off-by: Potin Lai <potin.lai@quantatw.com>
+Link: https://lore.kernel.org/r/20220302123817.27025-2-potin.lai@quantatw.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Stable-dep-of: b153a0bb4199 ("hwmon: (pmbus/adm1275) Fix problems with temperature monitoring on ADM1272")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/pmbus/adm1275.c | 40 ++++++++++++++++++++++++++++++++++-
+ 1 file changed, 39 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c
+index 0be1b5777d2f0..92eb047ff246f 100644
+--- a/drivers/hwmon/pmbus/adm1275.c
++++ b/drivers/hwmon/pmbus/adm1275.c
+@@ -475,6 +475,7 @@ static int adm1275_probe(struct i2c_client *client)
+ int vindex = -1, voindex = -1, cindex = -1, pindex = -1;
+ int tindex = -1;
+ u32 shunt;
++ u32 avg;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_BYTE_DATA
+@@ -687,7 +688,7 @@ static int adm1275_probe(struct i2c_client *client)
+ 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,
++ ret = i2c_smbus_write_word_data(client,
+ ADM1275_PMON_CONFIG,
+ config);
+ if (ret < 0) {
+@@ -756,6 +757,43 @@ static int adm1275_probe(struct i2c_client *client)
+ return -ENODEV;
+ }
+
++ if (data->have_power_sampling &&
++ of_property_read_u32(client->dev.of_node,
++ "adi,power-sample-average", &avg) == 0) {
++ if (!avg || avg > ADM1275_SAMPLES_AVG_MAX ||
++ BIT(__fls(avg)) != avg) {
++ dev_err(&client->dev,
++ "Invalid number of power samples");
++ return -EINVAL;
++ }
++ ret = adm1275_write_pmon_config(data, client, true,
++ ilog2(avg));
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "Setting power sample averaging failed with error %d",
++ ret);
++ return ret;
++ }
++ }
++
++ if (of_property_read_u32(client->dev.of_node,
++ "adi,volt-curr-sample-average", &avg) == 0) {
++ if (!avg || avg > ADM1275_SAMPLES_AVG_MAX ||
++ BIT(__fls(avg)) != avg) {
++ dev_err(&client->dev,
++ "Invalid number of voltage/current samples");
++ return -EINVAL;
++ }
++ ret = adm1275_write_pmon_config(data, client, false,
++ ilog2(avg));
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "Setting voltage and current sample averaging failed with error %d",
++ ret);
++ return ret;
++ }
++ }
++
+ if (voindex < 0)
+ voindex = vindex;
+ if (vindex >= 0) {
+--
+2.39.2
+
--- /dev/null
+From 0c0b7009ecd50f2663ebeecc2f294fd680f2b3f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 May 2021 17:10:43 +0000
+Subject: hwmon: (adm1275) enable adm1272 temperature reporting
+
+From: Chu Lin <linchuyuan@google.com>
+
+[ Upstream commit 9da9c2dc57b2fa2e65521894cb66df4bf615214d ]
+
+adm1272 supports temperature reporting but it is disabled by default.
+
+Tested:
+ls temp1_*
+temp1_crit temp1_highest temp1_max
+temp1_crit_alarm temp1_input temp1_max_alarm
+
+cat temp1_input
+26642
+
+Signed-off-by: Chu Lin <linchuyuan@google.com>
+Link: https://lore.kernel.org/r/20210512171043.2433694-1-linchuyuan@google.com
+[groeck: Updated subject to reflect correct driver]
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Stable-dep-of: b153a0bb4199 ("hwmon: (pmbus/adm1275) Fix problems with temperature monitoring on ADM1272")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/pmbus/adm1275.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c
+index e7997f37b2666..0be1b5777d2f0 100644
+--- a/drivers/hwmon/pmbus/adm1275.c
++++ b/drivers/hwmon/pmbus/adm1275.c
+@@ -611,11 +611,13 @@ static int adm1275_probe(struct i2c_client *client)
+ tindex = 8;
+
+ info->func[0] |= PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT |
+- PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
++ PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
++ PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
+
+- /* Enable VOUT if not enabled (it is disabled by default) */
+- if (!(config & ADM1278_VOUT_EN)) {
+- config |= ADM1278_VOUT_EN;
++ /* 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);
+@@ -625,10 +627,6 @@ static int adm1275_probe(struct i2c_client *client)
+ return -ENODEV;
+ }
+ }
+-
+- if (config & ADM1278_TEMP1_EN)
+- info->func[0] |=
+- PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
+ if (config & ADM1278_VIN_EN)
+ info->func[0] |= PMBUS_HAVE_VIN;
+ break;
+--
+2.39.2
+
--- /dev/null
+From f25316d6adfc6d3a70b958e068628015d8d028d7 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 f29ce49294daf..89d036bf88df7 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 26275eeecfd6a64675eea200d88f78bfe98b2d2c 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 92eb047ff246f..c0618205758e9 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 77c49dc265cc96ffdd5b46cb08d8bc03ccd6ba56 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 cf1206c3cb516b6a5d22d5a8452a679feed45d1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Oct 2021 12:11:08 +0200
+Subject: hwrng: virtio - add an internal buffer
+
+From: Laurent Vivier <lvivier@redhat.com>
+
+[ Upstream commit bf3175bc50a3754dc427e2f5046e17a9fafc8be7 ]
+
+hwrng core uses two buffers that can be mixed in the
+virtio-rng queue.
+
+If the buffer is provided with wait=0 it is enqueued in the
+virtio-rng queue but unused by the caller.
+On the next call, core provides another buffer but the
+first one is filled instead and the new one queued.
+And the caller reads the data from the new one that is not
+updated, and the data in the first one are lost.
+
+To avoid this mix, virtio-rng needs to use its own unique
+internal buffer at a cost of a data copy to the caller buffer.
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Link: https://lore.kernel.org/r/20211028101111.128049-2-lvivier@redhat.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Stable-dep-of: ac52578d6e8d ("hwrng: virtio - Fix race on data_avail and actual data")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/virtio-rng.c | 43 ++++++++++++++++++++++-------
+ 1 file changed, 33 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
+index a90001e02bf7a..208c547dcac16 100644
+--- a/drivers/char/hw_random/virtio-rng.c
++++ b/drivers/char/hw_random/virtio-rng.c
+@@ -18,13 +18,20 @@ static DEFINE_IDA(rng_index_ida);
+ struct virtrng_info {
+ struct hwrng hwrng;
+ struct virtqueue *vq;
+- struct completion have_data;
+ char name[25];
+- unsigned int data_avail;
+ int index;
+ bool busy;
+ bool hwrng_register_done;
+ bool hwrng_removed;
++ /* data transfer */
++ struct completion have_data;
++ unsigned int data_avail;
++ /* minimal size returned by rng_buffer_size() */
++#if SMP_CACHE_BYTES < 32
++ u8 data[32];
++#else
++ u8 data[SMP_CACHE_BYTES];
++#endif
+ };
+
+ static void random_recv_done(struct virtqueue *vq)
+@@ -39,14 +46,14 @@ static void random_recv_done(struct virtqueue *vq)
+ }
+
+ /* The host will fill any buffer we give it with sweet, sweet randomness. */
+-static void register_buffer(struct virtrng_info *vi, u8 *buf, size_t size)
++static void register_buffer(struct virtrng_info *vi)
+ {
+ struct scatterlist sg;
+
+- sg_init_one(&sg, buf, size);
++ sg_init_one(&sg, vi->data, sizeof(vi->data));
+
+ /* There should always be room for one buffer. */
+- virtqueue_add_inbuf(vi->vq, &sg, 1, buf, GFP_KERNEL);
++ virtqueue_add_inbuf(vi->vq, &sg, 1, vi->data, GFP_KERNEL);
+
+ virtqueue_kick(vi->vq);
+ }
+@@ -55,6 +62,8 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
+ {
+ int ret;
+ struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
++ unsigned int chunk;
++ size_t read;
+
+ if (vi->hwrng_removed)
+ return -ENODEV;
+@@ -62,19 +71,33 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
+ if (!vi->busy) {
+ vi->busy = true;
+ reinit_completion(&vi->have_data);
+- register_buffer(vi, buf, size);
++ register_buffer(vi);
+ }
+
+ if (!wait)
+ return 0;
+
+- ret = wait_for_completion_killable(&vi->have_data);
+- if (ret < 0)
+- return ret;
++ read = 0;
++ while (size != 0) {
++ ret = wait_for_completion_killable(&vi->have_data);
++ if (ret < 0)
++ return ret;
++
++ chunk = min_t(unsigned int, size, vi->data_avail);
++ memcpy(buf + read, vi->data, chunk);
++ read += chunk;
++ size -= chunk;
++ vi->data_avail = 0;
++
++ if (size != 0) {
++ reinit_completion(&vi->have_data);
++ register_buffer(vi);
++ }
++ }
+
+ vi->busy = false;
+
+- return vi->data_avail;
++ return read;
+ }
+
+ static void virtio_cleanup(struct hwrng *rng)
+--
+2.39.2
+
--- /dev/null
+From a4ef1bf50da23c50ffc9b011e4d22f19f95af67a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Oct 2021 12:11:11 +0200
+Subject: hwrng: virtio - always add a pending request
+
+From: Laurent Vivier <lvivier@redhat.com>
+
+[ Upstream commit 9a4b612d675b03f7fc9fa1957ca399c8223f3954 ]
+
+If we ensure we have already some data available by enqueuing
+again the buffer once data are exhausted, we can return what we
+have without waiting for the device answer.
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Link: https://lore.kernel.org/r/20211028101111.128049-5-lvivier@redhat.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Stable-dep-of: ac52578d6e8d ("hwrng: virtio - Fix race on data_avail and actual data")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/virtio-rng.c | 26 ++++++++++++--------------
+ 1 file changed, 12 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
+index 8ba97cf4ca8fb..0a7dde135db19 100644
+--- a/drivers/char/hw_random/virtio-rng.c
++++ b/drivers/char/hw_random/virtio-rng.c
+@@ -20,7 +20,6 @@ struct virtrng_info {
+ struct virtqueue *vq;
+ char name[25];
+ int index;
+- bool busy;
+ bool hwrng_register_done;
+ bool hwrng_removed;
+ /* data transfer */
+@@ -44,16 +43,18 @@ static void random_recv_done(struct virtqueue *vq)
+ return;
+
+ vi->data_idx = 0;
+- vi->busy = false;
+
+ complete(&vi->have_data);
+ }
+
+-/* The host will fill any buffer we give it with sweet, sweet randomness. */
+-static void register_buffer(struct virtrng_info *vi)
++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));
+
+ /* There should always be room for one buffer. */
+@@ -69,6 +70,8 @@ static unsigned int copy_data(struct virtrng_info *vi, void *buf,
+ memcpy(buf, vi->data + vi->data_idx, size);
+ vi->data_idx += size;
+ vi->data_avail -= size;
++ if (vi->data_avail == 0)
++ request_entropy(vi);
+ return size;
+ }
+
+@@ -98,13 +101,7 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
+ * so either size is 0 or data_avail is 0
+ */
+ while (size != 0) {
+- /* data_avail is 0 */
+- if (!vi->busy) {
+- /* no pending request, ask for more */
+- vi->busy = true;
+- reinit_completion(&vi->have_data);
+- register_buffer(vi);
+- }
++ /* data_avail is 0 but a request is pending */
+ ret = wait_for_completion_killable(&vi->have_data);
+ if (ret < 0)
+ return ret;
+@@ -126,8 +123,7 @@ static void virtio_cleanup(struct hwrng *rng)
+ {
+ struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
+
+- if (vi->busy)
+- complete(&vi->have_data);
++ complete(&vi->have_data);
+ }
+
+ static int probe_common(struct virtio_device *vdev)
+@@ -163,6 +159,9 @@ static int probe_common(struct virtio_device *vdev)
+ goto err_find;
+ }
+
++ /* we always have a pending entropy request */
++ request_entropy(vi);
++
+ return 0;
+
+ err_find:
+@@ -181,7 +180,6 @@ static void remove_common(struct virtio_device *vdev)
+ vi->data_idx = 0;
+ complete(&vi->have_data);
+ vdev->config->reset(vdev);
+- vi->busy = false;
+ if (vi->hwrng_register_done)
+ hwrng_unregister(&vi->hwrng);
+ vdev->config->del_vqs(vdev);
+--
+2.39.2
+
--- /dev/null
+From e5c27d8f5dd76cd19bd01e31e5df496b21c4be20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Oct 2021 12:11:09 +0200
+Subject: hwrng: virtio - don't wait on cleanup
+
+From: Laurent Vivier <lvivier@redhat.com>
+
+[ Upstream commit 2bb31abdbe55742c89f4dc0cc26fcbc8467364f6 ]
+
+When virtio-rng device was dropped by the hwrng core we were forced
+to wait the buffer to come back from the device to not have
+remaining ongoing operation that could spoil the buffer.
+
+But now, as the buffer is internal to the virtio-rng we can release
+the waiting loop immediately, the buffer will be retrieve and use
+when the virtio-rng driver will be selected again.
+
+This avoids to hang on an rng_current write command if the virtio-rng
+device is blocked by a lack of entropy. This allows to select
+another entropy source if the current one is empty.
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Link: https://lore.kernel.org/r/20211028101111.128049-3-lvivier@redhat.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Stable-dep-of: ac52578d6e8d ("hwrng: virtio - Fix race on data_avail and actual data")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/virtio-rng.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
+index 208c547dcac16..173aeea835bb6 100644
+--- a/drivers/char/hw_random/virtio-rng.c
++++ b/drivers/char/hw_random/virtio-rng.c
+@@ -82,6 +82,11 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
+ ret = wait_for_completion_killable(&vi->have_data);
+ if (ret < 0)
+ return ret;
++ /* if vi->data_avail is 0, we have been interrupted
++ * by a cleanup, but buffer stays in the queue
++ */
++ if (vi->data_avail == 0)
++ return read;
+
+ chunk = min_t(unsigned int, size, vi->data_avail);
+ memcpy(buf + read, vi->data, chunk);
+@@ -105,7 +110,7 @@ static void virtio_cleanup(struct hwrng *rng)
+ struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
+
+ if (vi->busy)
+- wait_for_completion(&vi->have_data);
++ complete(&vi->have_data);
+ }
+
+ static int probe_common(struct virtio_device *vdev)
+--
+2.39.2
+
--- /dev/null
+From 25df29d220b89bf5b7a4a3087e091adddf5b3314 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Oct 2021 12:11:10 +0200
+Subject: hwrng: virtio - don't waste entropy
+
+From: Laurent Vivier <lvivier@redhat.com>
+
+[ Upstream commit 5c8e933050044d6dd2a000f9a5756ae73cbe7c44 ]
+
+if we don't use all the entropy available in the buffer, keep it
+and use it later.
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Link: https://lore.kernel.org/r/20211028101111.128049-4-lvivier@redhat.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Stable-dep-of: ac52578d6e8d ("hwrng: virtio - Fix race on data_avail and actual data")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/virtio-rng.c | 52 +++++++++++++++++++----------
+ 1 file changed, 35 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
+index 173aeea835bb6..8ba97cf4ca8fb 100644
+--- a/drivers/char/hw_random/virtio-rng.c
++++ b/drivers/char/hw_random/virtio-rng.c
+@@ -26,6 +26,7 @@ struct virtrng_info {
+ /* data transfer */
+ struct completion have_data;
+ unsigned int data_avail;
++ unsigned int data_idx;
+ /* minimal size returned by rng_buffer_size() */
+ #if SMP_CACHE_BYTES < 32
+ u8 data[32];
+@@ -42,6 +43,9 @@ static void random_recv_done(struct virtqueue *vq)
+ if (!virtqueue_get_buf(vi->vq, &vi->data_avail))
+ return;
+
++ vi->data_idx = 0;
++ vi->busy = false;
++
+ complete(&vi->have_data);
+ }
+
+@@ -58,6 +62,16 @@ static void register_buffer(struct virtrng_info *vi)
+ virtqueue_kick(vi->vq);
+ }
+
++static unsigned int copy_data(struct virtrng_info *vi, void *buf,
++ unsigned int size)
++{
++ size = min_t(unsigned int, size, vi->data_avail);
++ memcpy(buf, vi->data + vi->data_idx, size);
++ vi->data_idx += size;
++ vi->data_avail -= size;
++ return size;
++}
++
+ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
+ {
+ int ret;
+@@ -68,17 +82,29 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
+ if (vi->hwrng_removed)
+ return -ENODEV;
+
+- if (!vi->busy) {
+- vi->busy = true;
+- reinit_completion(&vi->have_data);
+- register_buffer(vi);
++ read = 0;
++
++ /* copy available data */
++ if (vi->data_avail) {
++ chunk = copy_data(vi, buf, size);
++ size -= chunk;
++ read += chunk;
+ }
+
+ if (!wait)
+- return 0;
++ return read;
+
+- read = 0;
++ /* We have already copied available entropy,
++ * so either size is 0 or data_avail is 0
++ */
+ while (size != 0) {
++ /* data_avail is 0 */
++ if (!vi->busy) {
++ /* no pending request, ask for more */
++ vi->busy = true;
++ reinit_completion(&vi->have_data);
++ register_buffer(vi);
++ }
+ ret = wait_for_completion_killable(&vi->have_data);
+ if (ret < 0)
+ return ret;
+@@ -88,20 +114,11 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
+ if (vi->data_avail == 0)
+ return read;
+
+- chunk = min_t(unsigned int, size, vi->data_avail);
+- memcpy(buf + read, vi->data, chunk);
+- read += chunk;
++ chunk = copy_data(vi, buf + read, size);
+ size -= chunk;
+- vi->data_avail = 0;
+-
+- if (size != 0) {
+- reinit_completion(&vi->have_data);
+- register_buffer(vi);
+- }
++ read += chunk;
+ }
+
+- vi->busy = false;
+-
+ return read;
+ }
+
+@@ -161,6 +178,7 @@ static void remove_common(struct virtio_device *vdev)
+
+ vi->hwrng_removed = true;
+ vi->data_avail = 0;
++ vi->data_idx = 0;
+ complete(&vi->have_data);
+ vdev->config->reset(vdev);
+ vi->busy = false;
+--
+2.39.2
+
--- /dev/null
+From b069af228565e64e0ac0fe214167dd764103a3bb 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 0a7dde135db19..3a194eb3ce8ad 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 ca3cf4ea5ab2608e6153ac6e6734cc2e88d389b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Feb 2023 11:56:28 -0500
+Subject: IB/hfi1: Fix sdma.h tx->num_descs off-by-one errors
+
+From: Patrick Kelsey <pat.kelsey@cornelisnetworks.com>
+
+[ Upstream commit fd8958efe8779d3db19c9124fce593ce681ac709 ]
+
+Fix three sources of error involving struct sdma_txreq.num_descs.
+
+When _extend_sdma_tx_descs() extends the descriptor array, it uses the
+value of tx->num_descs to determine how many existing entries from the
+tx's original, internal descriptor array to copy to the newly allocated
+one. As this value was incremented before the call, the copy loop will
+access one entry past the internal descriptor array, copying its contents
+into the corresponding slot in the new array.
+
+If the call to _extend_sdma_tx_descs() fails, _pad_smda_tx_descs() then
+invokes __sdma_tx_clean() which uses the value of tx->num_desc to drive a
+loop that unmaps all descriptor entries in use. As this value was
+incremented before the call, the unmap loop will invoke sdma_unmap_desc()
+on a descriptor entry whose contents consist of whatever random data was
+copied into it during (1), leading to cascading further calls into the
+kernel and driver using arbitrary data.
+
+_sdma_close_tx() was using tx->num_descs instead of tx->num_descs - 1.
+
+Fix all of the above by:
+- Only increment .num_descs after .descp is extended.
+- Use .num_descs - 1 instead of .num_descs for last .descp entry.
+
+Fixes: f4d26d81ad7f ("staging/rdma/hfi1: Add coalescing support for SDMA TX descriptors")
+Link: https://lore.kernel.org/r/167656658879.2223096.10026561343022570690.stgit@awfm-02.cornelisnetworks.com
+Signed-off-by: Brendan Cunningham <bcunningham@cornelisnetworks.com>
+Signed-off-by: Patrick Kelsey <pat.kelsey@cornelisnetworks.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: c9358de193ec ("IB/hfi1: Fix wrong mmu_node used for user SDMA packet after invalidate")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/sdma.c | 4 ++--
+ drivers/infiniband/hw/hfi1/sdma.h | 15 +++++++--------
+ 2 files changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c
+index 061562627dae4..728bf122ee0a7 100644
+--- a/drivers/infiniband/hw/hfi1/sdma.c
++++ b/drivers/infiniband/hw/hfi1/sdma.c
+@@ -3187,8 +3187,7 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx)
+ {
+ int rval = 0;
+
+- tx->num_desc++;
+- if ((unlikely(tx->num_desc == tx->desc_limit))) {
++ if ((unlikely(tx->num_desc + 1 == tx->desc_limit))) {
+ rval = _extend_sdma_tx_descs(dd, tx);
+ if (rval) {
+ __sdma_txclean(dd, tx);
+@@ -3203,6 +3202,7 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx)
+ NULL,
+ dd->sdma_pad_phys,
+ sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1)));
++ 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 7d4f316ac6e43..5a372ca1f6acf 100644
+--- a/drivers/infiniband/hw/hfi1/sdma.h
++++ b/drivers/infiniband/hw/hfi1/sdma.h
+@@ -674,14 +674,13 @@ static inline void sdma_txclean(struct hfi1_devdata *dd, struct sdma_txreq *tx)
+ static inline void _sdma_close_tx(struct hfi1_devdata *dd,
+ struct sdma_txreq *tx)
+ {
+- tx->descp[tx->num_desc].qw[0] |=
+- SDMA_DESC0_LAST_DESC_FLAG;
+- tx->descp[tx->num_desc].qw[1] |=
+- dd->default_desc1;
++ u16 last_desc = tx->num_desc - 1;
++
++ tx->descp[last_desc].qw[0] |= SDMA_DESC0_LAST_DESC_FLAG;
++ tx->descp[last_desc].qw[1] |= dd->default_desc1;
+ if (tx->flags & SDMA_TXREQ_F_URGENT)
+- tx->descp[tx->num_desc].qw[1] |=
+- (SDMA_DESC1_HEAD_TO_HOST_FLAG |
+- SDMA_DESC1_INT_REQ_FLAG);
++ tx->descp[last_desc].qw[1] |= (SDMA_DESC1_HEAD_TO_HOST_FLAG |
++ SDMA_DESC1_INT_REQ_FLAG);
+ }
+
+ static inline int _sdma_txadd_daddr(
+@@ -700,6 +699,7 @@ static inline int _sdma_txadd_daddr(
+ pinning_ctx,
+ addr, len);
+ WARN_ON(len > tx->tlen);
++ tx->num_desc++;
+ tx->tlen -= len;
+ /* special cases for last */
+ if (!tx->tlen) {
+@@ -711,7 +711,6 @@ static inline int _sdma_txadd_daddr(
+ _sdma_close_tx(dd, tx);
+ }
+ }
+- tx->num_desc++;
+ return rval;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 59423d0101c7a2958d3388a4ad2f1210fe6b4d64 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 956fc3fd88b99..1880484681357 100644
+--- a/drivers/infiniband/hw/hfi1/ipoib_tx.c
++++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c
+@@ -251,11 +251,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 d331184ded308..a501b7a682fca 100644
+--- a/drivers/infiniband/hw/hfi1/mmu_rb.c
++++ b/drivers/infiniband/hw/hfi1/mmu_rb.c
+@@ -60,8 +60,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 = {
+@@ -144,7 +143,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);
+@@ -172,12 +175,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);
+@@ -221,6 +218,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;
+@@ -235,6 +274,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);
+@@ -247,7 +290,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);
+ }
+ }
+
+@@ -259,7 +302,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);
+@@ -268,38 +310,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
+@@ -312,11 +332,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 0265d81c62061..be85537d23267 100644
+--- a/drivers/infiniband/hw/hfi1/mmu_rb.h
++++ b/drivers/infiniband/hw/hfi1/mmu_rb.h
+@@ -57,6 +57,7 @@ struct mmu_rb_node {
+ struct rb_node node;
+ struct mmu_rb_handler *handler;
+ struct list_head list;
++ struct kref refcount;
+ };
+
+ /*
+@@ -92,6 +93,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 728bf122ee0a7..2dc97de434a5e 100644
+--- a/drivers/infiniband/hw/hfi1/sdma.c
++++ b/drivers/infiniband/hw/hfi1/sdma.c
+@@ -1635,7 +1635,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;
+ }
+
+ /*
+@@ -3155,8 +3168,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;
+@@ -3199,9 +3212,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 5a372ca1f6acf..7611f09d78dca 100644
+--- a/drivers/infiniband/hw/hfi1/sdma.h
++++ b/drivers/infiniband/hw/hfi1/sdma.h
+@@ -635,9 +635,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];
+
+@@ -654,7 +656,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 */
+@@ -686,18 +692,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;
+@@ -717,11 +725,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.
+ *
+@@ -733,11 +748,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;
+@@ -761,7 +778,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);
+ }
+
+ /**
+@@ -795,8 +813,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);
+ }
+
+ /**
+@@ -842,7 +860,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;
+@@ -1093,6 +1112,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 4204650cebc29..fb091b5834b5d 100644
+--- a/drivers/infiniband/hw/hfi1/sdma_txreq.h
++++ b/drivers/infiniband/hw/hfi1/sdma_txreq.h
+@@ -62,6 +62,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 3f49633bf9855..a67791187d46d 100644
+--- a/drivers/infiniband/hw/hfi1/user_sdma.c
++++ b/drivers/infiniband/hw/hfi1/user_sdma.c
+@@ -103,18 +103,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,
+@@ -288,14 +284,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);
+@@ -1316,25 +1312,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);
+@@ -1343,11 +1331,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,
+@@ -1396,6 +1385,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)
+@@ -1409,6 +1405,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) {
+@@ -1472,15 +1474,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);
+@@ -1492,6 +1494,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,
+@@ -1535,9 +1551,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
+@@ -1559,8 +1578,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;
+@@ -1581,15 +1598,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;
+ }
+@@ -1640,42 +1657,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.
+ *
+@@ -1688,10 +1675,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;
+
+@@ -1709,13 +1692,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 9d417aacfa8b7..b2b26b71fcef0 100644
+--- a/drivers/infiniband/hw/hfi1/user_sdma.h
++++ b/drivers/infiniband/hw/hfi1/user_sdma.h
+@@ -145,7 +145,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 7658c620a125c..ab8bcdf104475 100644
+--- a/drivers/infiniband/hw/hfi1/vnic_sdma.c
++++ b/drivers/infiniband/hw/hfi1/vnic_sdma.c
+@@ -106,11 +106,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 854f7af34a3c8ff45221c9062afb9b802a127f1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Nov 2021 20:53:22 +0100
+Subject: IB/hfi1: Use bitmap_zalloc() when applicable
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit f86dbc9fc5d83384eae7eda0de17f823e8c81ca0 ]
+
+Use 'bitmap_zalloc()' to simplify code, improve the semantic and avoid
+some open-coded arithmetic in allocator arguments.
+
+Also change the corresponding 'kfree()' into 'bitmap_free()' to keep
+consistency.
+
+Link: https://lore.kernel.org/r/d46c6bc1869b8869244fa71943d2cad4104b3668.1637869925.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: c9358de193ec ("IB/hfi1: Fix wrong mmu_node used for user SDMA packet after invalidate")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/user_sdma.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c
+index 1eb5a44a4ae6a..3f49633bf9855 100644
+--- a/drivers/infiniband/hw/hfi1/user_sdma.c
++++ b/drivers/infiniband/hw/hfi1/user_sdma.c
+@@ -202,9 +202,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt,
+ if (!pq->reqs)
+ goto pq_reqs_nomem;
+
+- pq->req_in_use = kcalloc(BITS_TO_LONGS(hfi1_sdma_comp_ring_size),
+- sizeof(*pq->req_in_use),
+- GFP_KERNEL);
++ pq->req_in_use = bitmap_zalloc(hfi1_sdma_comp_ring_size, GFP_KERNEL);
+ if (!pq->req_in_use)
+ goto pq_reqs_no_in_use;
+
+@@ -251,7 +249,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt,
+ cq_nomem:
+ kmem_cache_destroy(pq->txreq_cache);
+ pq_txreq_nomem:
+- kfree(pq->req_in_use);
++ bitmap_free(pq->req_in_use);
+ pq_reqs_no_in_use:
+ kfree(pq->reqs);
+ pq_reqs_nomem:
+@@ -298,7 +296,7 @@ int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd,
+ pq->wait,
+ !atomic_read(&pq->n_reqs));
+ kfree(pq->reqs);
+- kfree(pq->req_in_use);
++ bitmap_free(pq->req_in_use);
+ kmem_cache_destroy(pq->txreq_cache);
+ flush_pq_iowait(pq);
+ kfree(pq);
+--
+2.39.2
+
--- /dev/null
+From e21a93d91af937916e22e329a86dfe710ae4d7fc 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 970dd878d8a76..47ba1eafcdc7b 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"
+
+@@ -272,6 +273,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 3aa0efb542aaf..72d7d2cf126d1 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -1569,14 +1569,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]);
++ }
+ }
+
+ /**
+@@ -5257,6 +5279,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 36e6af181b7d5be161661f87e7e94c93c932e1c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jun 2023 14:32:29 -0700
+Subject: igc: Fix race condition in PTP tx code
+
+From: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+
+[ Upstream commit 9c50e2b150c8ee0eee5f8154e2ad168cdd748877 ]
+
+Currently, the igc driver supports timestamping only one tx packet at a
+time. During the transmission flow, the skb that requires hardware
+timestamping is saved in adapter->ptp_tx_skb. Once hardware has the
+timestamp, an interrupt is delivered, and adapter->ptp_tx_work is
+scheduled. In igc_ptp_tx_work(), we read the timestamp register, update
+adapter->ptp_tx_skb, and notify the network stack.
+
+While the thread executing the transmission flow (the user process
+running in kernel mode) and the thread executing ptp_tx_work don't
+access adapter->ptp_tx_skb concurrently, there are two other places
+where adapter->ptp_tx_skb is accessed: igc_ptp_tx_hang() and
+igc_ptp_suspend().
+
+igc_ptp_tx_hang() is executed by the adapter->watchdog_task worker
+thread which runs periodically so it is possible we have two threads
+accessing ptp_tx_skb at the same time. Consider the following scenario:
+right after __IGC_PTP_TX_IN_PROGRESS is set in igc_xmit_frame_ring(),
+igc_ptp_tx_hang() is executed. Since adapter->ptp_tx_start hasn't been
+written yet, this is considered a timeout and adapter->ptp_tx_skb is
+cleaned up.
+
+This patch fixes the issue described above by adding the ptp_tx_lock to
+protect access to ptp_tx_skb and ptp_tx_start fields from igc_adapter.
+Since igc_xmit_frame_ring() called in atomic context by the networking
+stack, ptp_tx_lock is defined as a spinlock, and the irq safe variants
+of lock/unlock are used.
+
+With the introduction of the ptp_tx_lock, the __IGC_PTP_TX_IN_PROGRESS
+flag doesn't provide much of a use anymore so this patch gets rid of it.
+
+Fixes: 2c344ae24501 ("igc: Add support for TX timestamping")
+Signed-off-by: Andre Guedes <andre.guedes@intel.com>
+Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Reviewed-by: Kurt Kanzenbach <kurt@linutronix.de>
+Tested-by: Naama Meir <naamax.meir@linux.intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc.h | 5 +-
+ drivers/net/ethernet/intel/igc/igc_main.c | 9 ++--
+ drivers/net/ethernet/intel/igc/igc_ptp.c | 57 ++++++++++++-----------
+ 3 files changed, 41 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
+index 47ba1eafcdc7b..33f64c80335d3 100644
+--- a/drivers/net/ethernet/intel/igc/igc.h
++++ b/drivers/net/ethernet/intel/igc/igc.h
+@@ -210,6 +210,10 @@ struct igc_adapter {
+ struct ptp_clock *ptp_clock;
+ struct ptp_clock_info ptp_caps;
+ struct work_struct ptp_tx_work;
++ /* Access to ptp_tx_skb and ptp_tx_start are protected by the
++ * ptp_tx_lock.
++ */
++ spinlock_t ptp_tx_lock;
+ struct sk_buff *ptp_tx_skb;
+ struct hwtstamp_config tstamp_config;
+ unsigned long ptp_tx_start;
+@@ -389,7 +393,6 @@ enum igc_state_t {
+ __IGC_TESTING,
+ __IGC_RESETTING,
+ __IGC_DOWN,
+- __IGC_PTP_TX_IN_PROGRESS,
+ };
+
+ enum igc_tx_flags {
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index 72d7d2cf126d1..a15e4b6d7fa40 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -1467,9 +1467,10 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+ * the other timer registers before skipping the
+ * timestamping request.
+ */
+- if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON &&
+- !test_and_set_bit_lock(__IGC_PTP_TX_IN_PROGRESS,
+- &adapter->state)) {
++ unsigned long flags;
++
++ spin_lock_irqsave(&adapter->ptp_tx_lock, flags);
++ if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && !adapter->ptp_tx_skb) {
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+ tx_flags |= IGC_TX_FLAGS_TSTAMP;
+
+@@ -1478,6 +1479,8 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+ } else {
+ adapter->tx_hwtstamp_skipped++;
+ }
++
++ spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags);
+ }
+
+ /* record initial flags and protocol */
+diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c
+index ef53f7665b58c..25b238c6a675c 100644
+--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
++++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
+@@ -323,6 +323,7 @@ static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter,
+ return 0;
+ }
+
++/* Requires adapter->ptp_tx_lock held by caller. */
+ static void igc_ptp_tx_timeout(struct igc_adapter *adapter)
+ {
+ struct igc_hw *hw = &adapter->hw;
+@@ -330,7 +331,6 @@ static void igc_ptp_tx_timeout(struct igc_adapter *adapter)
+ dev_kfree_skb_any(adapter->ptp_tx_skb);
+ adapter->ptp_tx_skb = NULL;
+ adapter->tx_hwtstamp_timeouts++;
+- clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
+ /* Clear the tx valid bit in TSYNCTXCTL register to enable interrupt. */
+ rd32(IGC_TXSTMPH);
+ netdev_warn(adapter->netdev, "Tx timestamp timeout\n");
+@@ -338,20 +338,20 @@ static void igc_ptp_tx_timeout(struct igc_adapter *adapter)
+
+ void igc_ptp_tx_hang(struct igc_adapter *adapter)
+ {
+- bool timeout = time_is_before_jiffies(adapter->ptp_tx_start +
+- IGC_PTP_TX_TIMEOUT);
++ unsigned long flags;
+
+- if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state))
+- return;
++ spin_lock_irqsave(&adapter->ptp_tx_lock, flags);
+
+- /* If we haven't received a timestamp within the timeout, it is
+- * reasonable to assume that it will never occur, so we can unlock the
+- * timestamp bit when this occurs.
+- */
+- if (timeout) {
+- cancel_work_sync(&adapter->ptp_tx_work);
+- igc_ptp_tx_timeout(adapter);
+- }
++ if (!adapter->ptp_tx_skb)
++ goto unlock;
++
++ if (time_is_after_jiffies(adapter->ptp_tx_start + IGC_PTP_TX_TIMEOUT))
++ goto unlock;
++
++ igc_ptp_tx_timeout(adapter);
++
++unlock:
++ spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags);
+ }
+
+ /**
+@@ -361,6 +361,8 @@ void igc_ptp_tx_hang(struct igc_adapter *adapter)
+ * If we were asked to do hardware stamping and such a time stamp is
+ * available, then it must have been for this skb here because we only
+ * allow only one such packet into the queue.
++ *
++ * Context: Expects adapter->ptp_tx_lock to be held by caller.
+ */
+ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter)
+ {
+@@ -396,13 +398,7 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter)
+ shhwtstamps.hwtstamp =
+ ktime_add_ns(shhwtstamps.hwtstamp, adjust);
+
+- /* Clear the lock early before calling skb_tstamp_tx so that
+- * applications are not woken up before the lock bit is clear. We use
+- * a copy of the skb pointer to ensure other threads can't change it
+- * while we're notifying the stack.
+- */
+ adapter->ptp_tx_skb = NULL;
+- clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
+
+ /* Notify the stack and free the skb after we've unlocked */
+ skb_tstamp_tx(skb, &shhwtstamps);
+@@ -413,24 +409,33 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter)
+ * igc_ptp_tx_work
+ * @work: pointer to work struct
+ *
+- * This work function polls the TSYNCTXCTL valid bit to determine when a
+- * timestamp has been taken for the current stored skb.
++ * This work function checks the TSYNCTXCTL valid bit to determine when
++ * a timestamp has been taken for the current stored skb.
+ */
+ static void igc_ptp_tx_work(struct work_struct *work)
+ {
+ struct igc_adapter *adapter = container_of(work, struct igc_adapter,
+ ptp_tx_work);
+ struct igc_hw *hw = &adapter->hw;
++ unsigned long flags;
+ u32 tsynctxctl;
+
+- if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state))
+- return;
++ spin_lock_irqsave(&adapter->ptp_tx_lock, flags);
++
++ if (!adapter->ptp_tx_skb)
++ goto unlock;
+
+ tsynctxctl = rd32(IGC_TSYNCTXCTL);
+- if (WARN_ON_ONCE(!(tsynctxctl & IGC_TSYNCTXCTL_TXTT_0)))
+- return;
++ tsynctxctl &= IGC_TSYNCTXCTL_TXTT_0;
++ if (!tsynctxctl) {
++ WARN_ONCE(1, "Received a TSTAMP interrupt but no TSTAMP is ready.\n");
++ goto unlock;
++ }
+
+ igc_ptp_tx_hwtstamp(adapter);
++
++unlock:
++ spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags);
+ }
+
+ /**
+@@ -506,6 +511,7 @@ void igc_ptp_init(struct igc_adapter *adapter)
+ return;
+ }
+
++ spin_lock_init(&adapter->ptp_tx_lock);
+ spin_lock_init(&adapter->tmreg_lock);
+ INIT_WORK(&adapter->ptp_tx_work, igc_ptp_tx_work);
+
+@@ -559,7 +565,6 @@ void igc_ptp_suspend(struct igc_adapter *adapter)
+ cancel_work_sync(&adapter->ptp_tx_work);
+ dev_kfree_skb_any(adapter->ptp_tx_skb);
+ adapter->ptp_tx_skb = NULL;
+- clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
+
+ if (pci_device_is_present(adapter->pdev))
+ igc_ptp_time_save(adapter);
+--
+2.39.2
+
--- /dev/null
+From 902948244674474fb1ecb33d17916f973ac5922a 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 96ecb7d254037..1c403e8a8044c 100644
+--- a/security/integrity/ima/ima_policy.c
++++ b/security/integrity/ima/ima_policy.c
+@@ -628,6 +628,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
+ * @keyring: the keyring name, if given, to be used to check in the policy.
+@@ -1515,7 +1516,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 19d4b60d5c5bda29e11d0b30ba63f9e2d4e02760 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 4cc4e8ff42b33..ad035c342cd3b 100644
+--- a/drivers/input/misc/adxl34x.c
++++ b/drivers/input/misc/adxl34x.c
+@@ -811,8 +811,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 58984b34d65b9013dfb335f8a1cfb0de5b425dae 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 79d7fa710a714..54002d1a446b7 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 c50c6223c860ea3db19e35ba7a1898ee59debb07 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 0a5b5ff597c6f..ab09d110760ec 100644
+--- a/drivers/net/ipvlan/ipvlan_core.c
++++ b/drivers/net/ipvlan/ipvlan_core.c
+@@ -586,7 +586,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:
+@@ -612,7 +613,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);
+@@ -624,7 +626,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 258d14bec79a9e559ecef460edeb5f3999b9e30e 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 efa0e7b662390f48bb0e5debb82d7fef482bb4ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 10:35:51 +0100
+Subject: irqchip/jcore-aic: Kill use of irq_create_strict_mappings()
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit 5f8b938bd790cff6542c7fe3c1495c71f89fef1b ]
+
+irq_create_strict_mappings() is a poor way to allow the use of
+a linear IRQ domain as a legacy one. Let's be upfront about it.
+
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20210406093557.1073423-4-maz@kernel.org
+Stable-dep-of: 4848229494a3 ("irqchip/jcore-aic: Fix missing allocation of IRQ descriptors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-jcore-aic.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/irqchip/irq-jcore-aic.c b/drivers/irqchip/irq-jcore-aic.c
+index 033bccb41455c..5f47d8ee4ae39 100644
+--- a/drivers/irqchip/irq-jcore-aic.c
++++ b/drivers/irqchip/irq-jcore-aic.c
+@@ -100,11 +100,11 @@ static int __init aic_irq_of_init(struct device_node *node,
+ jcore_aic.irq_unmask = noop;
+ jcore_aic.name = "AIC";
+
+- domain = irq_domain_add_linear(node, dom_sz, &jcore_aic_irqdomain_ops,
++ domain = irq_domain_add_legacy(node, dom_sz - min_irq, min_irq, min_irq,
++ &jcore_aic_irqdomain_ops,
+ &jcore_aic);
+ if (!domain)
+ return -ENOMEM;
+- irq_create_strict_mappings(domain, min_irq, min_irq, dom_sz - min_irq);
+
+ return 0;
+ }
+--
+2.39.2
+
--- /dev/null
+From a3c57e8fa7590ab2a1e2641d13d77717cdcaaa2d 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 762df6108c589..473dc04591b8e 100644
+--- a/kernel/kcsan/core.c
++++ b/kernel/kcsan/core.c
+@@ -1035,7 +1035,9 @@ EXPORT_SYMBOL(__tsan_init);
+ 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 38f86974676b88696f3161d2486f2bdf5643603f 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 7a8104d489971..3a37fc62dc95f 100644
+--- a/kernel/kexec_core.c
++++ b/kernel/kexec_core.c
+@@ -1029,6 +1029,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;
+@@ -1040,9 +1041,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 d67c1b8520fd7e6fe7cfdb78a8167e2c331ef6c6 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 4cf250031f0f0..352ae837e0317 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 8a7a9f3fa7e6f0c1bec40f4048358a1cde9714d0 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 72b251110c4d7..1c389b0f5499a 100644
+--- a/tools/lib/bpf/bpf_helpers.h
++++ b/tools/lib/bpf/bpf_helpers.h
+@@ -42,16 +42,21 @@
+ /*
+ * Helper macro 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
+
+ /*
+ * Helper macro to throw a compilation error if __bpf_unreachable() gets
+--
+2.39.2
+
--- /dev/null
+From 386c7b4d579af23dfe234fa1e78bda68e7be6c6f 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 20afc0aec1778..f843ade442dec 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;
+
+@@ -1365,6 +1358,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 4d9e559b8c3eb9360636faa593edb329d07e5d68 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 01680029f0de5..32a917e5103a6 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -751,8 +751,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;
+@@ -1346,9 +1354,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 && unlikely(test_bit(Blocked, &rdev->flags))) {
+--
+2.39.2
+
--- /dev/null
+From e0aca2e91cd72aa9a8d67e78a15980205ecb955e 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 6a0459f9fafbc..01680029f0de5 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -3037,7 +3037,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;
+
+@@ -3049,11 +3048,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;
+ }
+@@ -3069,8 +3067,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
+@@ -3193,11 +3189,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 b30b16a728ee79acd711c60e324c2cfa423aaaeb 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 1553c2495841b..204838a6d443e 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -3890,8 +3890,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)
+@@ -3903,7 +3904,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 fc949584cca57f4a65bcdce6230955bbdb8fdf22 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 204838a6d443e..bbf39abc32b79 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -4574,6 +4574,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 8692fe93f831a0e5f8228bfa5adfa0fa6acbae89 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 f43ba69fbb3e3..2daae2e0cb19e 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 12e8019e683678656271e29ed55e4a1cfad6473a 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 dd06c18495eb6..0e37c6a5ee36c 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 2bcc8583f77d3deb5d937e1ca59308218e4c4aa1 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 887035893510b..2a8999efe50a0 100644
+--- a/arch/mips/boot/dts/ingenic/ci20.dts
++++ b/arch/mips/boot/dts/ingenic/ci20.dts
+@@ -185,16 +185,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 {
+@@ -205,21 +208,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 139b3b094ac79bfb59b7ee0a3d6b28b1c28227e3 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 75f5bfbf2c375..887035893510b 100644
+--- a/arch/mips/boot/dts/ingenic/ci20.dts
++++ b/arch/mips/boot/dts/ingenic/ci20.dts
+@@ -180,59 +180,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.
+@@ -246,7 +236,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 c38e49be2a238e8f490e00b93265dd7220445a14 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 2a8999efe50a0..9839daca65d53 100644
+--- a/arch/mips/boot/dts/ingenic/ci20.dts
++++ b/arch/mips/boot/dts/ingenic/ci20.dts
+@@ -183,8 +183,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 d7d20f8a4d21a09c843d64bb378fc2c9741e849a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jul 2021 18:09:56 -0700
+Subject: mm: rename p4d_page_vaddr to p4d_pgtable and make it return pud_t *
+
+From: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+
+[ Upstream commit dc4875f0e791de554bdc45aa1dbd6e45e107e50f ]
+
+No functional change in this patch.
+
+[aneesh.kumar@linux.ibm.com: m68k build error reported by kernel robot]
+ Link: https://lkml.kernel.org/r/87tulxnb2v.fsf@linux.ibm.com
+
+Link: https://lkml.kernel.org/r/20210615110859.320299-2-aneesh.kumar@linux.ibm.com
+Link: https://lore.kernel.org/linuxppc-dev/CAHk-=wi+J+iodze9FtjM3Zi4j4OeS+qqbKxME9QN4roxPEXH9Q@mail.gmail.com/
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Joel Fernandes <joel@joelfernandes.org>
+Cc: Kalesh Singh <kaleshsingh@google.com>
+Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Nicholas Piggin <npiggin@gmail.com>
+Cc: Stephen Rothwell <sfr@canb.auug.org.au>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: 0da90af431ab ("powerpc/book3s64/mm: Fix DirectMap stats in /proc/meminfo")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/pgtable.h | 4 ++--
+ arch/ia64/include/asm/pgtable.h | 2 +-
+ arch/mips/include/asm/pgtable-64.h | 4 ++--
+ arch/powerpc/include/asm/book3s/64/pgtable.h | 5 ++++-
+ arch/powerpc/include/asm/nohash/64/pgtable-4k.h | 6 +++++-
+ arch/powerpc/mm/book3s64/radix_pgtable.c | 2 +-
+ arch/powerpc/mm/pgtable_64.c | 2 +-
+ arch/sparc/include/asm/pgtable_64.h | 4 ++--
+ arch/x86/include/asm/pgtable.h | 4 ++--
+ arch/x86/mm/init_64.c | 4 ++--
+ include/asm-generic/pgtable-nop4d.h | 2 +-
+ include/asm-generic/pgtable-nopud.h | 2 +-
+ include/linux/pgtable.h | 2 +-
+ 13 files changed, 25 insertions(+), 18 deletions(-)
+
+diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
+index 3635d48ada17d..4eedfd784cf63 100644
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -694,9 +694,9 @@ static inline phys_addr_t p4d_page_paddr(p4d_t p4d)
+ return __p4d_to_phys(p4d);
+ }
+
+-static inline unsigned long p4d_page_vaddr(p4d_t p4d)
++static inline pud_t *p4d_pgtable(p4d_t p4d)
+ {
+- return (unsigned long)__va(p4d_page_paddr(p4d));
++ return (pud_t *)__va(p4d_page_paddr(p4d));
+ }
+
+ /* Find an entry in the frst-level page table. */
+diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h
+index fd92792d148b4..6e5c387566573 100644
+--- a/arch/ia64/include/asm/pgtable.h
++++ b/arch/ia64/include/asm/pgtable.h
+@@ -287,7 +287,7 @@ extern unsigned long VMALLOC_END;
+ #define p4d_bad(p4d) (!ia64_phys_addr_valid(p4d_val(p4d)))
+ #define p4d_present(p4d) (p4d_val(p4d) != 0UL)
+ #define p4d_clear(p4dp) (p4d_val(*(p4dp)) = 0UL)
+-#define p4d_page_vaddr(p4d) ((unsigned long) __va(p4d_val(p4d) & _PFN_MASK))
++#define p4d_pgtable(p4d) ((pud_t *) __va(p4d_val(p4d) & _PFN_MASK))
+ #define p4d_page(p4d) virt_to_page((p4d_val(p4d) + PAGE_OFFSET))
+ #endif
+
+diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
+index ab305453e90f8..b865edff2670e 100644
+--- a/arch/mips/include/asm/pgtable-64.h
++++ b/arch/mips/include/asm/pgtable-64.h
+@@ -210,9 +210,9 @@ static inline void p4d_clear(p4d_t *p4dp)
+ p4d_val(*p4dp) = (unsigned long)invalid_pud_table;
+ }
+
+-static inline unsigned long p4d_page_vaddr(p4d_t p4d)
++static inline pud_t *p4d_pgtable(p4d_t p4d)
+ {
+- return p4d_val(p4d);
++ return (pud_t *)p4d_val(p4d);
+ }
+
+ #define p4d_phys(p4d) virt_to_phys((void *)p4d_val(p4d))
+diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
+index 5ebf6450f6dad..2b4af824bdc55 100644
+--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
++++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
+@@ -1030,7 +1030,10 @@ extern struct page *p4d_page(p4d_t p4d);
+ /* Pointers in the page table tree are physical addresses */
+ #define __pgtable_ptr_val(ptr) __pa(ptr)
+
+-#define p4d_page_vaddr(p4d) __va(p4d_val(p4d) & ~P4D_MASKED_BITS)
++static inline pud_t *p4d_pgtable(p4d_t p4d)
++{
++ return (pud_t *)__va(p4d_val(p4d) & ~P4D_MASKED_BITS);
++}
+
+ static inline pmd_t *pud_pgtable(pud_t pud)
+ {
+diff --git a/arch/powerpc/include/asm/nohash/64/pgtable-4k.h b/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
+index fe2f4c9acd9ed..10f5cf444d72a 100644
+--- a/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
++++ b/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
+@@ -56,10 +56,14 @@
+ #define p4d_none(p4d) (!p4d_val(p4d))
+ #define p4d_bad(p4d) (p4d_val(p4d) == 0)
+ #define p4d_present(p4d) (p4d_val(p4d) != 0)
+-#define p4d_page_vaddr(p4d) (p4d_val(p4d) & ~P4D_MASKED_BITS)
+
+ #ifndef __ASSEMBLY__
+
++static inline pud_t *p4d_pgtable(p4d_t p4d)
++{
++ return (pud_t *) (p4d_val(p4d) & ~P4D_MASKED_BITS);
++}
++
+ static inline void p4d_clear(p4d_t *p4dp)
+ {
+ *p4dp = __p4d(0);
+diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
+index 605c770dd8191..44239e0acf8ea 100644
+--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
++++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
+@@ -898,7 +898,7 @@ static void __meminit remove_pagetable(unsigned long start, unsigned long end)
+ continue;
+ }
+
+- pud_base = (pud_t *)p4d_page_vaddr(*p4d);
++ pud_base = p4d_pgtable(*p4d);
+ remove_pud_table(pud_base, addr, next);
+ free_pud_table(pud_base, p4d);
+ }
+diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
+index bd0d903196d98..175aabf101e87 100644
+--- a/arch/powerpc/mm/pgtable_64.c
++++ b/arch/powerpc/mm/pgtable_64.c
+@@ -106,7 +106,7 @@ struct page *p4d_page(p4d_t p4d)
+ VM_WARN_ON(!p4d_huge(p4d));
+ return pte_page(p4d_pte(p4d));
+ }
+- return virt_to_page(p4d_page_vaddr(p4d));
++ return virt_to_page(p4d_pgtable(p4d));
+ }
+ #endif
+
+diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
+index cac02ac301f13..5a1efd600f770 100644
+--- a/arch/sparc/include/asm/pgtable_64.h
++++ b/arch/sparc/include/asm/pgtable_64.h
+@@ -860,8 +860,8 @@ static inline pmd_t *pud_pgtable(pud_t pud)
+ #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL)
+ #define pud_present(pud) (pud_val(pud) != 0U)
+ #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL)
+-#define p4d_page_vaddr(p4d) \
+- ((unsigned long) __va(p4d_val(p4d)))
++#define p4d_pgtable(p4d) \
++ ((pud_t *) __va(p4d_val(p4d)))
+ #define p4d_present(p4d) (p4d_val(p4d) != 0U)
+ #define p4d_clear(p4dp) (p4d_val(*(p4dp)) = 0UL)
+
+diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
+index a90f6d02fb961..9bacde3ff514a 100644
+--- a/arch/x86/include/asm/pgtable.h
++++ b/arch/x86/include/asm/pgtable.h
+@@ -906,9 +906,9 @@ static inline int p4d_present(p4d_t p4d)
+ return p4d_flags(p4d) & _PAGE_PRESENT;
+ }
+
+-static inline unsigned long p4d_page_vaddr(p4d_t p4d)
++static inline pud_t *p4d_pgtable(p4d_t p4d)
+ {
+- return (unsigned long)__va(p4d_val(p4d) & p4d_pfn_mask(p4d));
++ return (pud_t *)__va(p4d_val(p4d) & p4d_pfn_mask(p4d));
+ }
+
+ /*
+diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
+index 20951ab522a1d..acf4e50c5988b 100644
+--- a/arch/x86/mm/init_64.c
++++ b/arch/x86/mm/init_64.c
+@@ -193,8 +193,8 @@ static void sync_global_pgds_l4(unsigned long start, unsigned long end)
+ spin_lock(pgt_lock);
+
+ if (!p4d_none(*p4d_ref) && !p4d_none(*p4d))
+- BUG_ON(p4d_page_vaddr(*p4d)
+- != p4d_page_vaddr(*p4d_ref));
++ BUG_ON(p4d_pgtable(*p4d)
++ != p4d_pgtable(*p4d_ref));
+
+ if (p4d_none(*p4d))
+ set_p4d(p4d, *p4d_ref);
+diff --git a/include/asm-generic/pgtable-nop4d.h b/include/asm-generic/pgtable-nop4d.h
+index ce2cbb3c380ff..2f1d0aad645cf 100644
+--- a/include/asm-generic/pgtable-nop4d.h
++++ b/include/asm-generic/pgtable-nop4d.h
+@@ -42,7 +42,7 @@ static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address)
+ #define __p4d(x) ((p4d_t) { __pgd(x) })
+
+ #define pgd_page(pgd) (p4d_page((p4d_t){ pgd }))
+-#define pgd_page_vaddr(pgd) (p4d_page_vaddr((p4d_t){ pgd }))
++#define pgd_page_vaddr(pgd) ((unsigned long)(p4d_pgtable((p4d_t){ pgd })))
+
+ /*
+ * allocating and freeing a p4d is trivial: the 1-entry p4d is
+diff --git a/include/asm-generic/pgtable-nopud.h b/include/asm-generic/pgtable-nopud.h
+index 7cbd15f70bf55..eb70c6d7ceff2 100644
+--- a/include/asm-generic/pgtable-nopud.h
++++ b/include/asm-generic/pgtable-nopud.h
+@@ -49,7 +49,7 @@ static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)
+ #define __pud(x) ((pud_t) { __p4d(x) })
+
+ #define p4d_page(p4d) (pud_page((pud_t){ p4d }))
+-#define p4d_page_vaddr(p4d) (pud_pgtable((pud_t){ p4d }))
++#define p4d_pgtable(p4d) ((pud_t *)(pud_pgtable((pud_t){ p4d })))
+
+ /*
+ * allocating and freeing a pud is trivial: the 1-entry pud is
+diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
+index f8570799bc263..f924468d84ec4 100644
+--- a/include/linux/pgtable.h
++++ b/include/linux/pgtable.h
+@@ -97,7 +97,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
+ #ifndef pud_offset
+ static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)
+ {
+- return (pud_t *)p4d_page_vaddr(*p4d) + pud_index(address);
++ return p4d_pgtable(*p4d) + pud_index(address);
+ }
+ #define pud_offset pud_offset
+ #endif
+--
+2.39.2
+
--- /dev/null
+From 26e3fe5c3e6d486b886f903750f2b4a422c2e14a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jul 2021 18:09:53 -0700
+Subject: mm: rename pud_page_vaddr to pud_pgtable and make it return pmd_t *
+
+From: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+
+[ Upstream commit 9cf6fa2458443118b84090aa1bf7a3630b5940e8 ]
+
+No functional change in this patch.
+
+[aneesh.kumar@linux.ibm.com: fix]
+ Link: https://lkml.kernel.org/r/87wnqtnb60.fsf@linux.ibm.com
+[sfr@canb.auug.org.au: another fix]
+ Link: https://lkml.kernel.org/r/20210619134410.89559-1-aneesh.kumar@linux.ibm.com
+
+Link: https://lkml.kernel.org/r/20210615110859.320299-1-aneesh.kumar@linux.ibm.com
+Link: https://lore.kernel.org/linuxppc-dev/CAHk-=wi+J+iodze9FtjM3Zi4j4OeS+qqbKxME9QN4roxPEXH9Q@mail.gmail.com/
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Joel Fernandes <joel@joelfernandes.org>
+Cc: Kalesh Singh <kaleshsingh@google.com>
+Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Nicholas Piggin <npiggin@gmail.com>
+Cc: Stephen Rothwell <sfr@canb.auug.org.au>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: 0da90af431ab ("powerpc/book3s64/mm: Fix DirectMap stats in /proc/meminfo")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/alpha/include/asm/pgtable.h | 8 +++++---
+ arch/arm/include/asm/pgtable-3level.h | 2 +-
+ arch/arm64/include/asm/pgtable.h | 4 ++--
+ arch/ia64/include/asm/pgtable.h | 2 +-
+ arch/m68k/include/asm/motorola_pgtable.h | 2 +-
+ arch/mips/include/asm/pgtable-64.h | 4 ++--
+ arch/parisc/include/asm/pgtable.h | 4 ++--
+ arch/powerpc/include/asm/book3s/64/pgtable.h | 6 +++++-
+ arch/powerpc/include/asm/nohash/64/pgtable.h | 6 +++++-
+ arch/powerpc/mm/book3s64/radix_pgtable.c | 4 ++--
+ arch/powerpc/mm/pgtable_64.c | 2 +-
+ arch/riscv/include/asm/pgtable-64.h | 4 ++--
+ arch/sh/include/asm/pgtable-3level.h | 4 ++--
+ arch/sparc/include/asm/pgtable_32.h | 6 +++---
+ arch/sparc/include/asm/pgtable_64.h | 6 +++---
+ arch/um/include/asm/pgtable-3level.h | 2 +-
+ arch/x86/include/asm/pgtable.h | 4 ++--
+ arch/x86/mm/pat/set_memory.c | 4 ++--
+ arch/x86/mm/pgtable.c | 2 +-
+ include/asm-generic/pgtable-nopmd.h | 2 +-
+ include/asm-generic/pgtable-nopud.h | 2 +-
+ include/linux/pgtable.h | 2 +-
+ 22 files changed, 46 insertions(+), 36 deletions(-)
+
+diff --git a/arch/alpha/include/asm/pgtable.h b/arch/alpha/include/asm/pgtable.h
+index 660b14ce13179..12c120e436a24 100644
+--- a/arch/alpha/include/asm/pgtable.h
++++ b/arch/alpha/include/asm/pgtable.h
+@@ -241,8 +241,10 @@ pmd_page_vaddr(pmd_t pmd)
+ #define pud_page(pud) (mem_map + ((pud_val(pud) & _PFN_MASK) >> 32))
+ #endif
+
+-extern inline unsigned long pud_page_vaddr(pud_t pgd)
+-{ return PAGE_OFFSET + ((pud_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
++extern inline pmd_t *pud_pgtable(pud_t pgd)
++{
++ return (pmd_t *)(PAGE_OFFSET + ((pud_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)));
++}
+
+ extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
+ extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_VALID; }
+@@ -292,7 +294,7 @@ extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; retu
+ /* Find an entry in the second-level page table.. */
+ extern inline pmd_t * pmd_offset(pud_t * dir, unsigned long address)
+ {
+- pmd_t *ret = (pmd_t *) pud_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
++ pmd_t *ret = pud_pgtable(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
+ smp_rmb(); /* see above */
+ return ret;
+ }
+diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
+index 2b85d175e9996..4487aea88477d 100644
+--- a/arch/arm/include/asm/pgtable-3level.h
++++ b/arch/arm/include/asm/pgtable-3level.h
+@@ -130,7 +130,7 @@
+ flush_pmd_entry(pudp); \
+ } while (0)
+
+-static inline pmd_t *pud_page_vaddr(pud_t pud)
++static inline pmd_t *pud_pgtable(pud_t pud)
+ {
+ return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK);
+ }
+diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
+index 3f74db7b0a31d..3635d48ada17d 100644
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -633,9 +633,9 @@ static inline phys_addr_t pud_page_paddr(pud_t pud)
+ return __pud_to_phys(pud);
+ }
+
+-static inline unsigned long pud_page_vaddr(pud_t pud)
++static inline pmd_t *pud_pgtable(pud_t pud)
+ {
+- return (unsigned long)__va(pud_page_paddr(pud));
++ return (pmd_t *)__va(pud_page_paddr(pud));
+ }
+
+ /* Find an entry in the second-level page table. */
+diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h
+index 9f64fdfbf2750..fd92792d148b4 100644
+--- a/arch/ia64/include/asm/pgtable.h
++++ b/arch/ia64/include/asm/pgtable.h
+@@ -279,7 +279,7 @@ extern unsigned long VMALLOC_END;
+ #define pud_bad(pud) (!ia64_phys_addr_valid(pud_val(pud)))
+ #define pud_present(pud) (pud_val(pud) != 0UL)
+ #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL)
+-#define pud_page_vaddr(pud) ((unsigned long) __va(pud_val(pud) & _PFN_MASK))
++#define pud_pgtable(pud) ((pmd_t *) __va(pud_val(pud) & _PFN_MASK))
+ #define pud_page(pud) virt_to_page((pud_val(pud) + PAGE_OFFSET))
+
+ #if CONFIG_PGTABLE_LEVELS == 4
+diff --git a/arch/m68k/include/asm/motorola_pgtable.h b/arch/m68k/include/asm/motorola_pgtable.h
+index 8076467eff4b0..956c80874f98b 100644
+--- a/arch/m68k/include/asm/motorola_pgtable.h
++++ b/arch/m68k/include/asm/motorola_pgtable.h
+@@ -129,7 +129,7 @@ static inline void pud_set(pud_t *pudp, pmd_t *pmdp)
+
+ #define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK))
+ #define pmd_page_vaddr(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK))
+-#define pud_page_vaddr(pud) ((unsigned long)__va(pud_val(pud) & _TABLE_MASK))
++#define pud_pgtable(pud) ((pmd_t *)__va(pud_val(pud) & _TABLE_MASK))
+
+
+ #define pte_none(pte) (!pte_val(pte))
+diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
+index 1e7d6ce9d8d62..ab305453e90f8 100644
+--- a/arch/mips/include/asm/pgtable-64.h
++++ b/arch/mips/include/asm/pgtable-64.h
+@@ -314,9 +314,9 @@ static inline void pud_clear(pud_t *pudp)
+ #endif
+
+ #ifndef __PAGETABLE_PMD_FOLDED
+-static inline unsigned long pud_page_vaddr(pud_t pud)
++static inline pmd_t *pud_pgtable(pud_t pud)
+ {
+- return pud_val(pud);
++ return (pmd_t *)pud_val(pud);
+ }
+ #define pud_phys(pud) virt_to_phys((void *)pud_val(pud))
+ #define pud_page(pud) (pfn_to_page(pud_phys(pud) >> PAGE_SHIFT))
+diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
+index 8964798b8274e..ade591927cbff 100644
+--- a/arch/parisc/include/asm/pgtable.h
++++ b/arch/parisc/include/asm/pgtable.h
+@@ -330,8 +330,8 @@ static inline void pmd_clear(pmd_t *pmd) {
+
+
+ #if CONFIG_PGTABLE_LEVELS == 3
+-#define pud_page_vaddr(pud) ((unsigned long) __va(pud_address(pud)))
+-#define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud))
++#define pud_pgtable(pud) ((pmd_t *) __va(pud_address(pud)))
++#define pud_page(pud) virt_to_page((void *)pud_pgtable(pud))
+
+ /* For 64 bit we have three level tables */
+
+diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
+index 71e2c524f1eea..5ebf6450f6dad 100644
+--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
++++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
+@@ -1030,9 +1030,13 @@ extern struct page *p4d_page(p4d_t p4d);
+ /* Pointers in the page table tree are physical addresses */
+ #define __pgtable_ptr_val(ptr) __pa(ptr)
+
+-#define pud_page_vaddr(pud) __va(pud_val(pud) & ~PUD_MASKED_BITS)
+ #define p4d_page_vaddr(p4d) __va(p4d_val(p4d) & ~P4D_MASKED_BITS)
+
++static inline pmd_t *pud_pgtable(pud_t pud)
++{
++ return (pmd_t *)__va(pud_val(pud) & ~PUD_MASKED_BITS);
++}
++
+ #define pte_ERROR(e) \
+ pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+ #define pmd_ERROR(e) \
+diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h
+index 1eacff0fff029..a4d475c0fc2c0 100644
+--- a/arch/powerpc/include/asm/nohash/64/pgtable.h
++++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
+@@ -164,7 +164,11 @@ static inline void pud_clear(pud_t *pudp)
+ #define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \
+ || (pud_val(pud) & PUD_BAD_BITS))
+ #define pud_present(pud) (pud_val(pud) != 0)
+-#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS)
++
++static inline pmd_t *pud_pgtable(pud_t pud)
++{
++ return (pmd_t *)(pud_val(pud) & ~PUD_MASKED_BITS);
++}
+
+ extern struct page *pud_page(pud_t pud);
+
+diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
+index 5f0a2fa611fa2..605c770dd8191 100644
+--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
++++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
+@@ -864,7 +864,7 @@ static void __meminit remove_pud_table(pud_t *pud_start, unsigned long addr,
+ continue;
+ }
+
+- pmd_base = (pmd_t *)pud_page_vaddr(*pud);
++ pmd_base = pud_pgtable(*pud);
+ remove_pmd_table(pmd_base, addr, next);
+ free_pmd_table(pmd_base, pud);
+ }
+@@ -1156,7 +1156,7 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr)
+ pmd_t *pmd;
+ int i;
+
+- pmd = (pmd_t *)pud_page_vaddr(*pud);
++ pmd = pud_pgtable(*pud);
+ pud_clear(pud);
+
+ flush_tlb_kernel_range(addr, addr + PUD_SIZE);
+diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
+index aefc2bfdf1049..bd0d903196d98 100644
+--- a/arch/powerpc/mm/pgtable_64.c
++++ b/arch/powerpc/mm/pgtable_64.c
+@@ -117,7 +117,7 @@ struct page *pud_page(pud_t pud)
+ VM_WARN_ON(!pud_huge(pud));
+ return pte_page(pud_pte(pud));
+ }
+- return virt_to_page(pud_page_vaddr(pud));
++ return virt_to_page(pud_pgtable(pud));
+ }
+
+ /*
+diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
+index f3b0da64c6c8f..0e863f3f7187a 100644
+--- a/arch/riscv/include/asm/pgtable-64.h
++++ b/arch/riscv/include/asm/pgtable-64.h
+@@ -60,9 +60,9 @@ static inline void pud_clear(pud_t *pudp)
+ set_pud(pudp, __pud(0));
+ }
+
+-static inline unsigned long pud_page_vaddr(pud_t pud)
++static inline pmd_t *pud_pgtable(pud_t pud)
+ {
+- return (unsigned long)pfn_to_virt(pud_val(pud) >> _PAGE_PFN_SHIFT);
++ return (pmd_t *)pfn_to_virt(pud_val(pud) >> _PAGE_PFN_SHIFT);
+ }
+
+ static inline struct page *pud_page(pud_t pud)
+diff --git a/arch/sh/include/asm/pgtable-3level.h b/arch/sh/include/asm/pgtable-3level.h
+index 82d74472dfcda..56bf35c2f29c2 100644
+--- a/arch/sh/include/asm/pgtable-3level.h
++++ b/arch/sh/include/asm/pgtable-3level.h
+@@ -32,9 +32,9 @@ typedef struct { unsigned long long pmd; } pmd_t;
+ #define pmd_val(x) ((x).pmd)
+ #define __pmd(x) ((pmd_t) { (x) } )
+
+-static inline unsigned long pud_page_vaddr(pud_t pud)
++static inline pmd_t *pud_pgtable(pud_t pud)
+ {
+- return pud_val(pud);
++ return (pmd_t *)pud_val(pud);
+ }
+
+ /* only used by the stubbed out hugetlb gup code, should never be called */
+diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
+index 632cdb959542c..7d1d10a8fd937 100644
+--- a/arch/sparc/include/asm/pgtable_32.h
++++ b/arch/sparc/include/asm/pgtable_32.h
+@@ -152,13 +152,13 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
+ return (unsigned long)__nocache_va(v << 4);
+ }
+
+-static inline unsigned long pud_page_vaddr(pud_t pud)
++static inline pmd_t *pud_pgtable(pud_t pud)
+ {
+ if (srmmu_device_memory(pud_val(pud))) {
+- return ~0;
++ return (pmd_t *)~0;
+ } else {
+ unsigned long v = pud_val(pud) & SRMMU_PTD_PMASK;
+- return (unsigned long)__nocache_va(v << 4);
++ return (pmd_t *)__nocache_va(v << 4);
+ }
+ }
+
+diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
+index 7ef6affa105e4..cac02ac301f13 100644
+--- a/arch/sparc/include/asm/pgtable_64.h
++++ b/arch/sparc/include/asm/pgtable_64.h
+@@ -845,18 +845,18 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
+ return ((unsigned long) __va(pfn << PAGE_SHIFT));
+ }
+
+-static inline unsigned long pud_page_vaddr(pud_t pud)
++static inline pmd_t *pud_pgtable(pud_t pud)
+ {
+ pte_t pte = __pte(pud_val(pud));
+ unsigned long pfn;
+
+ pfn = pte_pfn(pte);
+
+- return ((unsigned long) __va(pfn << PAGE_SHIFT));
++ return ((pmd_t *) __va(pfn << PAGE_SHIFT));
+ }
+
+ #define pmd_page(pmd) virt_to_page((void *)pmd_page_vaddr(pmd))
+-#define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud))
++#define pud_page(pud) virt_to_page((void *)pud_pgtable(pud))
+ #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL)
+ #define pud_present(pud) (pud_val(pud) != 0U)
+ #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL)
+diff --git a/arch/um/include/asm/pgtable-3level.h b/arch/um/include/asm/pgtable-3level.h
+index 7e6a4180db9d3..091bff319ccdf 100644
+--- a/arch/um/include/asm/pgtable-3level.h
++++ b/arch/um/include/asm/pgtable-3level.h
+@@ -84,7 +84,7 @@ static inline void pud_clear (pud_t *pud)
+ }
+
+ #define pud_page(pud) phys_to_page(pud_val(pud) & PAGE_MASK)
+-#define pud_page_vaddr(pud) ((unsigned long) __va(pud_val(pud) & PAGE_MASK))
++#define pud_pgtable(pud) ((pmd_t *) __va(pud_val(pud) & PAGE_MASK))
+
+ static inline unsigned long pte_pfn(pte_t pte)
+ {
+diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
+index 87de9f2d71cf2..a90f6d02fb961 100644
+--- a/arch/x86/include/asm/pgtable.h
++++ b/arch/x86/include/asm/pgtable.h
+@@ -865,9 +865,9 @@ static inline int pud_present(pud_t pud)
+ return pud_flags(pud) & _PAGE_PRESENT;
+ }
+
+-static inline unsigned long pud_page_vaddr(pud_t pud)
++static inline pmd_t *pud_pgtable(pud_t pud)
+ {
+- return (unsigned long)__va(pud_val(pud) & pud_pfn_mask(pud));
++ return (pmd_t *)__va(pud_val(pud) & pud_pfn_mask(pud));
+ }
+
+ /*
+diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
+index 40baa90e74f4c..217dda690ed82 100644
+--- a/arch/x86/mm/pat/set_memory.c
++++ b/arch/x86/mm/pat/set_memory.c
+@@ -1126,7 +1126,7 @@ static void __unmap_pmd_range(pud_t *pud, pmd_t *pmd,
+ unsigned long start, unsigned long end)
+ {
+ if (unmap_pte_range(pmd, start, end))
+- if (try_to_free_pmd_page((pmd_t *)pud_page_vaddr(*pud)))
++ if (try_to_free_pmd_page(pud_pgtable(*pud)))
+ pud_clear(pud);
+ }
+
+@@ -1170,7 +1170,7 @@ static void unmap_pmd_range(pud_t *pud, unsigned long start, unsigned long end)
+ * Try again to free the PMD page if haven't succeeded above.
+ */
+ if (!pud_none(*pud))
+- if (try_to_free_pmd_page((pmd_t *)pud_page_vaddr(*pud)))
++ if (try_to_free_pmd_page(pud_pgtable(*pud)))
+ pud_clear(pud);
+ }
+
+diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
+index f6a9e2e366425..204b25ee26f0b 100644
+--- a/arch/x86/mm/pgtable.c
++++ b/arch/x86/mm/pgtable.c
+@@ -805,7 +805,7 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr)
+ pte_t *pte;
+ int i;
+
+- pmd = (pmd_t *)pud_page_vaddr(*pud);
++ pmd = pud_pgtable(*pud);
+ pmd_sv = (pmd_t *)__get_free_page(GFP_KERNEL);
+ if (!pmd_sv)
+ return 0;
+diff --git a/include/asm-generic/pgtable-nopmd.h b/include/asm-generic/pgtable-nopmd.h
+index 3e13acd019aef..10789cf51d160 100644
+--- a/include/asm-generic/pgtable-nopmd.h
++++ b/include/asm-generic/pgtable-nopmd.h
+@@ -51,7 +51,7 @@ static inline pmd_t * pmd_offset(pud_t * pud, unsigned long address)
+ #define __pmd(x) ((pmd_t) { __pud(x) } )
+
+ #define pud_page(pud) (pmd_page((pmd_t){ pud }))
+-#define pud_page_vaddr(pud) (pmd_page_vaddr((pmd_t){ pud }))
++#define pud_pgtable(pud) ((pmd_t *)(pmd_page_vaddr((pmd_t){ pud })))
+
+ /*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+diff --git a/include/asm-generic/pgtable-nopud.h b/include/asm-generic/pgtable-nopud.h
+index a9d751fbda9e8..7cbd15f70bf55 100644
+--- a/include/asm-generic/pgtable-nopud.h
++++ b/include/asm-generic/pgtable-nopud.h
+@@ -49,7 +49,7 @@ static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)
+ #define __pud(x) ((pud_t) { __p4d(x) })
+
+ #define p4d_page(p4d) (pud_page((pud_t){ p4d }))
+-#define p4d_page_vaddr(p4d) (pud_page_vaddr((pud_t){ p4d }))
++#define p4d_page_vaddr(p4d) (pud_pgtable((pud_t){ p4d }))
+
+ /*
+ * allocating and freeing a pud is trivial: the 1-entry pud is
+diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
+index 9def1ac19546b..f8570799bc263 100644
+--- a/include/linux/pgtable.h
++++ b/include/linux/pgtable.h
+@@ -89,7 +89,7 @@ static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address)
+ #ifndef pmd_offset
+ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
+ {
+- return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address);
++ return pud_pgtable(*pud) + pmd_index(address);
+ }
+ #define pmd_offset pmd_offset
+ #endif
+--
+2.39.2
+
--- /dev/null
+From 49cae101ae3245339a6016a083ed7291abbc1451 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 fb7f75fa786bc..78ac98cfa02d4 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -1621,7 +1621,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 4d41f6c42cbf57d879aaa1f9bb13cbb0fc070709 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 9216eae798ff2..fb7f75fa786bc 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -1796,12 +1796,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:
+@@ -1811,6 +1819,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 d83fda93ca383efde0bfc570f4b558d4c0cfc8ee 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 e48742760fec8..9216eae798ff2 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -1313,6 +1313,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)
+@@ -1795,12 +1799,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 d69737b2a1ccd25cefd56e5bfa156dedd5a002e8 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 3d91baf2e55aa..9d362283196aa 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -2009,6 +2009,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.
+@@ -2055,11 +2060,6 @@ static int axienet_probe(struct platform_device *pdev)
+ lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
+ lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
+
+- /* 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 a08cdc8ae945d27aa6d522b7c960234a238cee05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Sep 2021 11:10:37 -0700
+Subject: net: create netdev->dev_addr assignment helpers
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 48eab831ae8b9f7002a533fa4235eed63ea1f1a3 ]
+
+Recent work on converting address list to a tree made it obvious
+we need an abstraction around writing netdev->dev_addr. Without
+such abstraction updating the main device address is invisible
+to the core.
+
+Introduce a number of helpers which for now just wrap memcpy()
+but in the future can make necessary changes to the address
+tree.
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 391af06a02e7 ("wifi: wl3501_cs: Fix an error handling path in wl3501_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/etherdevice.h | 12 ++++++++++++
+ include/linux/netdevice.h | 18 ++++++++++++++++++
+ 2 files changed, 30 insertions(+)
+
+diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
+index 99209f50915f4..b060514bf25d2 100644
+--- a/include/linux/etherdevice.h
++++ b/include/linux/etherdevice.h
+@@ -299,6 +299,18 @@ static inline void ether_addr_copy(u8 *dst, const u8 *src)
+ #endif
+ }
+
++/**
++ * eth_hw_addr_set - Assign Ethernet address to a net_device
++ * @dev: pointer to net_device structure
++ * @addr: address to assign
++ *
++ * Assign given address to the net_device, addr_assign_type is not changed.
++ */
++static inline void eth_hw_addr_set(struct net_device *dev, const u8 *addr)
++{
++ ether_addr_copy(dev->dev_addr, addr);
++}
++
+ /**
+ * eth_hw_addr_inherit - Copy dev_addr from another net_device
+ * @dst: pointer to net_device to copy dev_addr to
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 8f03cc42bd43f..302abfc2a1f63 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -4474,6 +4474,24 @@ void __hw_addr_unsync_dev(struct netdev_hw_addr_list *list,
+ void __hw_addr_init(struct netdev_hw_addr_list *list);
+
+ /* Functions used for device addresses handling */
++static inline void
++__dev_addr_set(struct net_device *dev, const u8 *addr, size_t len)
++{
++ memcpy(dev->dev_addr, addr, len);
++}
++
++static inline void dev_addr_set(struct net_device *dev, const u8 *addr)
++{
++ __dev_addr_set(dev, addr, dev->addr_len);
++}
++
++static inline void
++dev_addr_mod(struct net_device *dev, unsigned int offset,
++ const u8 *addr, size_t len)
++{
++ memcpy(&dev->dev_addr[offset], addr, len);
++}
++
+ int dev_addr_add(struct net_device *dev, const unsigned char *addr,
+ unsigned char addr_type);
+ int dev_addr_del(struct net_device *dev, const unsigned char *addr,
+--
+2.39.2
+
--- /dev/null
+From 6ad39efca516d26f976bb2fd3da622dae913c90a 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 d49d4bf2e37c8..a81893bc06ce8 100644
+--- a/net/nfc/llcp.h
++++ b/net/nfc/llcp.h
+@@ -202,7 +202,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 bb9f40563ff63..5b8754ae7d3af 100644
+--- a/net/nfc/llcp_commands.c
++++ b/net/nfc/llcp_commands.c
+@@ -361,6 +361,7 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
+ struct sk_buff *skb;
+ struct nfc_llcp_local *local;
+ u16 size = 0;
++ int err;
+
+ pr_debug("Sending SYMM\n");
+
+@@ -372,8 +373,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);
+
+@@ -383,8 +386,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 fd43e75abd948..ddfd159f64e13 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);
+
+@@ -143,7 +145,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);
+
+@@ -171,7 +173,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);
+ }
+@@ -284,12 +285,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;
+ }
+@@ -610,12 +632,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;
+@@ -632,12 +657,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)
+@@ -1527,6 +1556,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;
+ }
+
+@@ -1543,6 +1574,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,
+@@ -1568,6 +1601,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)
+@@ -1618,7 +1653,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 fdf0856182c65..6e1fba2084930 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,
+@@ -181,7 +181,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);
+@@ -698,22 +698,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;
+@@ -759,11 +759,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 e0e1168655118..1c5b3ce1e8b16 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 2764756c66513a7ad3cada7cacb3b8ad87d9e0bd 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 de66406c50572..83e9a4d019c16 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -5254,12 +5254,6 @@ int 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 582ea97f8965d0aa2efdc6253c88ddaeaa017515 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 94001eb51ffe4..a9ae292e932ae 100644
+--- a/net/netfilter/nf_conntrack_proto_dccp.c
++++ b/net/netfilter/nf_conntrack_proto_dccp.c
+@@ -431,9 +431,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) {
+@@ -458,10 +468,17 @@ 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->net, state->pf,
+@@ -469,24 +486,53 @@ static bool dccp_error(const struct dccp_hdr *dh,
+ 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))
+ return -NF_ACCEPT;
+--
+2.39.2
+
--- /dev/null
+From bbde13d2663de15196c26ab572f08c068588f449 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 78fd9122b70c7..751df19fe0f8a 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 2d09f0cb4979acb6cce6b687bb1673fd0729bac9 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 03e7f7581559d..1fb5c535537c1 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1934,6 +1934,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 9b013d052a722..4e00c6e2cb431 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -2175,13 +2175,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 c2632c8e99a95f686c18e6515fddac171942fe23 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 888ff53c8144d..d3c03ebf06a5b 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -3889,7 +3889,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))
+@@ -3903,10 +3903,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;
+ }
+@@ -3918,7 +3918,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 ca8f00bc3f157df70df3480903b22ea7f584dbc5 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 99c869d8d3044..9737c3229c12a 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1602,6 +1602,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;
+
+@@ -1611,12 +1612,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 18de3171ec2270d9e520a5325a8dfdf385729ed2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jul 2021 16:41:59 +0200
+Subject: nfc: constify several pointers to u8, char and sk_buff
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+[ Upstream commit 3df40eb3a2ea58bf404a38f15a7a2768e4762cb0 ]
+
+Several functions receive pointers to u8, char or sk_buff but do not
+modify the contents so make them const. This allows doing the same for
+local variables and in total makes the code a little bit safer.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 0d9b41daa590 ("nfc: llcp: fix possible use of uninitialized variable in nfc_llcp_send_connect()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/nfc/nfc.h | 4 ++--
+ net/nfc/core.c | 4 ++--
+ net/nfc/hci/llc_shdlc.c | 10 ++++-----
+ net/nfc/llcp.h | 8 +++----
+ net/nfc/llcp_commands.c | 46 ++++++++++++++++++++++-------------------
+ net/nfc/llcp_core.c | 44 +++++++++++++++++++++------------------
+ net/nfc/nfc.h | 2 +-
+ 7 files changed, 63 insertions(+), 55 deletions(-)
+
+diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h
+index 2cd3a261bcbcf..32890e43f06cc 100644
+--- a/include/net/nfc/nfc.h
++++ b/include/net/nfc/nfc.h
+@@ -266,7 +266,7 @@ struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk,
+ struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp);
+
+ int nfc_set_remote_general_bytes(struct nfc_dev *dev,
+- u8 *gt, u8 gt_len);
++ const u8 *gt, u8 gt_len);
+ u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len);
+
+ int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name,
+@@ -280,7 +280,7 @@ int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx,
+ u8 comm_mode, u8 rf_mode);
+
+ int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode,
+- u8 *gb, size_t gb_len);
++ const u8 *gb, size_t gb_len);
+ int nfc_tm_deactivated(struct nfc_dev *dev);
+ int nfc_tm_data_received(struct nfc_dev *dev, struct sk_buff *skb);
+
+diff --git a/net/nfc/core.c b/net/nfc/core.c
+index 2ef56366bd5fe..10a3d740d1553 100644
+--- a/net/nfc/core.c
++++ b/net/nfc/core.c
+@@ -634,7 +634,7 @@ int nfc_disable_se(struct nfc_dev *dev, u32 se_idx)
+ return rc;
+ }
+
+-int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len)
++int nfc_set_remote_general_bytes(struct nfc_dev *dev, const u8 *gb, u8 gb_len)
+ {
+ pr_debug("dev_name=%s gb_len=%d\n", dev_name(&dev->dev), gb_len);
+
+@@ -663,7 +663,7 @@ int nfc_tm_data_received(struct nfc_dev *dev, struct sk_buff *skb)
+ EXPORT_SYMBOL(nfc_tm_data_received);
+
+ int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode,
+- u8 *gb, size_t gb_len)
++ const u8 *gb, size_t gb_len)
+ {
+ int rc;
+
+diff --git a/net/nfc/hci/llc_shdlc.c b/net/nfc/hci/llc_shdlc.c
+index 0eb4ddc056e78..02909e3e91ef1 100644
+--- a/net/nfc/hci/llc_shdlc.c
++++ b/net/nfc/hci/llc_shdlc.c
+@@ -123,7 +123,7 @@ static bool llc_shdlc_x_lteq_y_lt_z(int x, int y, int z)
+ return ((y >= x) || (y < z)) ? true : false;
+ }
+
+-static struct sk_buff *llc_shdlc_alloc_skb(struct llc_shdlc *shdlc,
++static struct sk_buff *llc_shdlc_alloc_skb(const struct llc_shdlc *shdlc,
+ int payload_len)
+ {
+ struct sk_buff *skb;
+@@ -137,7 +137,7 @@ static struct sk_buff *llc_shdlc_alloc_skb(struct llc_shdlc *shdlc,
+ }
+
+ /* immediately sends an S frame. */
+-static int llc_shdlc_send_s_frame(struct llc_shdlc *shdlc,
++static int llc_shdlc_send_s_frame(const struct llc_shdlc *shdlc,
+ enum sframe_type sframe_type, int nr)
+ {
+ int r;
+@@ -159,7 +159,7 @@ static int llc_shdlc_send_s_frame(struct llc_shdlc *shdlc,
+ }
+
+ /* immediately sends an U frame. skb may contain optional payload */
+-static int llc_shdlc_send_u_frame(struct llc_shdlc *shdlc,
++static int llc_shdlc_send_u_frame(const struct llc_shdlc *shdlc,
+ struct sk_buff *skb,
+ enum uframe_modifier uframe_modifier)
+ {
+@@ -361,7 +361,7 @@ static void llc_shdlc_connect_complete(struct llc_shdlc *shdlc, int r)
+ wake_up(shdlc->connect_wq);
+ }
+
+-static int llc_shdlc_connect_initiate(struct llc_shdlc *shdlc)
++static int llc_shdlc_connect_initiate(const struct llc_shdlc *shdlc)
+ {
+ struct sk_buff *skb;
+
+@@ -377,7 +377,7 @@ static int llc_shdlc_connect_initiate(struct llc_shdlc *shdlc)
+ return llc_shdlc_send_u_frame(shdlc, skb, U_FRAME_RSET);
+ }
+
+-static int llc_shdlc_connect_send_ua(struct llc_shdlc *shdlc)
++static int llc_shdlc_connect_send_ua(const struct llc_shdlc *shdlc)
+ {
+ struct sk_buff *skb;
+
+diff --git a/net/nfc/llcp.h b/net/nfc/llcp.h
+index 97853c9cefc70..d49d4bf2e37c8 100644
+--- a/net/nfc/llcp.h
++++ b/net/nfc/llcp.h
+@@ -221,15 +221,15 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *sk, struct socket *newsock);
+
+ /* TLV API */
+ int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
+- u8 *tlv_array, u16 tlv_array_len);
++ const u8 *tlv_array, u16 tlv_array_len);
+ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
+- u8 *tlv_array, u16 tlv_array_len);
++ const u8 *tlv_array, u16 tlv_array_len);
+
+ /* Commands API */
+ void nfc_llcp_recv(void *data, struct sk_buff *skb, int err);
+-u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length);
++u8 *nfc_llcp_build_tlv(u8 type, const u8 *value, u8 value_length, u8 *tlv_length);
+ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdres_tlv(u8 tid, u8 sap);
+-struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri,
++struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, const char *uri,
+ size_t uri_len);
+ void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp);
+ void nfc_llcp_free_sdp_tlv_list(struct hlist_head *sdp_head);
+diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
+index 475061c79c442..3c4172a5aeb5e 100644
+--- a/net/nfc/llcp_commands.c
++++ b/net/nfc/llcp_commands.c
+@@ -15,7 +15,7 @@
+ #include "nfc.h"
+ #include "llcp.h"
+
+-static u8 llcp_tlv_length[LLCP_TLV_MAX] = {
++static const u8 llcp_tlv_length[LLCP_TLV_MAX] = {
+ 0,
+ 1, /* VERSION */
+ 2, /* MIUX */
+@@ -29,7 +29,7 @@ static u8 llcp_tlv_length[LLCP_TLV_MAX] = {
+
+ };
+
+-static u8 llcp_tlv8(u8 *tlv, u8 type)
++static u8 llcp_tlv8(const u8 *tlv, u8 type)
+ {
+ if (tlv[0] != type || tlv[1] != llcp_tlv_length[tlv[0]])
+ return 0;
+@@ -37,7 +37,7 @@ static u8 llcp_tlv8(u8 *tlv, u8 type)
+ return tlv[2];
+ }
+
+-static u16 llcp_tlv16(u8 *tlv, u8 type)
++static u16 llcp_tlv16(const u8 *tlv, u8 type)
+ {
+ if (tlv[0] != type || tlv[1] != llcp_tlv_length[tlv[0]])
+ return 0;
+@@ -46,37 +46,37 @@ static u16 llcp_tlv16(u8 *tlv, u8 type)
+ }
+
+
+-static u8 llcp_tlv_version(u8 *tlv)
++static u8 llcp_tlv_version(const u8 *tlv)
+ {
+ return llcp_tlv8(tlv, LLCP_TLV_VERSION);
+ }
+
+-static u16 llcp_tlv_miux(u8 *tlv)
++static u16 llcp_tlv_miux(const u8 *tlv)
+ {
+ return llcp_tlv16(tlv, LLCP_TLV_MIUX) & 0x7ff;
+ }
+
+-static u16 llcp_tlv_wks(u8 *tlv)
++static u16 llcp_tlv_wks(const u8 *tlv)
+ {
+ return llcp_tlv16(tlv, LLCP_TLV_WKS);
+ }
+
+-static u16 llcp_tlv_lto(u8 *tlv)
++static u16 llcp_tlv_lto(const u8 *tlv)
+ {
+ return llcp_tlv8(tlv, LLCP_TLV_LTO);
+ }
+
+-static u8 llcp_tlv_opt(u8 *tlv)
++static u8 llcp_tlv_opt(const u8 *tlv)
+ {
+ return llcp_tlv8(tlv, LLCP_TLV_OPT);
+ }
+
+-static u8 llcp_tlv_rw(u8 *tlv)
++static u8 llcp_tlv_rw(const u8 *tlv)
+ {
+ return llcp_tlv8(tlv, LLCP_TLV_RW) & 0xf;
+ }
+
+-u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length)
++u8 *nfc_llcp_build_tlv(u8 type, const u8 *value, u8 value_length, u8 *tlv_length)
+ {
+ u8 *tlv, length;
+
+@@ -130,7 +130,7 @@ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdres_tlv(u8 tid, u8 sap)
+ return sdres;
+ }
+
+-struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri,
++struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, const char *uri,
+ size_t uri_len)
+ {
+ struct nfc_llcp_sdp_tlv *sdreq;
+@@ -190,9 +190,10 @@ void nfc_llcp_free_sdp_tlv_list(struct hlist_head *head)
+ }
+
+ int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
+- u8 *tlv_array, u16 tlv_array_len)
++ const u8 *tlv_array, u16 tlv_array_len)
+ {
+- u8 *tlv = tlv_array, type, length, offset = 0;
++ const u8 *tlv = tlv_array;
++ u8 type, length, offset = 0;
+
+ pr_debug("TLV array length %d\n", tlv_array_len);
+
+@@ -239,9 +240,10 @@ int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
+ }
+
+ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
+- u8 *tlv_array, u16 tlv_array_len)
++ const u8 *tlv_array, u16 tlv_array_len)
+ {
+- u8 *tlv = tlv_array, type, length, offset = 0;
++ const u8 *tlv = tlv_array;
++ u8 type, length, offset = 0;
+
+ pr_debug("TLV array length %d\n", tlv_array_len);
+
+@@ -295,7 +297,7 @@ static struct sk_buff *llcp_add_header(struct sk_buff *pdu,
+ return pdu;
+ }
+
+-static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv,
++static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, const u8 *tlv,
+ u8 tlv_length)
+ {
+ /* XXX Add an skb length check */
+@@ -389,9 +391,10 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
+ {
+ struct nfc_llcp_local *local;
+ struct sk_buff *skb;
+- u8 *service_name_tlv = NULL, service_name_tlv_length;
+- u8 *miux_tlv = NULL, miux_tlv_length;
+- u8 *rw_tlv = NULL, rw_tlv_length, rw;
++ 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;
+ int err;
+ u16 size = 0;
+ __be16 miux;
+@@ -465,8 +468,9 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock)
+ {
+ struct nfc_llcp_local *local;
+ struct sk_buff *skb;
+- u8 *miux_tlv = NULL, miux_tlv_length;
+- u8 *rw_tlv = NULL, rw_tlv_length, rw;
++ const u8 *miux_tlv = NULL;
++ const u8 *rw_tlv = NULL;
++ u8 miux_tlv_length, rw_tlv_length, rw;
+ int err;
+ u16 size = 0;
+ __be16 miux;
+diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
+index edadebb3efd2a..fd43e75abd948 100644
+--- a/net/nfc/llcp_core.c
++++ b/net/nfc/llcp_core.c
+@@ -302,7 +302,7 @@ static char *wks[] = {
+ "urn:nfc:sn:snep",
+ };
+
+-static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len)
++static int nfc_llcp_wks_sap(const char *service_name, size_t service_name_len)
+ {
+ int sap, num_wks;
+
+@@ -326,7 +326,7 @@ static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len)
+
+ static
+ struct nfc_llcp_sock *nfc_llcp_sock_from_sn(struct nfc_llcp_local *local,
+- u8 *sn, size_t sn_len)
++ const u8 *sn, size_t sn_len)
+ {
+ struct sock *sk;
+ struct nfc_llcp_sock *llcp_sock, *tmp_sock;
+@@ -523,7 +523,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local)
+ {
+ u8 *gb_cur, version, version_length;
+ u8 lto_length, wks_length, miux_length;
+- u8 *version_tlv = NULL, *lto_tlv = NULL,
++ const u8 *version_tlv = NULL, *lto_tlv = NULL,
+ *wks_tlv = NULL, *miux_tlv = NULL;
+ __be16 wks = cpu_to_be16(local->local_wks);
+ u8 gb_len = 0;
+@@ -613,7 +613,7 @@ u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len)
+ return local->gb;
+ }
+
+-int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len)
++int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len)
+ {
+ struct nfc_llcp_local *local;
+
+@@ -640,27 +640,27 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len)
+ local->remote_gb_len - 3);
+ }
+
+-static u8 nfc_llcp_dsap(struct sk_buff *pdu)
++static u8 nfc_llcp_dsap(const struct sk_buff *pdu)
+ {
+ return (pdu->data[0] & 0xfc) >> 2;
+ }
+
+-static u8 nfc_llcp_ptype(struct sk_buff *pdu)
++static u8 nfc_llcp_ptype(const struct sk_buff *pdu)
+ {
+ return ((pdu->data[0] & 0x03) << 2) | ((pdu->data[1] & 0xc0) >> 6);
+ }
+
+-static u8 nfc_llcp_ssap(struct sk_buff *pdu)
++static u8 nfc_llcp_ssap(const struct sk_buff *pdu)
+ {
+ return pdu->data[1] & 0x3f;
+ }
+
+-static u8 nfc_llcp_ns(struct sk_buff *pdu)
++static u8 nfc_llcp_ns(const struct sk_buff *pdu)
+ {
+ return pdu->data[2] >> 4;
+ }
+
+-static u8 nfc_llcp_nr(struct sk_buff *pdu)
++static u8 nfc_llcp_nr(const struct sk_buff *pdu)
+ {
+ return pdu->data[2] & 0xf;
+ }
+@@ -802,7 +802,7 @@ static struct nfc_llcp_sock *nfc_llcp_connecting_sock_get(struct nfc_llcp_local
+ }
+
+ static struct nfc_llcp_sock *nfc_llcp_sock_get_sn(struct nfc_llcp_local *local,
+- u8 *sn, size_t sn_len)
++ const u8 *sn, size_t sn_len)
+ {
+ struct nfc_llcp_sock *llcp_sock;
+
+@@ -816,9 +816,10 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get_sn(struct nfc_llcp_local *local,
+ return llcp_sock;
+ }
+
+-static u8 *nfc_llcp_connect_sn(struct sk_buff *skb, size_t *sn_len)
++static const u8 *nfc_llcp_connect_sn(const struct sk_buff *skb, size_t *sn_len)
+ {
+- u8 *tlv = &skb->data[2], type, length;
++ u8 type, length;
++ const u8 *tlv = &skb->data[2];
+ size_t tlv_array_len = skb->len - LLCP_HEADER_SIZE, offset = 0;
+
+ while (offset < tlv_array_len) {
+@@ -876,7 +877,7 @@ static void nfc_llcp_recv_ui(struct nfc_llcp_local *local,
+ }
+
+ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
+- struct sk_buff *skb)
++ const struct sk_buff *skb)
+ {
+ struct sock *new_sk, *parent;
+ struct nfc_llcp_sock *sock, *new_sock;
+@@ -894,7 +895,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
+ goto fail;
+ }
+ } else {
+- u8 *sn;
++ const u8 *sn;
+ size_t sn_len;
+
+ sn = nfc_llcp_connect_sn(skb, &sn_len);
+@@ -1113,7 +1114,7 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local,
+ }
+
+ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
+- struct sk_buff *skb)
++ const struct sk_buff *skb)
+ {
+ struct nfc_llcp_sock *llcp_sock;
+ struct sock *sk;
+@@ -1156,7 +1157,8 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
+ nfc_llcp_sock_put(llcp_sock);
+ }
+
+-static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb)
++static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
++ const struct sk_buff *skb)
+ {
+ struct nfc_llcp_sock *llcp_sock;
+ struct sock *sk;
+@@ -1189,7 +1191,8 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb)
+ nfc_llcp_sock_put(llcp_sock);
+ }
+
+-static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb)
++static void nfc_llcp_recv_dm(struct nfc_llcp_local *local,
++ const struct sk_buff *skb)
+ {
+ struct nfc_llcp_sock *llcp_sock;
+ struct sock *sk;
+@@ -1227,12 +1230,13 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb)
+ }
+
+ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
+- struct sk_buff *skb)
++ const struct sk_buff *skb)
+ {
+ struct nfc_llcp_sock *llcp_sock;
+- u8 dsap, ssap, *tlv, type, length, tid, sap;
++ u8 dsap, ssap, type, length, tid, sap;
++ const u8 *tlv;
+ u16 tlv_len, offset;
+- char *service_name;
++ const char *service_name;
+ size_t service_name_len;
+ struct nfc_llcp_sdp_tlv *sdp;
+ HLIST_HEAD(llc_sdres_list);
+diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h
+index 889fefd64e56b..de2ec66d7e83a 100644
+--- a/net/nfc/nfc.h
++++ b/net/nfc/nfc.h
+@@ -48,7 +48,7 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
+ u8 comm_mode, u8 rf_mode);
+ int nfc_llcp_register_device(struct nfc_dev *dev);
+ void nfc_llcp_unregister_device(struct nfc_dev *dev);
+-int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len);
++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);
+--
+2.39.2
+
--- /dev/null
+From 953865878bb11ed6b9f729717f012aa30be6ab61 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 3c4172a5aeb5e..bb9f40563ff63 100644
+--- a/net/nfc/llcp_commands.c
++++ b/net/nfc/llcp_commands.c
+@@ -394,7 +394,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 998b900982f58640594482f27569947d33e70a94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Mar 2022 20:25:19 +0100
+Subject: nfc: llcp: simplify llcp_sock_connect() error paths
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+[ Upstream commit ec10fd154d934cc4195da3cbd017a12817b41d51 ]
+
+The llcp_sock_connect() error paths were using a mixed way of central
+exit (goto) and cleanup
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 6709d4b7bc2e ("net: nfc: Fix use-after-free caused by nfc_llcp_find_local")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_sock.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index 0b93a17b9f11f..fdf0856182c65 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -712,10 +712,8 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
+ llcp_sock->local = nfc_llcp_local_get(local);
+ llcp_sock->ssap = nfc_llcp_get_local_ssap(local);
+ if (llcp_sock->ssap == LLCP_SAP_MAX) {
+- nfc_llcp_local_put(llcp_sock->local);
+- llcp_sock->local = NULL;
+ ret = -ENOMEM;
+- goto put_dev;
++ goto sock_llcp_put_local;
+ }
+
+ llcp_sock->reserved_ssap = llcp_sock->ssap;
+@@ -760,8 +758,11 @@ 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);
+ llcp_sock->local = NULL;
++ llcp_sock->dev = NULL;
+
+ put_dev:
+ nfc_put_device(dev);
+--
+2.39.2
+
--- /dev/null
+From 8fdf7a52857c304fa818cfe881d03e4577dbd0a2 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 bca5d1bdd79bd..b9567cc8698ed 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -926,6 +926,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 4b954ef1a2294dd5e09be30c5ffb49868f85aadf 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 e466c58f9ec4c..7ef3c87f8a23d 100644
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -475,6 +475,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c)
+ /* Restore timestamps on parent (best effort) */
+ ovl_set_timestamps(upperdir, &c->pstat);
+ ovl_dentry_set_upper_alias(c->dentry);
++ ovl_dentry_update_reval(c->dentry, upper);
+ }
+ }
+ inode_unlock(udir);
+@@ -762,6 +763,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 8ebd9f2b1c95b..a7021c87bfcb0 100644
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -266,8 +266,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 44118f0ab0b31..f981283177ecd 100644
+--- a/fs/overlayfs/export.c
++++ b/fs/overlayfs/export.c
+@@ -324,8 +324,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 092812c2f118a..ff5284b86bd56 100644
+--- a/fs/overlayfs/namei.c
++++ b/fs/overlayfs/namei.c
+@@ -1095,8 +1095,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 898de3bf884e4..26f91868fbdaf 100644
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -257,8 +257,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 e3cd5a00f880d..5d7df839902df 100644
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -1868,7 +1868,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 e8b14d2c180c6..060f9c99d9b33 100644
+--- a/fs/overlayfs/util.c
++++ b/fs/overlayfs/util.c
+@@ -90,14 +90,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 845dcb78132d571d50eab8c8634ee27e3fba36cf 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 4cc42ad2f6c52..550e1cdb473fa 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -1719,6 +1719,7 @@ static inline struct pci_dev *pci_get_class(unsigned int class,
+ #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 a2c77802943704838b8d41b060ca5af8e2387aee 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 ac0557a305aff..51da8ba67d216 100644
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -993,21 +993,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 */
+@@ -1015,7 +1018,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 7813ef36b6286c4bbe5203fbf6e761ab5bed682e 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 fb96d37a135c1..4d8d15ac51ef4 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 8bd23dfb062b88c2044b2b4aa4e6cd08c2a2808a 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 aefef1986201a..80cfea5d9f122 100644
+--- a/drivers/pci/controller/pci-ftpci100.c
++++ b/drivers/pci/controller/pci-ftpci100.c
+@@ -442,22 +442,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 76c408ea4d347b0ca5a0a1113a4723b6f82b121c 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 3195003f3d8632e1770a6f306d15c154a3b7e815 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 bb019e3839888..36061aaf026c8 100644
+--- a/drivers/perf/arm-cmn.c
++++ b/drivers/perf/arm-cmn.c
+@@ -1254,9 +1254,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);
+
+ /* We do at least know that a DTC's XP must be in that DTC's domain */
+ xp = arm_cmn_node_to_xp(dn);
+@@ -1303,7 +1304,7 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
+ dn->type = CMN_TYPE_RNI;
+ }
+
+- 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 e28c7b563899e05f44bbbc0213b34a0103b60b4e 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 609a941ae2963..fb3029495c23c 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>
+@@ -247,6 +248,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 8201231b1c9bdae247ab23e09a3a6e95869c717e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Nov 2021 08:14:08 +0200
+Subject: perf bench: Use unbuffered output when pipe/tee'ing to a file
+
+From: Sohaib Mohamed <sohaib.amhmd@gmail.com>
+
+[ Upstream commit f0a29c9647ff8bbb424641f79bc1894e83dec218 ]
+
+The output of 'perf bench' gets buffered when I pipe it to a file or to
+tee, in such a way that I can see it only at the end.
+
+E.g.
+
+ $ perf bench internals synthesize -t
+ < output comes out fine after each test run >
+
+ $ perf bench internals synthesize -t | tee file.txt
+ < output comes out only at the end of all tests >
+
+This patch resolves this issue for 'bench' and 'test' subcommands.
+
+See, also:
+
+ $ perf bench mem all | tee file.txt
+ $ perf bench sched all | tee file.txt
+ $ perf bench internals all -t | tee file.txt
+ $ perf bench internals all | tee file.txt
+
+Committer testing:
+
+It really gets staggered, i.e. outputs in bursts, when the buffer fills
+up and has to be drained to make up space for more output.
+
+Suggested-by: Riccardo Mancini <rickyman7@gmail.com>
+Signed-off-by: Sohaib Mohamed <sohaib.amhmd@gmail.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Acked-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Fabian Hemmer <copy@copy.sh>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: http://lore.kernel.org/lkml/20211119061409.78004-1-sohaib.amhmd@gmail.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 16203e9cd018 ("perf bench: Add missing setlocale() call to allow usage of %'d style formatting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-bench.c | 5 +++--
+ tools/perf/tests/builtin-test.c | 3 +++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
+index 62a7b7420a448..609a941ae2963 100644
+--- a/tools/perf/builtin-bench.c
++++ b/tools/perf/builtin-bench.c
+@@ -225,7 +225,6 @@ static void run_collection(struct collection *coll)
+ if (!bench->fn)
+ break;
+ printf("# Running %s/%s benchmark...\n", coll->name, bench->name);
+- fflush(stdout);
+
+ argv[1] = bench->name;
+ run_bench(coll->name, bench->name, bench->fn, 1, argv);
+@@ -246,6 +245,9 @@ int cmd_bench(int argc, const char **argv)
+ struct collection *coll;
+ int ret = 0;
+
++ /* Unbuffered output */
++ setvbuf(stdout, NULL, _IONBF, 0);
++
+ if (argc < 2) {
+ /* No collection specified. */
+ print_usage();
+@@ -299,7 +301,6 @@ int cmd_bench(int argc, const char **argv)
+
+ if (bench_format == BENCH_FORMAT_DEFAULT)
+ printf("# Running '%s/%s' benchmark:\n", coll->name, bench->name);
+- fflush(stdout);
+ ret = run_bench(coll->name, bench->name, bench->fn, argc-1, argv+1);
+ goto end;
+ }
+diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
+index 132bdb3e6c31a..73c911dd0c2ca 100644
+--- a/tools/perf/tests/builtin-test.c
++++ b/tools/perf/tests/builtin-test.c
+@@ -793,6 +793,9 @@ int cmd_test(int argc, const char **argv)
+ if (ret < 0)
+ return ret;
+
++ /* Unbuffered output */
++ setvbuf(stdout, NULL, _IONBF, 0);
++
+ argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0);
+ if (argc >= 1 && !strcmp(argv[0], "list"))
+ return perf_test__list(argc - 1, argv + 1);
+--
+2.39.2
+
--- /dev/null
+From afc9137bd4a179e2ec35946840e665b3ea36f5c4 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 f8a10d5148f6f..443374a77c8dc 100644
+--- a/tools/perf/util/dwarf-aux.c
++++ b/tools/perf/util/dwarf-aux.c
+@@ -1081,7 +1081,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 f5702368ee74168d7e8437fd0421f50a92c21bb8 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 52eba415928a3..afc955340f81c 100644
+--- a/arch/x86/events/amd/core.c
++++ b/arch/x86/events/amd/core.c
+@@ -364,7 +364,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))
+ return -EOPNOTSUPP;
+diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
+index 8a85658a24cc1..354d52e17ef55 100644
+--- a/arch/x86/events/amd/ibs.c
++++ b/arch/x86/events/amd/ibs.c
+@@ -202,7 +202,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
+@@ -211,25 +211,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) {
+@@ -255,22 +239,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 b9a7fd0a27e2d..a4e4bbb7795d3 100644
+--- a/arch/x86/include/asm/perf_event.h
++++ b/arch/x86/include/asm/perf_event.h
+@@ -412,8 +412,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 f50d14617f42085af74c4bf2ec8c0040a60641ce 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 5651714e527c5..85befbacb2a44 100644
+--- a/tools/perf/builtin-script.c
++++ b/tools/perf/builtin-script.c
+@@ -2146,6 +2146,9 @@ static int process_sample_event(struct perf_tool *tool,
+ return 0;
+ }
+
++// 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)
+ {
+@@ -2154,7 +2157,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)
+@@ -2164,14 +2166,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;
+ }
+ }
+
+@@ -2455,7 +2456,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 5b24663f20196fd75452e5152d8e1df6f9e97d49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Mar 2021 08:59:21 -0300
+Subject: perf script: Fixup 'struct evsel_script' method prefix
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit 297e69bfa4c7aa27259dd456af1377e868337043 ]
+
+They all operate on 'struct evsel_script' instances, so should be
+prefixed with evsel_script__, not with perf_evsel_script__.
+
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 36d3e4138e1b ("perf script: Fix allocation of evsel->priv related to per-event dump files")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-script.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
+index 5109d01619eed..5651714e527c5 100644
+--- a/tools/perf/builtin-script.c
++++ b/tools/perf/builtin-script.c
+@@ -295,8 +295,7 @@ static inline struct evsel_script *evsel_script(struct evsel *evsel)
+ return (struct evsel_script *)evsel->priv;
+ }
+
+-static struct evsel_script *perf_evsel_script__new(struct evsel *evsel,
+- struct perf_data *data)
++static struct evsel_script *evsel_script__new(struct evsel *evsel, struct perf_data *data)
+ {
+ struct evsel_script *es = zalloc(sizeof(*es));
+
+@@ -316,7 +315,7 @@ static struct evsel_script *perf_evsel_script__new(struct evsel *evsel,
+ return NULL;
+ }
+
+-static void perf_evsel_script__delete(struct evsel_script *es)
++static void evsel_script__delete(struct evsel_script *es)
+ {
+ zfree(&es->filename);
+ fclose(es->fp);
+@@ -324,7 +323,7 @@ static void perf_evsel_script__delete(struct evsel_script *es)
+ free(es);
+ }
+
+-static int perf_evsel_script__fprintf(struct evsel_script *es, FILE *fp)
++static int evsel_script__fprintf(struct evsel_script *es, FILE *fp)
+ {
+ struct stat st;
+
+@@ -2166,8 +2165,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
+
+ if (!evsel->priv) {
+ if (scr->per_event_dump) {
+- evsel->priv = perf_evsel_script__new(evsel,
+- scr->session->data);
++ evsel->priv = evsel_script__new(evsel, scr->session->data);
+ } else {
+ es = zalloc(sizeof(*es));
+ if (!es)
+@@ -2422,7 +2420,7 @@ static void perf_script__fclose_per_event_dump(struct perf_script *script)
+ evlist__for_each_entry(evlist, evsel) {
+ if (!evsel->priv)
+ break;
+- perf_evsel_script__delete(evsel->priv);
++ evsel_script__delete(evsel->priv);
+ evsel->priv = NULL;
+ }
+ }
+@@ -2442,7 +2440,7 @@ static int perf_script__fopen_per_event_dump(struct perf_script *script)
+ if (evsel->priv != NULL)
+ continue;
+
+- evsel->priv = perf_evsel_script__new(evsel, script->session->data);
++ evsel->priv = evsel_script__new(evsel, script->session->data);
+ if (evsel->priv == NULL)
+ goto out_err_fclose;
+ }
+@@ -2477,8 +2475,8 @@ static void perf_script__exit_per_event_dump_stats(struct perf_script *script)
+ evlist__for_each_entry(script->session->evlist, evsel) {
+ struct evsel_script *es = evsel->priv;
+
+- perf_evsel_script__fprintf(es, stdout);
+- perf_evsel_script__delete(es);
++ evsel_script__fprintf(es, stdout);
++ evsel_script__delete(es);
+ evsel->priv = NULL;
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From db07635fac6fc2c41c24cb46c3712f64503cf367 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 315a6c4d9ade0..bf8aa0ea35d1b 100644
+--- a/drivers/pinctrl/pinctrl-at91-pio4.c
++++ b/drivers/pinctrl/pinctrl-at91-pio4.c
+@@ -1083,6 +1083,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 c26e9bb0254a0a6a468fba391773407fc226511e 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 c7ae9f900b532..e3f49d0ed0298 100644
+--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+@@ -359,10 +359,8 @@ static int bcm2835_of_gpio_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 fcc2fa46d02b5b2033a4f0420c183a2e8168ca6d 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 2ed17cdf946d1..44caada37b71f 100644
+--- a/drivers/pinctrl/intel/pinctrl-cherryview.c
++++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
+@@ -945,11 +945,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;
+
+@@ -959,6 +954,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 6a6104aac6c8a023d4854fd70f10ddde3046bfbd 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 d0ba5459ce0b9..8a90f08c9682b 100644
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -2763,10 +2763,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 d15cf54b63c6091588114eab3a271062045e29df 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 d089627f2f2b4..6d12a724d2b6b 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 a832e611e3d16bdaa0233ebfcadc3325333fa81a 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 bc228725346b4..0e4b2c214a70a 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 1646808d354ce..6b68e5ed20812 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 631b33d7ac0c03998e8835c41fed91c3c870f3b8 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 44239e0acf8ea..3728c17de87e9 100644
+--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
++++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
+@@ -783,9 +783,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);
+@@ -807,13 +807,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;
+
+@@ -831,19 +834,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;
+
+@@ -861,16 +867,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;
+@@ -899,7 +909,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);
+ }
+
+@@ -922,7 +932,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 */
+@@ -958,7 +968,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 77ce992044466d4b35641b1f2fb12da039ba5fc4 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 386be136026e8..b76cd49d521b9 100644
+--- a/arch/powerpc/mm/init_64.c
++++ b/arch/powerpc/mm/init_64.c
+@@ -188,7 +188,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 b9fedeaff1af375340534c593f09910cf0453940 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 28aac933a4391..e3e52ff2cbf58 100644
+--- a/arch/powerpc/platforms/powernv/pci-sriov.c
++++ b/arch/powerpc/platforms/powernv/pci-sriov.c
+@@ -600,12 +600,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 253fd2f1c371d27fb17f253939ff6842e608b89f 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 184cb97c83bdd..b6183f1f4ebcf 100644
+--- a/fs/pstore/ram_core.c
++++ b/fs/pstore/ram_core.c
+@@ -577,6 +577,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 e112d9a2739ab59beb21f353942726227a2d643b 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 886e9959496fe..f98df826972c9 100644
+--- a/drivers/gpu/drm/radeon/ci_dpm.c
++++ b/drivers/gpu/drm/radeon/ci_dpm.c
+@@ -5541,6 +5541,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))
+@@ -5570,11 +5571,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,
+@@ -5614,6 +5619,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,
+@@ -5702,25 +5713,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 7548fc01e80b9606a4672a30186f437c97c092f0 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 74be0b6438fb3..dfc6172ffe1d2 100644
+--- a/kernel/rcu/rcuscale.c
++++ b/kernel/rcu/rcuscale.c
+@@ -470,89 +470,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
+@@ -572,20 +489,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.
+@@ -747,6 +650,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 1965bc7265d6f394a191236a6abb0745253b69d5 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 dfc6172ffe1d2..6c05365ed80fc 100644
+--- a/kernel/rcu/rcuscale.c
++++ b/kernel/rcu/rcuscale.c
+@@ -670,6 +670,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 46a475b7221c6553082f6cc77d500c0ff436faa5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Oct 2021 17:40:28 +0800
+Subject: rcuscale: Always log error message
+
+From: Li Zhijian <zhijianx.li@intel.com>
+
+[ Upstream commit 86e7ed1bd57d020e35d430542bf5d689c3200568 ]
+
+Unconditionally log messages corresponding to errors.
+
+Acked-by: Davidlohr Bueso <dbueso@suse.de>
+Signed-off-by: Li Zhijian <zhijianx.li@intel.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.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 | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c
+index 28bc688e2705c..4452c3c4060ce 100644
+--- a/kernel/rcu/rcuscale.c
++++ b/kernel/rcu/rcuscale.c
+@@ -49,8 +49,8 @@ MODULE_AUTHOR("Paul E. McKenney <paulmck@linux.ibm.com>");
+ pr_alert("%s" SCALE_FLAG " %s\n", scale_type, s)
+ #define VERBOSE_SCALEOUT_STRING(s) \
+ do { if (verbose) pr_alert("%s" SCALE_FLAG " %s\n", scale_type, s); } while (0)
+-#define VERBOSE_SCALEOUT_ERRSTRING(s) \
+- do { if (verbose) pr_alert("%s" SCALE_FLAG "!!! %s\n", scale_type, s); } while (0)
++#define SCALEOUT_ERRSTRING(s) \
++ pr_alert("%s" SCALE_FLAG "!!! %s\n", scale_type, s)
+
+ /*
+ * The intended use cases for the nreaders and nwriters module parameters
+@@ -484,11 +484,11 @@ rcu_scale_cleanup(void)
+ * during the mid-boot phase, so have to wait till the end.
+ */
+ if (rcu_gp_is_expedited() && !rcu_gp_is_normal() && !gp_exp)
+- VERBOSE_SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!");
++ SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!");
+ if (rcu_gp_is_normal() && gp_exp)
+- VERBOSE_SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!");
++ SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!");
+ if (gp_exp && gp_async)
+- VERBOSE_SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!");
++ SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!");
+
+ if (torture_cleanup_begin())
+ return;
+@@ -803,7 +803,7 @@ rcu_scale_init(void)
+ reader_tasks = kcalloc(nrealreaders, sizeof(reader_tasks[0]),
+ GFP_KERNEL);
+ if (reader_tasks == NULL) {
+- VERBOSE_SCALEOUT_ERRSTRING("out of memory");
++ SCALEOUT_ERRSTRING("out of memory");
+ firsterr = -ENOMEM;
+ goto unwind;
+ }
+@@ -823,7 +823,7 @@ rcu_scale_init(void)
+ kcalloc(nrealwriters, sizeof(*writer_n_durations),
+ GFP_KERNEL);
+ if (!writer_tasks || !writer_durations || !writer_n_durations) {
+- VERBOSE_SCALEOUT_ERRSTRING("out of memory");
++ SCALEOUT_ERRSTRING("out of memory");
+ firsterr = -ENOMEM;
+ goto unwind;
+ }
+--
+2.39.2
+
--- /dev/null
+From 591fd16b7111931d0aea43cd526dbc7f5978cce7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 18:37:08 +0800
+Subject: rcuscale: Console output claims too few grace periods
+
+From: Jiangong.Han <jiangong.han@windriver.com>
+
+[ Upstream commit 811192c5f24bfd7246ce9ce06f668d8c408bf39b ]
+
+The rcuscale console output claims N grace periods, numbered from zero
+to N, which means that there were really N+1 grace periods. The root
+cause of this bug is that rcu_scale_writer() stores the number of the
+last grace period (numbered from zero) into writer_n_durations[me]
+instead of the number of grace periods. This commit therefore assigns
+the actual number of grace periods to writer_n_durations[me], and also
+makes the corresponding adjustment to the loop outputting per-grace-period
+measurements.
+
+Sample of old console output:
+ rcu-scale: writer 0 gps: 133
+ ......
+ rcu-scale: 0 writer-duration: 0 44003961
+ rcu-scale: 0 writer-duration: 1 32003582
+ ......
+ rcu-scale: 0 writer-duration: 132 28004391
+ rcu-scale: 0 writer-duration: 133 27996410
+
+Sample of new console output:
+ rcu-scale: writer 0 gps: 134
+ ......
+ rcu-scale: 0 writer-duration: 0 44003961
+ rcu-scale: 0 writer-duration: 1 32003582
+ ......
+ rcu-scale: 0 writer-duration: 132 28004391
+ rcu-scale: 0 writer-duration: 133 27996410
+
+Signed-off-by: Jiangong.Han <jiangong.han@windriver.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.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 | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c
+index 2819b95479af9..28bc688e2705c 100644
+--- a/kernel/rcu/rcuscale.c
++++ b/kernel/rcu/rcuscale.c
+@@ -457,7 +457,7 @@ rcu_scale_writer(void *arg)
+ if (gp_async) {
+ cur_ops->gp_barrier();
+ }
+- writer_n_durations[me] = i_max;
++ writer_n_durations[me] = i_max + 1;
+ torture_kthread_stopping("rcu_scale_writer");
+ return 0;
+ }
+@@ -531,7 +531,7 @@ rcu_scale_cleanup(void)
+ wdpp = writer_durations[i];
+ if (!wdpp)
+ continue;
+- for (j = 0; j <= writer_n_durations[i]; j++) {
++ 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,
+--
+2.39.2
+
--- /dev/null
+From 63ca538c1874b5f0d7f97111cbbbfe36c54f4999 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 4452c3c4060ce..74be0b6438fb3 100644
+--- a/kernel/rcu/rcuscale.c
++++ b/kernel/rcu/rcuscale.c
+@@ -579,8 +579,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();
+@@ -693,8 +692,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 dfc2eaddd983d360db9f483b54cf845e9c2652de 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 212e5cd82d0db..2b0c3a86293cf 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -295,7 +295,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;
+@@ -304,6 +305,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;
+@@ -363,9 +365,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;
+ }
+
+@@ -379,6 +382,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);
+@@ -397,7 +401,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:
+@@ -425,6 +430,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 3ee401205cdbd0e0df8cf108fddde7c8915376e3 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 9ef6aea29ff16..bdde44286d562 100644
+--- a/drivers/infiniband/hw/bnxt_re/main.c
++++ b/drivers/infiniband/hw/bnxt_re/main.c
+@@ -294,15 +294,21 @@ static void bnxt_re_start_irq(void *handle, struct bnxt_msix_entry *ent)
+ for (indx = 0; indx < rdev->num_msix; indx++)
+ rdev->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 b26a89187a192..9eba4b39c7032 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+@@ -404,6 +404,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);
+@@ -411,11 +414,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)
+@@ -454,8 +456,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 5759027914b01..a111e880276f3 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -633,6 +633,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);
+@@ -641,10 +645,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)
+@@ -690,8 +692,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 ea89cf3200bd215b64fb9fc34b4f171d99e261ad 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 d6b7c0d1f6766..d44b6a5c90b57 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+@@ -2732,11 +2732,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 7ec0bd906934d3631bbbbe26874757ac88fe75df 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 9eba4b39c7032..b4b180652c0a0 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+@@ -1603,7 +1603,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;
+@@ -1627,8 +1627,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,
+@@ -2058,7 +2056,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);
+
+@@ -2099,7 +2097,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 f6be9a1bbeaeb6557e6767d81235b3cdac5ed7b4 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 bdde44286d562..8a618769915d5 100644
+--- a/drivers/infiniband/hw/bnxt_re/main.c
++++ b/drivers/infiniband/hw/bnxt_re/main.c
+@@ -1191,12 +1191,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];
+
+@@ -1214,7 +1208,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 6a28dec9e8c7d7ef91a213d4cd4889c604e765e8 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 b4b180652c0a0..d6b7c0d1f6766 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+@@ -417,6 +417,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;
+ }
+
+@@ -443,6 +445,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)
+@@ -454,9 +457,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;
+ }
+@@ -470,7 +478,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 f50784405e27e..667f93d90045e 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+@@ -469,7 +469,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 a111e880276f3..4836bc433f53c 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -646,6 +646,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;
+ }
+
+@@ -678,9 +680,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;
+@@ -690,15 +694,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 6953f4e53dd20..7df7170c80e06 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+@@ -172,6 +172,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 54c09a12193dd1084d4576dd27888ec66110c85a 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 4836bc433f53c..212e5cd82d0db 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
+@@ -595,7 +595,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 53f496bf76935e63babb5d74abce170baabbc63e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 17:29:55 +0800
+Subject: RDMA/hns: Clean the hardware related code for HEM
+
+From: Xi Wang <wangxi11@huawei.com>
+
+[ Upstream commit 68e11a6086b10e1a88d2b2c8432299f595db748d ]
+
+Move the HIP06 related code to the hw v1 source file for HEM.
+
+Link: https://lore.kernel.org/r/1621589395-2435-6-git-send-email-liweihang@huawei.com
+Signed-off-by: Xi Wang <wangxi11@huawei.com>
+Signed-off-by: Weihang Li <liweihang@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: cf5b608fb0e3 ("RDMA/hns: Fix hns_roce_table_get return value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_device.h | 2 -
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 82 +--------------------
+ drivers/infiniband/hw/hns/hns_roce_hem.h | 9 +--
+ drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 77 +++++++++++++++++++
+ drivers/infiniband/hw/hns/hns_roce_hw_v1.h | 5 ++
+ 5 files changed, 85 insertions(+), 90 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
+index d9aa7424d2902..09b5e4935c2ca 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_device.h
++++ b/drivers/infiniband/hw/hns/hns_roce_device.h
+@@ -46,8 +46,6 @@
+
+ #define HNS_ROCE_IB_MIN_SQ_STRIDE 6
+
+-#define HNS_ROCE_BA_SIZE (32 * 4096)
+-
+ #define BA_BYTE_LEN 8
+
+ /* Hardware specification only for v1 engine */
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index 831e9476c6284..3c3187f22216a 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -36,9 +36,6 @@
+ #include "hns_roce_hem.h"
+ #include "hns_roce_common.h"
+
+-#define DMA_ADDR_T_SHIFT 12
+-#define BT_BA_SHIFT 32
+-
+ #define HEM_INDEX_BUF BIT(0)
+ #define HEM_INDEX_L0 BIT(1)
+ #define HEM_INDEX_L1 BIT(2)
+@@ -326,81 +323,6 @@ void hns_roce_free_hem(struct hns_roce_dev *hr_dev, struct hns_roce_hem *hem)
+ kfree(hem);
+ }
+
+-static int hns_roce_set_hem(struct hns_roce_dev *hr_dev,
+- struct hns_roce_hem_table *table, unsigned long obj)
+-{
+- spinlock_t *lock = &hr_dev->bt_cmd_lock;
+- struct device *dev = hr_dev->dev;
+- struct hns_roce_hem_iter iter;
+- void __iomem *bt_cmd;
+- __le32 bt_cmd_val[2];
+- __le32 bt_cmd_h = 0;
+- unsigned long flags;
+- __le32 bt_cmd_l;
+- int ret = 0;
+- u64 bt_ba;
+- long end;
+-
+- /* Find the HEM(Hardware Entry Memory) entry */
+- unsigned long i = (obj & (table->num_obj - 1)) /
+- (table->table_chunk_size / table->obj_size);
+-
+- switch (table->type) {
+- case HEM_TYPE_QPC:
+- case HEM_TYPE_MTPT:
+- case HEM_TYPE_CQC:
+- case HEM_TYPE_SRQC:
+- roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+- ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, table->type);
+- break;
+- default:
+- return ret;
+- }
+-
+- roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M,
+- ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj);
+- roce_set_bit(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0);
+- roce_set_bit(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1);
+-
+- /* Currently iter only a chunk */
+- for (hns_roce_hem_first(table->hem[i], &iter);
+- !hns_roce_hem_last(&iter); hns_roce_hem_next(&iter)) {
+- bt_ba = hns_roce_hem_addr(&iter) >> DMA_ADDR_T_SHIFT;
+-
+- spin_lock_irqsave(lock, flags);
+-
+- bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG;
+-
+- end = HW_SYNC_TIMEOUT_MSECS;
+- while (end > 0) {
+- if (!(readl(bt_cmd) >> BT_CMD_SYNC_SHIFT))
+- break;
+-
+- mdelay(HW_SYNC_SLEEP_TIME_INTERVAL);
+- end -= HW_SYNC_SLEEP_TIME_INTERVAL;
+- }
+-
+- if (end <= 0) {
+- dev_err(dev, "Write bt_cmd err,hw_sync is not zero.\n");
+- spin_unlock_irqrestore(lock, flags);
+- return -EBUSY;
+- }
+-
+- bt_cmd_l = cpu_to_le32(bt_ba);
+- roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M,
+- ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S,
+- bt_ba >> BT_BA_SHIFT);
+-
+- bt_cmd_val[0] = bt_cmd_l;
+- bt_cmd_val[1] = bt_cmd_h;
+- hns_roce_write64_k(bt_cmd_val,
+- hr_dev->reg_base + ROCEE_BT_CMD_L_REG);
+- spin_unlock_irqrestore(lock, flags);
+- }
+-
+- return ret;
+-}
+-
+ static int calc_hem_config(struct hns_roce_dev *hr_dev,
+ struct hns_roce_hem_table *table, unsigned long obj,
+ struct hns_roce_hem_mhop *mhop,
+@@ -666,7 +588,7 @@ int hns_roce_table_get(struct hns_roce_dev *hr_dev,
+ }
+
+ /* Set HEM base address(128K/page, pa) to Hardware */
+- if (hns_roce_set_hem(hr_dev, table, obj)) {
++ if (hr_dev->hw->set_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT)) {
+ hns_roce_free_hem(hr_dev, table->hem[i]);
+ table->hem[i] = NULL;
+ ret = -ENODEV;
+@@ -771,7 +693,7 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev,
+ &table->mutex))
+ return;
+
+- if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
++ if (hr_dev->hw->clear_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT))
+ dev_warn(dev, "failed to clear HEM base address.\n");
+
+ hns_roce_free_hem(hr_dev, table->hem[i]);
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.h b/drivers/infiniband/hw/hns/hns_roce_hem.h
+index 03d44e2efa473..b7617786b1005 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.h
+@@ -34,9 +34,7 @@
+ #ifndef _HNS_ROCE_HEM_H
+ #define _HNS_ROCE_HEM_H
+
+-#define HW_SYNC_SLEEP_TIME_INTERVAL 20
+-#define HW_SYNC_TIMEOUT_MSECS (25 * HW_SYNC_SLEEP_TIME_INTERVAL)
+-#define BT_CMD_SYNC_SHIFT 31
++#define HEM_HOP_STEP_DIRECT 0xff
+
+ enum {
+ /* MAP HEM(Hardware Entry Memory) */
+@@ -73,11 +71,6 @@ enum {
+ (type >= HEM_TYPE_MTT && hop_num == 1) || \
+ (type >= HEM_TYPE_MTT && hop_num == HNS_ROCE_HOP_NUM_0))
+
+-enum {
+- HNS_ROCE_HEM_PAGE_SHIFT = 12,
+- HNS_ROCE_HEM_PAGE_SIZE = 1 << HNS_ROCE_HEM_PAGE_SHIFT,
+-};
+-
+ struct hns_roce_hem_chunk {
+ struct list_head list;
+ int npages;
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+index cec705b58a847..6f9b024d4ff7c 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+@@ -450,6 +450,82 @@ static void hns_roce_set_db_event_mode(struct hns_roce_dev *hr_dev,
+ roce_write(hr_dev, ROCEE_GLB_CFG_REG, val);
+ }
+
++static int hns_roce_v1_set_hem(struct hns_roce_dev *hr_dev,
++ struct hns_roce_hem_table *table, int obj,
++ int step_idx)
++{
++ spinlock_t *lock = &hr_dev->bt_cmd_lock;
++ struct device *dev = hr_dev->dev;
++ struct hns_roce_hem_iter iter;
++ void __iomem *bt_cmd;
++ __le32 bt_cmd_val[2];
++ __le32 bt_cmd_h = 0;
++ unsigned long flags;
++ __le32 bt_cmd_l;
++ int ret = 0;
++ u64 bt_ba;
++ long end;
++
++ /* Find the HEM(Hardware Entry Memory) entry */
++ unsigned long i = (obj & (table->num_obj - 1)) /
++ (table->table_chunk_size / table->obj_size);
++
++ switch (table->type) {
++ case HEM_TYPE_QPC:
++ case HEM_TYPE_MTPT:
++ case HEM_TYPE_CQC:
++ case HEM_TYPE_SRQC:
++ roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
++ ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, table->type);
++ break;
++ default:
++ return ret;
++ }
++
++ roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M,
++ ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj);
++ roce_set_bit(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0);
++ roce_set_bit(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1);
++
++ /* Currently iter only a chunk */
++ for (hns_roce_hem_first(table->hem[i], &iter);
++ !hns_roce_hem_last(&iter); hns_roce_hem_next(&iter)) {
++ bt_ba = hns_roce_hem_addr(&iter) >> HNS_HW_PAGE_SHIFT;
++
++ spin_lock_irqsave(lock, flags);
++
++ bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG;
++
++ end = HW_SYNC_TIMEOUT_MSECS;
++ while (end > 0) {
++ if (!(readl(bt_cmd) >> BT_CMD_SYNC_SHIFT))
++ break;
++
++ mdelay(HW_SYNC_SLEEP_TIME_INTERVAL);
++ end -= HW_SYNC_SLEEP_TIME_INTERVAL;
++ }
++
++ if (end <= 0) {
++ dev_err(dev, "Write bt_cmd err,hw_sync is not zero.\n");
++ spin_unlock_irqrestore(lock, flags);
++ return -EBUSY;
++ }
++
++ bt_cmd_l = cpu_to_le32(bt_ba);
++ roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M,
++ ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S,
++ upper_32_bits(bt_ba));
++
++ bt_cmd_val[0] = bt_cmd_l;
++ bt_cmd_val[1] = bt_cmd_h;
++ hns_roce_write64_k(bt_cmd_val,
++ hr_dev->reg_base + ROCEE_BT_CMD_L_REG);
++ spin_unlock_irqrestore(lock, flags);
++ }
++
++ return ret;
++}
++
+ static void hns_roce_set_db_ext_mode(struct hns_roce_dev *hr_dev, u32 sdb_mode,
+ u32 odb_mode)
+ {
+@@ -4358,6 +4434,7 @@ static const struct hns_roce_hw hns_roce_hw_v1 = {
+ .set_mtu = hns_roce_v1_set_mtu,
+ .write_mtpt = hns_roce_v1_write_mtpt,
+ .write_cqc = hns_roce_v1_write_cqc,
++ .set_hem = hns_roce_v1_set_hem,
+ .clear_hem = hns_roce_v1_clear_hem,
+ .modify_qp = hns_roce_v1_modify_qp,
+ .query_qp = hns_roce_v1_query_qp,
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
+index 46ab0a321d211..9ff1a41ddec3f 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
+@@ -1042,6 +1042,11 @@ struct hns_roce_db_table {
+ struct hns_roce_ext_db *ext_db;
+ };
+
++#define HW_SYNC_SLEEP_TIME_INTERVAL 20
++#define HW_SYNC_TIMEOUT_MSECS (25 * HW_SYNC_SLEEP_TIME_INTERVAL)
++#define BT_CMD_SYNC_SHIFT 31
++#define HNS_ROCE_BA_SIZE (32 * 4096)
++
+ struct hns_roce_bt_table {
+ struct hns_roce_buf_list qpc_buf;
+ struct hns_roce_buf_list mtpt_buf;
+--
+2.39.2
+
--- /dev/null
+From 83250f546c46886d2c3e823f2bf72e73a533c707 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Dec 2020 09:37:33 +0800
+Subject: RDMA/hns: Fix coding style issues
+
+From: Lang Cheng <chenglang@huawei.com>
+
+[ Upstream commit dc93a0d987fcfe93b132871e72d4ea5aff36dd5c ]
+
+Just format the code without modifying anything, including fixing some
+redundant and missing blanks and spaces and changing the variable
+definition order.
+
+Link: https://lore.kernel.org/r/1607650657-35992-8-git-send-email-liweihang@huawei.com
+Signed-off-by: Lang Cheng <chenglang@huawei.com>
+Signed-off-by: Weihang Li <liweihang@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: cf5b608fb0e3 ("RDMA/hns: Fix hns_roce_table_get return value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_cmd.c | 27 +++++++++++-----------
+ drivers/infiniband/hw/hns/hns_roce_cmd.h | 4 ++--
+ drivers/infiniband/hw/hns/hns_roce_cq.c | 2 +-
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 20 ++++++++--------
+ drivers/infiniband/hw/hns/hns_roce_hem.h | 2 +-
+ drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 9 +++-----
+ drivers/infiniband/hw/hns/hns_roce_hw_v1.h | 2 +-
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 9 +++-----
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 6 ++---
+ drivers/infiniband/hw/hns/hns_roce_main.c | 6 ++---
+ drivers/infiniband/hw/hns/hns_roce_mr.c | 4 ++--
+ drivers/infiniband/hw/hns/hns_roce_qp.c | 2 +-
+ drivers/infiniband/hw/hns/hns_roce_srq.c | 1 -
+ 13 files changed, 43 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.c b/drivers/infiniband/hw/hns/hns_roce_cmd.c
+index 455d533dd7c4a..c493d7644b577 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_cmd.c
++++ b/drivers/infiniband/hw/hns/hns_roce_cmd.c
+@@ -36,9 +36,9 @@
+ #include "hns_roce_device.h"
+ #include "hns_roce_cmd.h"
+
+-#define CMD_POLL_TOKEN 0xffff
+-#define CMD_MAX_NUM 32
+-#define CMD_TOKEN_MASK 0x1f
++#define CMD_POLL_TOKEN 0xffff
++#define CMD_MAX_NUM 32
++#define CMD_TOKEN_MASK 0x1f
+
+ static int hns_roce_cmd_mbox_post_hw(struct hns_roce_dev *hr_dev, u64 in_param,
+ u64 out_param, u32 in_modifier,
+@@ -93,8 +93,8 @@ static int hns_roce_cmd_mbox_poll(struct hns_roce_dev *hr_dev, u64 in_param,
+ void hns_roce_cmd_event(struct hns_roce_dev *hr_dev, u16 token, u8 status,
+ u64 out_param)
+ {
+- struct hns_roce_cmd_context
+- *context = &hr_dev->cmd.context[token & hr_dev->cmd.token_mask];
++ struct hns_roce_cmd_context *context =
++ &hr_dev->cmd.context[token % hr_dev->cmd.max_cmds];
+
+ if (token != context->token)
+ return;
+@@ -164,8 +164,8 @@ static int hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param,
+ int ret;
+
+ down(&hr_dev->cmd.event_sem);
+- ret = __hns_roce_cmd_mbox_wait(hr_dev, in_param, out_param,
+- in_modifier, op_modifier, op, timeout);
++ ret = __hns_roce_cmd_mbox_wait(hr_dev, in_param, out_param, in_modifier,
++ op_modifier, op, timeout);
+ up(&hr_dev->cmd.event_sem);
+
+ return ret;
+@@ -231,9 +231,8 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev)
+ struct hns_roce_cmdq *hr_cmd = &hr_dev->cmd;
+ int i;
+
+- hr_cmd->context = kmalloc_array(hr_cmd->max_cmds,
+- sizeof(*hr_cmd->context),
+- GFP_KERNEL);
++ hr_cmd->context =
++ kcalloc(hr_cmd->max_cmds, sizeof(*hr_cmd->context), GFP_KERNEL);
+ if (!hr_cmd->context)
+ return -ENOMEM;
+
+@@ -262,8 +261,8 @@ void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev)
+ hr_cmd->use_events = 0;
+ }
+
+-struct hns_roce_cmd_mailbox
+- *hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev)
++struct hns_roce_cmd_mailbox *
++hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev)
+ {
+ struct hns_roce_cmd_mailbox *mailbox;
+
+@@ -271,8 +270,8 @@ struct hns_roce_cmd_mailbox
+ if (!mailbox)
+ return ERR_PTR(-ENOMEM);
+
+- mailbox->buf = dma_pool_alloc(hr_dev->cmd.pool, GFP_KERNEL,
+- &mailbox->dma);
++ mailbox->buf =
++ dma_pool_alloc(hr_dev->cmd.pool, GFP_KERNEL, &mailbox->dma);
+ if (!mailbox->buf) {
+ kfree(mailbox);
+ return ERR_PTR(-ENOMEM);
+diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.h b/drivers/infiniband/hw/hns/hns_roce_cmd.h
+index 1915bacaded0a..8e63b827f28cc 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_cmd.h
++++ b/drivers/infiniband/hw/hns/hns_roce_cmd.h
+@@ -143,8 +143,8 @@ int hns_roce_cmd_mbox(struct hns_roce_dev *hr_dev, u64 in_param, u64 out_param,
+ unsigned long in_modifier, u8 op_modifier, u16 op,
+ unsigned long timeout);
+
+-struct hns_roce_cmd_mailbox
+- *hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev);
++struct hns_roce_cmd_mailbox *
++hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev);
+ void hns_roce_free_cmd_mailbox(struct hns_roce_dev *hr_dev,
+ struct hns_roce_cmd_mailbox *mailbox);
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c
+index 8a6bded9c11cb..9200e6477e1ed 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_cq.c
++++ b/drivers/infiniband/hw/hns/hns_roce_cq.c
+@@ -41,9 +41,9 @@
+
+ static int alloc_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
+ {
++ struct ib_device *ibdev = &hr_dev->ib_dev;
+ struct hns_roce_cmd_mailbox *mailbox;
+ struct hns_roce_cq_table *cq_table;
+- struct ib_device *ibdev = &hr_dev->ib_dev;
+ u64 mtts[MTT_MIN_COUNT] = { 0 };
+ dma_addr_t dma_handle;
+ int ret;
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index c880a8be7e3cd..edc287a0a91a1 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -198,9 +198,9 @@ int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
+ {
+ struct device *dev = hr_dev->dev;
+ u32 chunk_ba_num;
++ u32 chunk_size;
+ u32 table_idx;
+ u32 bt_num;
+- u32 chunk_size;
+
+ if (get_hem_table_config(hr_dev, mhop, table->type))
+ return -EINVAL;
+@@ -332,15 +332,15 @@ static int hns_roce_set_hem(struct hns_roce_dev *hr_dev,
+ {
+ spinlock_t *lock = &hr_dev->bt_cmd_lock;
+ struct device *dev = hr_dev->dev;
+- long end;
+- unsigned long flags;
+ struct hns_roce_hem_iter iter;
+ void __iomem *bt_cmd;
+ __le32 bt_cmd_val[2];
+ __le32 bt_cmd_h = 0;
++ unsigned long flags;
+ __le32 bt_cmd_l;
+- u64 bt_ba;
+ int ret = 0;
++ u64 bt_ba;
++ long end;
+
+ /* Find the HEM(Hardware Entry Memory) entry */
+ unsigned long i = (obj & (table->num_obj - 1)) /
+@@ -640,8 +640,8 @@ int hns_roce_table_get(struct hns_roce_dev *hr_dev,
+ struct hns_roce_hem_table *table, unsigned long obj)
+ {
+ struct device *dev = hr_dev->dev;
+- int ret = 0;
+ unsigned long i;
++ int ret = 0;
+
+ if (hns_roce_check_whether_mhop(hr_dev, table->type))
+ return hns_roce_table_mhop_get(hr_dev, table, obj);
+@@ -789,14 +789,14 @@ void *hns_roce_table_find(struct hns_roce_dev *hr_dev,
+ struct hns_roce_hem_chunk *chunk;
+ struct hns_roce_hem_mhop mhop;
+ struct hns_roce_hem *hem;
+- void *addr = NULL;
+ unsigned long mhop_obj = obj;
+ unsigned long obj_per_chunk;
+ unsigned long idx_offset;
+ int offset, dma_offset;
++ void *addr = NULL;
++ u32 hem_idx = 0;
+ int length;
+ int i, j;
+- u32 hem_idx = 0;
+
+ if (!table->lowmem)
+ return NULL;
+@@ -966,8 +966,8 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev,
+ {
+ struct hns_roce_hem_mhop mhop;
+ u32 buf_chunk_size;
+- int i;
+ u64 obj;
++ int i;
+
+ if (hns_roce_calc_hem_mhop(hr_dev, table, NULL, &mhop))
+ return;
+@@ -1298,8 +1298,8 @@ static int hem_list_alloc_root_bt(struct hns_roce_dev *hr_dev,
+ const struct hns_roce_buf_region *regions,
+ int region_cnt)
+ {
+- struct roce_hem_item *hem, *temp_hem, *root_hem;
+ struct list_head temp_list[HNS_ROCE_MAX_BT_REGION];
++ struct roce_hem_item *hem, *temp_hem, *root_hem;
+ const struct hns_roce_buf_region *r;
+ struct list_head temp_root;
+ struct list_head temp_btm;
+@@ -1404,8 +1404,8 @@ int hns_roce_hem_list_request(struct hns_roce_dev *hr_dev,
+ {
+ const struct hns_roce_buf_region *r;
+ int ofs, end;
+- int ret;
+ int unit;
++ int ret;
+ int i;
+
+ if (region_cnt > HNS_ROCE_MAX_BT_REGION) {
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.h b/drivers/infiniband/hw/hns/hns_roce_hem.h
+index b34c940077bb5..112243d112c23 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.h
+@@ -174,4 +174,4 @@ static inline dma_addr_t hns_roce_hem_addr(struct hns_roce_hem_iter *iter)
+ return sg_dma_address(&iter->chunk->mem[iter->page_idx]);
+ }
+
+-#endif /*_HNS_ROCE_HEM_H*/
++#endif /* _HNS_ROCE_HEM_H */
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+index b3d5ba8ef439a..cec705b58a847 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+@@ -239,7 +239,7 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp,
+ break;
+ }
+
+- /*Ctrl field, ctrl set type: sig, solic, imm, fence */
++ /* Ctrl field, ctrl set type: sig, solic, imm, fence */
+ /* SO wait for conforming application scenarios */
+ ctrl->flag |= (wr->send_flags & IB_SEND_SIGNALED ?
+ cpu_to_le32(HNS_ROCE_WQE_CQ_NOTIFY) : 0) |
+@@ -300,7 +300,7 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp,
+ }
+ ctrl->flag |= cpu_to_le32(HNS_ROCE_WQE_INLINE);
+ } else {
+- /*sqe num is two */
++ /* sqe num is two */
+ for (i = 0; i < wr->num_sge; i++)
+ set_data_seg(dseg + i, wr->sg_list + i);
+
+@@ -1165,7 +1165,7 @@ static int hns_roce_raq_init(struct hns_roce_dev *hr_dev)
+ }
+ raq->e_raq_buf->map = addr;
+
+- /* Configure raq extended address. 48bit 4K align*/
++ /* Configure raq extended address. 48bit 4K align */
+ roce_write(hr_dev, ROCEE_EXT_RAQ_REG, raq->e_raq_buf->map >> 12);
+
+ /* Configure raq_shift */
+@@ -2760,7 +2760,6 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
+ roce_set_field(context->qpc_bytes_16,
+ QP_CONTEXT_QPC_BYTES_16_QP_NUM_M,
+ QP_CONTEXT_QPC_BYTES_16_QP_NUM_S, hr_qp->qpn);
+-
+ } else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) {
+ roce_set_field(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTES_4_TRANSPORT_SERVICE_TYPE_M,
+@@ -3793,7 +3792,6 @@ static int hns_roce_v1_aeq_int(struct hns_roce_dev *hr_dev,
+ int event_type;
+
+ while ((aeqe = next_aeqe_sw_v1(eq))) {
+-
+ /* Make sure we read the AEQ entry after we have checked the
+ * ownership bit
+ */
+@@ -3898,7 +3896,6 @@ static int hns_roce_v1_ceq_int(struct hns_roce_dev *hr_dev,
+ u32 cqn;
+
+ while ((ceqe = next_ceqe_sw_v1(eq))) {
+-
+ /* Make sure we read CEQ entry after we have checked the
+ * ownership bit
+ */
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
+index ffd0156080f52..46ab0a321d211 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
+@@ -419,7 +419,7 @@ struct hns_roce_wqe_data_seg {
+
+ struct hns_roce_wqe_raddr_seg {
+ __le32 rkey;
+- __le32 len;/* reserved */
++ __le32 len; /* reserved */
+ __le64 raddr;
+ };
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 76ed547b76ea7..322f341f41458 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -1028,8 +1028,8 @@ static int hns_roce_v2_rst_process_cmd(struct hns_roce_dev *hr_dev)
+ struct hns_roce_v2_priv *priv = hr_dev->priv;
+ struct hnae3_handle *handle = priv->handle;
+ const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
+- unsigned long instance_stage; /* the current instance stage */
+- unsigned long reset_stage; /* the current reset stage */
++ unsigned long instance_stage; /* the current instance stage */
++ unsigned long reset_stage; /* the current reset stage */
+ unsigned long reset_cnt;
+ bool sw_resetting;
+ bool hw_resetting;
+@@ -2434,7 +2434,6 @@ static int hns_roce_init_link_table(struct hns_roce_dev *hr_dev,
+ if (i < (pg_num - 1))
+ entry[i].blk_ba1_nxt_ptr |=
+ (i + 1) << HNS_ROCE_LINK_TABLE_NXT_PTR_S;
+-
+ }
+ link_tbl->npages = pg_num;
+ link_tbl->pg_sz = buf_chk_sz;
+@@ -5540,16 +5539,14 @@ static int hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
+ case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW:
+ hns_roce_cq_event(hr_dev, cqn, event_type);
+ break;
+- case HNS_ROCE_EVENT_TYPE_DB_OVERFLOW:
+- break;
+ case HNS_ROCE_EVENT_TYPE_MB:
+ hns_roce_cmd_event(hr_dev,
+ le16_to_cpu(aeqe->event.cmd.token),
+ aeqe->event.cmd.status,
+ le64_to_cpu(aeqe->event.cmd.out_param));
+ break;
++ case HNS_ROCE_EVENT_TYPE_DB_OVERFLOW:
+ case HNS_ROCE_EVENT_TYPE_CEQ_OVERFLOW:
+- break;
+ case HNS_ROCE_EVENT_TYPE_FLR:
+ break;
+ default:
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+index 8a92faeb3d237..8948d2b5577d5 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+@@ -440,7 +440,7 @@ struct hns_roce_srq_context {
+ #define SRQC_BYTE_60_SRQ_DB_RECORD_ADDR_S 1
+ #define SRQC_BYTE_60_SRQ_DB_RECORD_ADDR_M GENMASK(31, 1)
+
+-enum{
++enum {
+ V2_MPT_ST_VALID = 0x1,
+ V2_MPT_ST_FREE = 0x2,
+ };
+@@ -1076,9 +1076,9 @@ struct hns_roce_v2_ud_send_wqe {
+ __le32 dmac;
+ __le32 byte_48;
+ u8 dgid[GID_LEN_V2];
+-
+ };
+-#define V2_UD_SEND_WQE_BYTE_4_OPCODE_S 0
++
++#define V2_UD_SEND_WQE_BYTE_4_OPCODE_S 0
+ #define V2_UD_SEND_WQE_BYTE_4_OPCODE_M GENMASK(4, 0)
+
+ #define V2_UD_SEND_WQE_BYTE_4_OWNER_S 7
+diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
+index 8cc2dae269aff..90cbd15f64415 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_main.c
++++ b/drivers/infiniband/hw/hns/hns_roce_main.c
+@@ -582,8 +582,8 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
+
+ static int hns_roce_init_hem(struct hns_roce_dev *hr_dev)
+ {
+- int ret;
+ struct device *dev = hr_dev->dev;
++ int ret;
+
+ ret = hns_roce_init_hem_table(hr_dev, &hr_dev->mr_table.mtpt_table,
+ HEM_TYPE_MTPT, hr_dev->caps.mtpt_entry_sz,
+@@ -723,8 +723,8 @@ static int hns_roce_init_hem(struct hns_roce_dev *hr_dev)
+ */
+ static int hns_roce_setup_hca(struct hns_roce_dev *hr_dev)
+ {
+- int ret;
+ struct device *dev = hr_dev->dev;
++ int ret;
+
+ spin_lock_init(&hr_dev->sm_lock);
+ spin_lock_init(&hr_dev->bt_cmd_lock);
+@@ -847,8 +847,8 @@ void hns_roce_handle_device_err(struct hns_roce_dev *hr_dev)
+
+ int hns_roce_init(struct hns_roce_dev *hr_dev)
+ {
+- int ret;
+ struct device *dev = hr_dev->dev;
++ int ret;
+
+ if (hr_dev->hw->reset) {
+ ret = hr_dev->hw->reset(hr_dev, true);
+diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
+index 1c342a7bd7dff..d5b3b10e0a807 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
+@@ -167,10 +167,10 @@ static void hns_roce_mr_free(struct hns_roce_dev *hr_dev,
+ static int hns_roce_mr_enable(struct hns_roce_dev *hr_dev,
+ struct hns_roce_mr *mr)
+ {
+- int ret;
+ unsigned long mtpt_idx = key_to_hw_index(mr->key);
+- struct device *dev = hr_dev->dev;
+ struct hns_roce_cmd_mailbox *mailbox;
++ struct device *dev = hr_dev->dev;
++ int ret;
+
+ /* Allocate mailbox memory */
+ mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
+diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
+index 6fe98af7741b5..c42c6761382d1 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
++++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
+@@ -114,8 +114,8 @@ void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type)
+ static void hns_roce_ib_qp_event(struct hns_roce_qp *hr_qp,
+ enum hns_roce_event type)
+ {
+- struct ib_event event;
+ struct ib_qp *ibqp = &hr_qp->ibqp;
++ struct ib_event event;
+
+ if (ibqp->event_handler) {
+ event.device = ibqp->device;
+diff --git a/drivers/infiniband/hw/hns/hns_roce_srq.c b/drivers/infiniband/hw/hns/hns_roce_srq.c
+index 08df97e0a6654..02e2416b5fed6 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_srq.c
++++ b/drivers/infiniband/hw/hns/hns_roce_srq.c
+@@ -245,7 +245,6 @@ static int alloc_srq_idx(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq,
+ err = -ENOMEM;
+ goto err_idx_mtr;
+ }
+-
+ }
+
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From 542b277f62895ed776c839d9db5590db488d77c6 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 3c3187f22216a..854b41c14774d 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -588,11 +588,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 f5f03e27fab0ffedbb5f2578859539bdde5fd8c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 17:29:54 +0800
+Subject: RDMA/hns: Use refcount_t APIs for HEM
+
+From: Weihang Li <liweihang@huawei.com>
+
+[ Upstream commit 82eb481da64586ccd287b2b2c5a086202c65e7eb ]
+
+refcount_t is better than integer for reference counting, it will WARN on
+overflow/underflow and avoid use-after-free risks.
+
+Link: https://lore.kernel.org/r/1621589395-2435-5-git-send-email-liweihang@huawei.com
+Signed-off-by: Weihang Li <liweihang@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: cf5b608fb0e3 ("RDMA/hns: Fix hns_roce_table_get return value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 32 +++++++++++-------------
+ drivers/infiniband/hw/hns/hns_roce_hem.h | 4 +--
+ 2 files changed, 17 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index edc287a0a91a1..831e9476c6284 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -260,7 +260,6 @@ static struct hns_roce_hem *hns_roce_alloc_hem(struct hns_roce_dev *hr_dev,
+ if (!hem)
+ return NULL;
+
+- hem->refcount = 0;
+ INIT_LIST_HEAD(&hem->chunk_list);
+
+ order = get_order(hem_alloc_size);
+@@ -607,7 +606,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
+
+ mutex_lock(&table->mutex);
+ if (table->hem[index.buf]) {
+- ++table->hem[index.buf]->refcount;
++ refcount_inc(&table->hem[index.buf]->refcount);
+ goto out;
+ }
+
+@@ -626,7 +625,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
+ }
+ }
+
+- ++table->hem[index.buf]->refcount;
++ refcount_set(&table->hem[index.buf]->refcount, 1);
+ goto out;
+
+ err_alloc:
+@@ -652,7 +651,7 @@ int hns_roce_table_get(struct hns_roce_dev *hr_dev,
+ mutex_lock(&table->mutex);
+
+ if (table->hem[i]) {
+- ++table->hem[i]->refcount;
++ refcount_inc(&table->hem[i]->refcount);
+ goto out;
+ }
+
+@@ -675,7 +674,7 @@ int hns_roce_table_get(struct hns_roce_dev *hr_dev,
+ goto out;
+ }
+
+- ++table->hem[i]->refcount;
++ refcount_set(&table->hem[i]->refcount, 1);
+ out:
+ mutex_unlock(&table->mutex);
+ return ret;
+@@ -742,11 +741,11 @@ static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev,
+ return;
+ }
+
+- mutex_lock(&table->mutex);
+- if (check_refcount && (--table->hem[index.buf]->refcount > 0)) {
+- mutex_unlock(&table->mutex);
++ if (!check_refcount)
++ mutex_lock(&table->mutex);
++ else if (!refcount_dec_and_mutex_lock(&table->hem[index.buf]->refcount,
++ &table->mutex))
+ return;
+- }
+
+ clear_mhop_hem(hr_dev, table, obj, &mhop, &index);
+ free_mhop_hem(hr_dev, table, &mhop, &index);
+@@ -768,16 +767,15 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev,
+ i = (obj & (table->num_obj - 1)) /
+ (table->table_chunk_size / table->obj_size);
+
+- mutex_lock(&table->mutex);
++ if (!refcount_dec_and_mutex_lock(&table->hem[i]->refcount,
++ &table->mutex))
++ return;
+
+- if (--table->hem[i]->refcount == 0) {
+- /* Clear HEM base address */
+- if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
+- dev_warn(dev, "Clear HEM base address failed.\n");
++ if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
++ dev_warn(dev, "failed to clear HEM base address.\n");
+
+- hns_roce_free_hem(hr_dev, table->hem[i]);
+- table->hem[i] = NULL;
+- }
++ hns_roce_free_hem(hr_dev, table->hem[i]);
++ table->hem[i] = NULL;
+
+ mutex_unlock(&table->mutex);
+ }
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.h b/drivers/infiniband/hw/hns/hns_roce_hem.h
+index 112243d112c23..03d44e2efa473 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.h
+@@ -87,8 +87,8 @@ struct hns_roce_hem_chunk {
+ };
+
+ struct hns_roce_hem {
+- struct list_head chunk_list;
+- int refcount;
++ struct list_head chunk_list;
++ refcount_t refcount;
+ };
+
+ struct hns_roce_hem_iter {
+--
+2.39.2
+
--- /dev/null
+From a74d833260a058ea18ce5e9026933f2466fa75ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Oct 2020 20:20:02 -0300
+Subject: RDMA: Remove uverbs_ex_cmd_mask values that are linked to functions
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit b8e3130dd96b7b2d6d92e62dcd1515af30212fe2 ]
+
+Since a while now the uverbs layer checks if the driver implements a
+function before allowing the ucmd to proceed. This largely obsoletes the
+cmd_mask stuff, but there is some tricky bits in drivers preventing it
+from being removed.
+
+Remove the easy elements of uverbs_ex_cmd_mask by pre-setting them in the
+core code. These are triggered soley based on the related ops function
+pointer.
+
+query_device_ex is not triggered based on an op, but all drivers already
+implement something compatible with the extension, so enable it globally
+too.
+
+Link: https://lore.kernel.org/r/2-v1-caa70ba3d1ab+1436e-ucmd_mask_jgg@nvidia.com
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: cf5b608fb0e3 ("RDMA/hns: Fix hns_roce_table_get return value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/device.c | 11 +++++++++++
+ drivers/infiniband/core/uverbs_cmd.c | 2 +-
+ drivers/infiniband/hw/efa/efa_main.c | 3 ---
+ drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 7 -------
+ drivers/infiniband/hw/hns/hns_roce_main.c | 2 --
+ drivers/infiniband/hw/mlx4/main.c | 14 +-------------
+ drivers/infiniband/hw/mlx5/main.c | 14 ++------------
+ 7 files changed, 15 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
+index 5b7abcf102fe9..3c29fd04b3016 100644
+--- a/drivers/infiniband/core/device.c
++++ b/drivers/infiniband/core/device.c
+@@ -600,6 +600,17 @@ struct ib_device *_ib_alloc_device(size_t size)
+ init_completion(&device->unreg_completion);
+ INIT_WORK(&device->unregistration_work, ib_unregister_work);
+
++ device->uverbs_ex_cmd_mask =
++ BIT_ULL(IB_USER_VERBS_EX_CMD_CREATE_FLOW) |
++ BIT_ULL(IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
++ BIT_ULL(IB_USER_VERBS_EX_CMD_CREATE_WQ) |
++ BIT_ULL(IB_USER_VERBS_EX_CMD_DESTROY_FLOW) |
++ BIT_ULL(IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL) |
++ BIT_ULL(IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
++ BIT_ULL(IB_USER_VERBS_EX_CMD_MODIFY_CQ) |
++ BIT_ULL(IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
++ BIT_ULL(IB_USER_VERBS_EX_CMD_QUERY_DEVICE);
++
+ return device;
+ }
+ EXPORT_SYMBOL(_ib_alloc_device);
+diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
+index 09cf470c08d65..158f9eadc4e95 100644
+--- a/drivers/infiniband/core/uverbs_cmd.c
++++ b/drivers/infiniband/core/uverbs_cmd.c
+@@ -3778,7 +3778,7 @@ const struct uapi_definition uverbs_def_write_intf[] = {
+ IB_USER_VERBS_EX_CMD_MODIFY_CQ,
+ ib_uverbs_ex_modify_cq,
+ UAPI_DEF_WRITE_I(struct ib_uverbs_ex_modify_cq),
+- UAPI_DEF_METHOD_NEEDS_FN(create_cq))),
++ UAPI_DEF_METHOD_NEEDS_FN(modify_cq))),
+
+ DECLARE_UVERBS_OBJECT(
+ UVERBS_OBJECT_DEVICE,
+diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c
+index ffdd18f4217f5..cd41cd114ab63 100644
+--- a/drivers/infiniband/hw/efa/efa_main.c
++++ b/drivers/infiniband/hw/efa/efa_main.c
+@@ -326,9 +326,6 @@ static int efa_ib_device_add(struct efa_dev *dev)
+ (1ull << IB_USER_VERBS_CMD_CREATE_AH) |
+ (1ull << IB_USER_VERBS_CMD_DESTROY_AH);
+
+- dev->ibdev.uverbs_ex_cmd_mask =
+- (1ull << IB_USER_VERBS_EX_CMD_QUERY_DEVICE);
+-
+ ib_set_device_ops(&dev->ibdev, &efa_dev_ops);
+
+ err = ib_register_device(&dev->ibdev, "efa_%d", &pdev->dev);
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+index 5f4d8a32ed6d9..b3d5ba8ef439a 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+@@ -2062,11 +2062,6 @@ static void hns_roce_v1_write_cqc(struct hns_roce_dev *hr_dev,
+ CQ_CONTEXT_CQC_BYTE_32_CQ_CONS_IDX_S, 0);
+ }
+
+-static int hns_roce_v1_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
+-{
+- return -EOPNOTSUPP;
+-}
+-
+ static int hns_roce_v1_req_notify_cq(struct ib_cq *ibcq,
+ enum ib_cq_notify_flags flags)
+ {
+@@ -4347,7 +4342,6 @@ static void hns_roce_v1_cleanup_eq_table(struct hns_roce_dev *hr_dev)
+
+ static const struct ib_device_ops hns_roce_v1_dev_ops = {
+ .destroy_qp = hns_roce_v1_destroy_qp,
+- .modify_cq = hns_roce_v1_modify_cq,
+ .poll_cq = hns_roce_v1_poll_cq,
+ .post_recv = hns_roce_v1_post_recv,
+ .post_send = hns_roce_v1_post_send,
+@@ -4367,7 +4361,6 @@ static const struct hns_roce_hw hns_roce_hw_v1 = {
+ .set_mtu = hns_roce_v1_set_mtu,
+ .write_mtpt = hns_roce_v1_write_mtpt,
+ .write_cqc = hns_roce_v1_write_cqc,
+- .modify_cq = hns_roce_v1_modify_cq,
+ .clear_hem = hns_roce_v1_clear_hem,
+ .modify_qp = hns_roce_v1_modify_qp,
+ .query_qp = hns_roce_v1_query_qp,
+diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
+index 1e8b3e4ef1b17..8cc2dae269aff 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_main.c
++++ b/drivers/infiniband/hw/hns/hns_roce_main.c
+@@ -511,8 +511,6 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
+ (1ULL << IB_USER_VERBS_CMD_QUERY_QP) |
+ (1ULL << IB_USER_VERBS_CMD_DESTROY_QP);
+
+- ib_dev->uverbs_ex_cmd_mask |= (1ULL << IB_USER_VERBS_EX_CMD_MODIFY_CQ);
+-
+ if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_REREG_MR) {
+ ib_dev->uverbs_cmd_mask |= (1ULL << IB_USER_VERBS_CMD_REREG_MR);
+ ib_set_device_ops(ib_dev, &hns_roce_dev_mr_ops);
+diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
+index 05c7200751e50..c62cdd6456962 100644
+--- a/drivers/infiniband/hw/mlx4/main.c
++++ b/drivers/infiniband/hw/mlx4/main.c
+@@ -2682,8 +2682,6 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
+
+ ib_set_device_ops(&ibdev->ib_dev, &mlx4_ib_dev_ops);
+ ibdev->ib_dev.uverbs_ex_cmd_mask |=
+- (1ull << IB_USER_VERBS_EX_CMD_MODIFY_CQ) |
+- (1ull << IB_USER_VERBS_EX_CMD_QUERY_DEVICE) |
+ (1ull << IB_USER_VERBS_EX_CMD_CREATE_CQ) |
+ (1ull << IB_USER_VERBS_EX_CMD_CREATE_QP);
+
+@@ -2691,15 +2689,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
+ ((mlx4_ib_port_link_layer(&ibdev->ib_dev, 1) ==
+ IB_LINK_LAYER_ETHERNET) ||
+ (mlx4_ib_port_link_layer(&ibdev->ib_dev, 2) ==
+- IB_LINK_LAYER_ETHERNET))) {
+- ibdev->ib_dev.uverbs_ex_cmd_mask |=
+- (1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
+- (1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
+- (1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
+- (1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
+- (1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
++ IB_LINK_LAYER_ETHERNET)))
+ ib_set_device_ops(&ibdev->ib_dev, &mlx4_ib_dev_wq_ops);
+- }
+
+ if (dev->caps.flags & MLX4_DEV_CAP_FLAG_MEM_WINDOW ||
+ dev->caps.bmme_flags & MLX4_BMME_FLAG_TYPE_2_WIN) {
+@@ -2718,9 +2709,6 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
+
+ if (check_flow_steering_support(dev)) {
+ ibdev->steering_support = MLX4_STEERING_MODE_DEVICE_MANAGED;
+- ibdev->ib_dev.uverbs_ex_cmd_mask |=
+- (1ull << IB_USER_VERBS_EX_CMD_CREATE_FLOW) |
+- (1ull << IB_USER_VERBS_EX_CMD_DESTROY_FLOW);
+ ib_set_device_ops(&ibdev->ib_dev, &mlx4_ib_dev_fs_ops);
+ }
+
+diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
+index 39ba7005f2c4c..215d6618839be 100644
+--- a/drivers/infiniband/hw/mlx5/main.c
++++ b/drivers/infiniband/hw/mlx5/main.c
+@@ -4180,14 +4180,10 @@ static int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev)
+ (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_XSRQ) |
+ (1ull << IB_USER_VERBS_CMD_OPEN_QP);
+- dev->ib_dev.uverbs_ex_cmd_mask =
+- (1ull << IB_USER_VERBS_EX_CMD_QUERY_DEVICE) |
++ dev->ib_dev.uverbs_ex_cmd_mask |=
+ (1ull << IB_USER_VERBS_EX_CMD_CREATE_CQ) |
+ (1ull << IB_USER_VERBS_EX_CMD_CREATE_QP) |
+- (1ull << IB_USER_VERBS_EX_CMD_MODIFY_QP) |
+- (1ull << IB_USER_VERBS_EX_CMD_MODIFY_CQ) |
+- (1ull << IB_USER_VERBS_EX_CMD_CREATE_FLOW) |
+- (1ull << IB_USER_VERBS_EX_CMD_DESTROY_FLOW);
++ (1ull << IB_USER_VERBS_EX_CMD_MODIFY_QP);
+
+ if (MLX5_CAP_GEN(mdev, ipoib_enhanced_offloads) &&
+ IS_ENABLED(CONFIG_MLX5_CORE_IPOIB))
+@@ -4290,12 +4286,6 @@ static int mlx5_ib_roce_init(struct mlx5_ib_dev *dev)
+ ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);
+
+ if (ll == IB_LINK_LAYER_ETHERNET) {
+- dev->ib_dev.uverbs_ex_cmd_mask |=
+- (1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
+- (1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
+- (1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
+- (1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
+- (1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
+ ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_common_roce_ops);
+
+ port_num = mlx5_core_native_port_num(dev->mdev) - 1;
+--
+2.39.2
+
--- /dev/null
+From 2f2c35957d80a482001fb79b1fa3fd1549acaba1 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 f5ab74683b58a..e4ff64d28c778 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1751,7 +1751,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 67a1eeb8763cf618d13e3e65e0620ff493b2790c 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 e4ff64d28c778..52b75779dbb7e 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1751,19 +1751,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
+@@ -5032,10 +5030,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);
+@@ -5938,7 +5934,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 4f48749d354cf146c71193323ebd3fdcded68944 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 3c9c2d6e3b92e..888ff53c8144d 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -929,24 +929,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;
+@@ -1221,7 +1224,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;
+@@ -1327,33 +1331,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;
+
+@@ -1386,7 +1392,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 b0512fd8896309815a1a22bc71a99058624bf569 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 1fb398af11fd2ef8c67757ff37867b82d408ddce 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 fb6444d0409cf..211a25351e7d4 100644
+--- a/drivers/scsi/3w-xxxx.c
++++ b/drivers/scsi/3w-xxxx.c
+@@ -2308,8 +2308,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 bb6b7c102298ac20051979240acafa9ccfb30b12 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 f48ef47546f4d..b33cb1172f31d 100644
+--- a/drivers/scsi/qedf/qedf_main.c
++++ b/drivers/scsi/qedf/qedf_main.c
+@@ -3042,9 +3042,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 5237efe2699ffcf1896deec8e44b4f19b11e2715 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 35d3eee26ea56..4a7f811abae4e 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -8039,6 +8039,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 */
+@@ -9407,6 +9423,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,
+@@ -9459,6 +9476,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 60665650fdbfd3d71145d0f63c21e45e313f606a 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 c3a905923ef29..cbf166df57da7 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
+
scripts-tags.sh-resolve-gtags-empty-index-generation.patch
drm-amdgpu-validate-vm-ioctl-flags.patch
nubus-partially-revert-proc_create_single_data-conversion.patch
+fs-pipe-reveal-missing-function-protoypes.patch
+x86-resctrl-only-show-tasks-pid-in-current-pid-names.patch
+blk-iocost-use-spin_lock_irqsave-in-adjust_inuse_and.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
+irqchip-jcore-aic-kill-use-of-irq_create_strict_mapp.patch
+irqchip-jcore-aic-fix-missing-allocation-of-irq-desc.patch
+posix-timers-prevent-rt-livelock-in-itimer_delete.patch
+tracing-timer-add-missing-hrtimer-modes-to-decode_hr.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
+powercap-rapl-fix-config_iosf_mbi-dependency.patch
+arm-9303-1-kprobes-avoid-missing-declaration-warning.patch
+cpufreq-intel_pstate-fix-energy_performance_preferen.patch
+thermal-drivers-sun8i-fix-some-error-handling-paths-.patch
+rcuscale-console-output-claims-too-few-grace-periods.patch
+rcuscale-always-log-error-message.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
+perf-ibs-fix-interface-via-core-pmu-events.patch
+x86-mm-fix-__swp_entry_to_pte-for-xen-pv-guests.patch
+evm-complete-description-of-evm_inode_setattr.patch
+ima-fix-build-warnings.patch
+pstore-ram-add-check-for-kstrdup.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
+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
+bpf-remove-extra-lock_sock-for-tcp_zerocopy_receive.patch
+sctp-add-bpf_bypass_getsockopt-proto-callback.patch
+libbpf-fix-offsetof-and-container_of-to-work-with-co.patch
+nfc-constify-several-pointers-to-u8-char-and-sk_buff.patch
+nfc-llcp-fix-possible-use-of-uninitialized-variable-.patch
+bpftool-jit-limited-misreported-as-negative-value-on.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
+wl3501_cs-fix-misspelling-and-provide-missing-docume.patch
+net-create-netdev-dev_addr-assignment-helpers.patch
+wl3501_cs-use-eth_hw_addr_set.patch
+wifi-move-from-strlcpy-with-unused-retval-to-strscpy.patch
+wifi-wl3501_cs-fix-an-error-handling-path-in-wl3501_.patch
+wifi-ray_cs-utilize-strnlen-in-parse_addr.patch
+wifi-ray_cs-drop-useless-status-variable-in-parse_ad.patch
+wifi-ray_cs-fix-an-error-handling-path-in-ray_probe.patch
+wifi-ath9k-don-t-allow-to-overwrite-endpoint0-attrib.patch
+wifi-rsi-do-not-configure-wowlan-in-shutdown-hook-if.patch
+wifi-rsi-do-not-set-mmc_pm_keep_power-in-shutdown.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
+memstick-r592-make-memstick_debug_get_tpc_name-stati.patch
+wifi-ath9k-fix-possible-stall-on-ath9k_txq_list_has_.patch
+rtnetlink-extend-rtext_filter_skip_stats-to-ifla_vf_.patch
+wifi-iwlwifi-pull-from-txqs-with-softirqs-disabled.patch
+wifi-cfg80211-rewrite-merging-of-inherited-elements.patch
+wifi-ath9k-convert-msecs-to-jiffies-where-needed.patch
+igc-fix-race-condition-in-ptp-tx-code.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
+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
+sfc-fix-crash-when-reading-stats-while-nic-is-resett.patch
+nfc-llcp-simplify-llcp_sock_connect-error-paths.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
+netlink-add-__sock_i_ino-for-__netlink_diag_dump.patch
+radeon-avoid-double-free-in-ci_dpm_init.patch
+drm-amd-display-explicitly-specify-update-type-per-p.patch
+input-drv260x-sleep-between-polling-go-bit.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
+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
+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
+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
+arm-dts-gta04-move-model-property-out-of-pinctrl-nod.patch
+arm64-dts-qcom-msm8916-correct-camss-unit-address.patch
+arm64-dts-qcom-msm8994-correct-spmi-unit-address.patch
+arm64-dts-qcom-msm8996-correct-camss-unit-address.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-apq8096-fix-fixed-regulator-name-prop.patch
+arm-dts-stm32-shorten-the-av96-hdmi-sound-card-name.patch
+memory-brcmstb_dpfe-fix-testing-array-offset-after-u.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
+ib-hfi1-use-bitmap_zalloc-when-applicable.patch
+ib-hfi1-fix-sdma.h-tx-num_descs-off-by-one-errors.patch
+ib-hfi1-fix-wrong-mmu_node-used-for-user-sdma-packet.patch
+rdma-remove-uverbs_ex_cmd_mask-values-that-are-linke.patch
+rdma-hns-fix-coding-style-issues.patch
+rdma-hns-use-refcount_t-apis-for-hem.patch
+rdma-hns-clean-the-hardware-related-code-for-hem.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
+fbdev-omapfb-lcd_mipid-fix-an-error-handling-path-in.patch
+arm64-dts-ti-k3-j7200-fix-physical-address-of-pin.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-adm1275-enable-adm1272-temperature-reporting.patch
+hwmon-adm1275-allow-setting-sample-averaging.patch
+hwmon-pmbus-adm1275-fix-problems-with-temperature-mo.patch
+arm-dts-bcm5301x-fix-duplex-full-full-duplex.patch
+mips-dts-ci20-fix-act8600-regulator-node-names.patch
+drm-amdkfd-fix-potential-deallocation-of-previously-.patch
+drm-radeon-fix-possible-division-by-zero-errors.patch
+amdgpu-validate-offset_in_bo-of-drm_amdgpu_gem_va.patch
+rdma-bnxt_re-wraparound-mbox-producer-index.patch
+rdma-bnxt_re-avoid-calling-wake_up-threads-from-spin.patch
+clk-imx-clk-imx8mn-fix-memory-leak-in-imx8mn_clocks_.patch
+clk-imx-clk-imx8mp-improve-error-handling-in-imx8mp_.patch
+clk-tegra-tegra124-emc-fix-potential-memory-leak.patch
+alsa-ac97-fix-possible-null-dereference-in-snd_ac97_.patch
+drm-msm-dpu-do-not-enable-color-management-if-dspps-.patch
+drm-msm-dp-free-resources-after-unregistering-them.patch
+clk-vc5-check-memory-returned-by-kasprintf.patch
+clk-cdce925-check-return-value-of-kasprintf.patch
+clk-si5341-allow-different-output-vdd_sel-values.patch
+clk-si5341-add-sysfs-properties-to-allow-checking-re.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
+mips-dts-ci20-add-parent-supplies-to-act8600-regulat.patch
+mips-dts-ci20-raise-vddcore-voltage-to-1.125-volts.patch
+pci-cadence-fix-gen2-link-retraining-process.patch
+scsi-qedf-fix-null-dereference-in-error-handling.patch
+pinctrl-bcm2835-handle-gpiochip_add_pin_range-errors.patch
+pci-aspm-disable-aspm-on-mfd-function-removal-to-avo.patch
+scsi-3w-xxxx-add-error-handling-for-initialization-f.patch
+pci-pciehp-cancel-bringup-sequence-if-card-is-not-pr.patch
+pci-ftpci100-release-the-clock-resources.patch
+pci-add-pci_clear_master-stub-for-non-config_pci.patch
+perf-bench-use-unbuffered-output-when-pipe-tee-ing-t.patch
+perf-bench-add-missing-setlocale-call-to-allow-usage.patch
+pinctrl-cherryview-return-correct-value-if-pin-in-pu.patch
+kcsan-don-t-expect-64-bits-atomic-builtins-from-32-b.patch
+perf-script-fixup-struct-evsel_script-method-prefix.patch
+perf-script-fix-allocation-of-evsel-priv-related-to-.patch
+perf-dwarf-aux-fix-off-by-one-in-die_get_varname.patch
+pinctrl-at91-pio4-check-return-value-of-devm_kasprin.patch
+powerpc-powernv-sriov-perform-null-check-on-iov-befo.patch
+mm-rename-pud_page_vaddr-to-pud_pgtable-and-make-it-.patch
+mm-rename-p4d_page_vaddr-to-p4d_pgtable-and-make-it-.patch
+powerpc-book3s64-mm-fix-directmap-stats-in-proc-memi.patch
+powerpc-mm-dax-fix-the-condition-when-checking-if-al.patch
+hwrng-virtio-add-an-internal-buffer.patch
+hwrng-virtio-don-t-wait-on-cleanup.patch
+hwrng-virtio-don-t-waste-entropy.patch
+hwrng-virtio-always-add-a-pending-request.patch
+hwrng-virtio-fix-race-on-data_avail-and-actual-data.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
+modpost-fix-off-by-one-in-is_executable_section.patch
+arc-define-asm_nl-and-__align-_str-outside-ifdef-__a.patch
+nfsv4.1-freeze-the-session-table-upon-receiving-nfs4.patch
+dax-fix-dax_mapping_release-use-after-free.patch
+dax-introduce-alloc_dev_dax_id.patch
+hwrng-st-keep-clock-enabled-while-hwrng-is-registere.patch
--- /dev/null
+From 75963a2c89109d639fc38a89fce752d54f6e1349 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 32654fe1f8b59..3f53b5ea78410 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)
+@@ -1836,9 +1838,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 ec706adb07b98dbc5afeb6fddaf93f6a968e95a5 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 5a4420ed4d3e181af89d6f23db6cdd734c65c78b 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 01ef79f15b024..be259c685cc80 100644
+--- a/drivers/spi/spi-geni-qcom.c
++++ b/drivers/spi/spi-geni-qcom.c
+@@ -32,7 +32,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 bdd8bf3b2f77d51a8ff4faa845a851b60c3f5537 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 f8b13071a6f42..e053b06280172 100644
+--- a/drivers/thermal/sun8i_thermal.c
++++ b/drivers/thermal/sun8i_thermal.c
+@@ -318,6 +318,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;
+@@ -338,47 +343,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)
+@@ -529,17 +522,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,
+@@ -641,7 +623,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 f7ad98f39d66ad65432fb53bebb736745261a335 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 40e9b5a12732d..5c540ccabcac9 100644
+--- a/include/trace/events/timer.h
++++ b/include/trace/events/timer.h
+@@ -156,7 +156,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 b1f41a32c1fdb8a0a4244d5a9f68cd844d7a39e6 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 f700ff2df074e..0db377ff8f608 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 cf8ed9cf94968f60ba6e2b6589e4e70d614fc215 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 b0b831b4f588c5013aec399093c59fb13d34da39 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 8b85f3f8ef8fa82b948c8f47c73dbf2dd7ad6562 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 2bd4d295c9bdf..b2cfc483515c0 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,
+@@ -2244,7 +2244,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 a1c999d636b80be83d6c7a0696f8e74f6ef974de 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 a8eb9d66f21e7e1ead2a91b90e0658cff3df7ded 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 42f00a2a8c800..cf5648188459c 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 ddbc319830af208f36ca2850afb00e56b3c05aba 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 ac354dfc50559..2bd4d295c9bdf 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 c112f917ef24a41fbbbd1267e0cb04c674789095 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 368eebefa741e..e64f108d288bb 100644
+--- a/drivers/net/wireless/atmel/atmel_cs.c
++++ b/drivers/net/wireless/atmel/atmel_cs.c
+@@ -73,6 +73,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");
+
+@@ -83,8 +84,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 a76a968e19d26af3d7b8a654b158449e091829ec 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 d09dabae56271..671c7f83d5fc3 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -262,117 +262,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;
+ }
+
+@@ -2170,7 +2205,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 4889d88d16da3749c2f55b09c4acd6365d49237a 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 7c61d179895b3..5b173f21e87bf 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+@@ -1174,8 +1174,11 @@ static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode,
+ mvmtxq = iwl_mvm_txq_from_mac80211(txq);
+ mvmtxq->stopped = !start;
+
+- 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 0581b1356066b97de4b37695f9b4f2d0afd60be1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Aug 2022 22:14:53 +0200
+Subject: wifi: move from strlcpy with unused retval to strscpy
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit bf99f11df4de45fcba6f6c441b411a16bccaccf6 ]
+
+Follow the advice of the below link and prefer 'strscpy' in this
+subsystem. Conversion is 1:1 because the return value is not used.
+Generated by a coccinelle script.
+
+Link: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw@mail.gmail.com/
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220830201457.7984-2-wsa+renesas@sang-engineering.com
+Stable-dep-of: 391af06a02e7 ("wifi: wl3501_cs: Fix an error handling path in wl3501_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath6kl/init.c | 2 +-
+ drivers/net/wireless/ath/carl9170/fw.c | 2 +-
+ drivers/net/wireless/ath/wil6210/main.c | 2 +-
+ drivers/net/wireless/ath/wil6210/netdev.c | 2 +-
+ drivers/net/wireless/ath/wil6210/wmi.c | 2 +-
+ drivers/net/wireless/atmel/atmel.c | 2 +-
+ drivers/net/wireless/broadcom/b43/leds.c | 2 +-
+ drivers/net/wireless/broadcom/b43legacy/leds.c | 2 +-
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 8 ++++----
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 8 ++++----
+ .../net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 2 +-
+ .../net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 2 +-
+ drivers/net/wireless/intel/ipw2x00/ipw2100.c | 6 +++---
+ drivers/net/wireless/intel/ipw2x00/ipw2200.c | 6 +++---
+ drivers/net/wireless/intel/iwlegacy/3945-mac.c | 2 +-
+ drivers/net/wireless/intersil/hostap/hostap_ioctl.c | 2 +-
+ drivers/net/wireless/marvell/libertas/ethtool.c | 4 ++--
+ drivers/net/wireless/microchip/wilc1000/mon.c | 2 +-
+ drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 2 +-
+ drivers/net/wireless/quantenna/qtnfmac/commands.c | 2 +-
+ drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c | 2 +-
+ drivers/net/wireless/wl3501_cs.c | 8 ++++----
+ 22 files changed, 36 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
+index 39bf196861751..b9e9808634610 100644
+--- a/drivers/net/wireless/ath/ath6kl/init.c
++++ b/drivers/net/wireless/ath/ath6kl/init.c
+@@ -1014,7 +1014,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
+
+ switch (ie_id) {
+ case ATH6KL_FW_IE_FW_VERSION:
+- strlcpy(ar->wiphy->fw_version, data,
++ strscpy(ar->wiphy->fw_version, data,
+ min(sizeof(ar->wiphy->fw_version), ie_len+1));
+
+ ath6kl_dbg(ATH6KL_DBG_BOOT,
+diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
+index 1ab09e1c9ec57..4c1aecd1163ce 100644
+--- a/drivers/net/wireless/ath/carl9170/fw.c
++++ b/drivers/net/wireless/ath/carl9170/fw.c
+@@ -105,7 +105,7 @@ static void carl9170_fw_info(struct ar9170 *ar)
+ CARL9170FW_GET_MONTH(fw_date),
+ CARL9170FW_GET_DAY(fw_date));
+
+- strlcpy(ar->hw->wiphy->fw_version, motd_desc->release,
++ strscpy(ar->hw->wiphy->fw_version, motd_desc->release,
+ sizeof(ar->hw->wiphy->fw_version));
+ }
+ }
+diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
+index 3ba5b2550a8c1..bb532c6866beb 100644
+--- a/drivers/net/wireless/ath/wil6210/main.c
++++ b/drivers/net/wireless/ath/wil6210/main.c
+@@ -1305,7 +1305,7 @@ void wil_get_board_file(struct wil6210_priv *wil, char *buf, size_t len)
+ board_file = WIL_BOARD_FILE_NAME;
+ }
+
+- strlcpy(buf, board_file, len);
++ strscpy(buf, board_file, len);
+ }
+
+ static int wil_get_bl_info(struct wil6210_priv *wil)
+diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
+index 07b4a252a23c9..41fd4e548a513 100644
+--- a/drivers/net/wireless/ath/wil6210/netdev.c
++++ b/drivers/net/wireless/ath/wil6210/netdev.c
+@@ -445,7 +445,7 @@ int wil_if_add(struct wil6210_priv *wil)
+
+ wil_dbg_misc(wil, "entered");
+
+- strlcpy(wiphy->fw_version, wil->fw_version, sizeof(wiphy->fw_version));
++ strscpy(wiphy->fw_version, wil->fw_version, sizeof(wiphy->fw_version));
+
+ rc = wiphy_register(wiphy);
+ if (rc < 0) {
+diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
+index 421aebbb49e54..a2c0f14bf74ef 100644
+--- a/drivers/net/wireless/ath/wil6210/wmi.c
++++ b/drivers/net/wireless/ath/wil6210/wmi.c
+@@ -780,7 +780,7 @@ static void wmi_evt_ready(struct wil6210_vif *vif, int id, void *d, int len)
+ return; /* FW load will fail after timeout */
+ }
+ /* ignore MAC address, we already have it from the boot loader */
+- strlcpy(wiphy->fw_version, wil->fw_version, sizeof(wiphy->fw_version));
++ strscpy(wiphy->fw_version, wil->fw_version, sizeof(wiphy->fw_version));
+
+ if (len > offsetof(struct wmi_ready_event, rfc_read_calib_result)) {
+ wil_dbg_wmi(wil, "rfc calibration result %d\n",
+diff --git a/drivers/net/wireless/atmel/atmel.c b/drivers/net/wireless/atmel/atmel.c
+index 707fe66727f8d..2a445fefedd7a 100644
+--- a/drivers/net/wireless/atmel/atmel.c
++++ b/drivers/net/wireless/atmel/atmel.c
+@@ -1519,7 +1519,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
+ priv->firmware = NULL;
+ priv->firmware_type = fw_type;
+ if (firmware) /* module parameter */
+- strlcpy(priv->firmware_id, firmware, sizeof(priv->firmware_id));
++ strscpy(priv->firmware_id, firmware, sizeof(priv->firmware_id));
+ priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
+ priv->station_state = STATION_STATE_DOWN;
+ priv->do_rx_crc = 0;
+diff --git a/drivers/net/wireless/broadcom/b43/leds.c b/drivers/net/wireless/broadcom/b43/leds.c
+index 982a772a9d879..bfe1be345844d 100644
+--- a/drivers/net/wireless/broadcom/b43/leds.c
++++ b/drivers/net/wireless/broadcom/b43/leds.c
+@@ -118,7 +118,7 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
+ led->wl = dev->wl;
+ led->index = led_index;
+ led->activelow = activelow;
+- strlcpy(led->name, name, sizeof(led->name));
++ strscpy(led->name, name, sizeof(led->name));
+ atomic_set(&led->state, 0);
+
+ led->led_dev.name = led->name;
+diff --git a/drivers/net/wireless/broadcom/b43legacy/leds.c b/drivers/net/wireless/broadcom/b43legacy/leds.c
+index 38b5be3a84e2c..79e6fd205bfb7 100644
+--- a/drivers/net/wireless/broadcom/b43legacy/leds.c
++++ b/drivers/net/wireless/broadcom/b43legacy/leds.c
+@@ -88,7 +88,7 @@ static int b43legacy_register_led(struct b43legacy_wldev *dev,
+ led->dev = dev;
+ led->index = led_index;
+ led->activelow = activelow;
+- strlcpy(led->name, name, sizeof(led->name));
++ strscpy(led->name, name, sizeof(led->name));
+
+ led->led_dev.name = led->name;
+ led->led_dev.default_trigger = default_trigger;
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+index f29de630908d7..a964f9f0c4435 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+@@ -219,7 +219,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
+ &revinfo, sizeof(revinfo));
+ if (err < 0) {
+ bphy_err(drvr, "retrieving revision info failed, %d\n", err);
+- strlcpy(ri->chipname, "UNKNOWN", sizeof(ri->chipname));
++ strscpy(ri->chipname, "UNKNOWN", sizeof(ri->chipname));
+ } else {
+ ri->vendorid = le32_to_cpu(revinfo.vendorid);
+ ri->deviceid = le32_to_cpu(revinfo.deviceid);
+@@ -273,7 +273,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
+
+ /* locate firmware version number for ethtool */
+ ptr = strrchr(buf, ' ') + 1;
+- strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
++ strscpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
+
+ /* Query for 'clmver' to get CLM version info from firmware */
+ memset(buf, 0, sizeof(buf));
+@@ -385,11 +385,11 @@ static void brcmf_mp_attach(void)
+ * if not set then if available use the platform data version. To make
+ * sure it gets initialized at all, always copy the module param version
+ */
+- strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path,
++ strscpy(brcmf_mp_global.firmware_path, brcmf_firmware_path,
+ BRCMF_FW_ALTPATH_LEN);
+ if ((brcmfmac_pdata) && (brcmfmac_pdata->fw_alternative_path) &&
+ (brcmf_mp_global.firmware_path[0] == '\0')) {
+- strlcpy(brcmf_mp_global.firmware_path,
++ strscpy(brcmf_mp_global.firmware_path,
+ brcmfmac_pdata->fw_alternative_path,
+ BRCMF_FW_ALTPATH_LEN);
+ }
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+index 3d544eedc1a39..3d3ee350fdfb3 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -569,10 +569,10 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
+
+ if (drvr->revinfo.result == 0)
+ brcmu_dotrev_str(drvr->revinfo.driverrev, drev);
+- strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
+- strlcpy(info->version, drev, sizeof(info->version));
+- strlcpy(info->fw_version, drvr->fwver, sizeof(info->fw_version));
+- strlcpy(info->bus_info, dev_name(drvr->bus_if->dev),
++ strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
++ strscpy(info->version, drev, sizeof(info->version));
++ strscpy(info->fw_version, drvr->fwver, sizeof(info->fw_version));
++ strscpy(info->bus_info, dev_name(drvr->bus_if->dev),
+ sizeof(info->bus_info));
+ }
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+index 060889bf6d053..b9cd9d7482a1e 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+@@ -740,7 +740,7 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev,
+ fwnames[j].path[0] = '\0';
+ /* check if firmware path is provided by module parameter */
+ if (brcmf_mp_global.firmware_path[0] != '\0') {
+- strlcpy(fwnames[j].path, mp_path,
++ strscpy(fwnames[j].path, mp_path,
+ BRCMF_FW_NAME_LEN);
+
+ if (end != '/') {
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+index 437e83ea8902d..4ff5432a36cb2 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+@@ -688,7 +688,7 @@ static void brcmf_fws_macdesc_set_name(struct brcmf_fws_info *fws,
+ struct brcmf_fws_mac_descriptor *desc)
+ {
+ if (desc == &fws->desc.other)
+- strlcpy(desc->name, "MAC-OTHER", sizeof(desc->name));
++ strscpy(desc->name, "MAC-OTHER", sizeof(desc->name));
+ else if (desc->mac_handle)
+ scnprintf(desc->name, sizeof(desc->name), "MAC-%d:%d",
+ desc->mac_handle, desc->interface_id);
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+index 23fbddd0c1f8e..24a0cea9d64e8 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+@@ -5907,8 +5907,8 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
+ struct ipw2100_priv *priv = libipw_priv(dev);
+ char fw_ver[64], ucode_ver[64];
+
+- strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+- strlcpy(info->version, DRV_VERSION, sizeof(info->version));
++ strscpy(info->driver, DRV_NAME, sizeof(info->driver));
++ strscpy(info->version, DRV_VERSION, sizeof(info->version));
+
+ ipw2100_get_fwversion(priv, fw_ver, sizeof(fw_ver));
+ ipw2100_get_ucodeversion(priv, ucode_ver, sizeof(ucode_ver));
+@@ -5916,7 +5916,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
+ snprintf(info->fw_version, sizeof(info->fw_version), "%s:%d:%s",
+ fw_ver, priv->eeprom_version, ucode_ver);
+
+- strlcpy(info->bus_info, pci_name(priv->pci_dev),
++ strscpy(info->bus_info, pci_name(priv->pci_dev),
+ sizeof(info->bus_info));
+ }
+
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+index bb728fb24b8a4..706cd36a43055 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+@@ -10427,8 +10427,8 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
+ char date[32];
+ u32 len;
+
+- strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+- strlcpy(info->version, DRV_VERSION, sizeof(info->version));
++ strscpy(info->driver, DRV_NAME, sizeof(info->driver));
++ strscpy(info->version, DRV_VERSION, sizeof(info->version));
+
+ len = sizeof(vers);
+ ipw_get_ordinal(p, IPW_ORD_STAT_FW_VERSION, vers, &len);
+@@ -10437,7 +10437,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
+
+ snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)",
+ vers, date);
+- strlcpy(info->bus_info, pci_name(p->pci_dev),
++ strscpy(info->bus_info, pci_name(p->pci_dev),
+ sizeof(info->bus_info));
+ }
+
+diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+index ef0ac42a55a2a..e786bd9f3163a 100644
+--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c
++++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+@@ -3256,7 +3256,7 @@ il3945_store_measurement(struct device *d, struct device_attribute *attr,
+
+ if (count) {
+ char *p = buffer;
+- strlcpy(buffer, buf, sizeof(buffer));
++ strscpy(buffer, buf, sizeof(buffer));
+ channel = simple_strtoul(p, NULL, 0);
+ if (channel)
+ params.channel = channel;
+diff --git a/drivers/net/wireless/intersil/hostap/hostap_ioctl.c b/drivers/net/wireless/intersil/hostap/hostap_ioctl.c
+index 514c7b01dbf6f..293a081b0dc75 100644
+--- a/drivers/net/wireless/intersil/hostap/hostap_ioctl.c
++++ b/drivers/net/wireless/intersil/hostap/hostap_ioctl.c
+@@ -3859,7 +3859,7 @@ static void prism2_get_drvinfo(struct net_device *dev,
+ iface = netdev_priv(dev);
+ local = iface->local;
+
+- strlcpy(info->driver, "hostap", sizeof(info->driver));
++ strscpy(info->driver, "hostap", sizeof(info->driver));
+ snprintf(info->fw_version, sizeof(info->fw_version),
+ "%d.%d.%d", (local->sta_fw_ver >> 16) & 0xff,
+ (local->sta_fw_ver >> 8) & 0xff,
+diff --git a/drivers/net/wireless/marvell/libertas/ethtool.c b/drivers/net/wireless/marvell/libertas/ethtool.c
+index 1bb8746a0b23b..d580e6a95d7a0 100644
+--- a/drivers/net/wireless/marvell/libertas/ethtool.c
++++ b/drivers/net/wireless/marvell/libertas/ethtool.c
+@@ -20,8 +20,8 @@ static void lbs_ethtool_get_drvinfo(struct net_device *dev,
+ priv->fwrelease >> 16 & 0xff,
+ priv->fwrelease >> 8 & 0xff,
+ priv->fwrelease & 0xff);
+- strlcpy(info->driver, "libertas", sizeof(info->driver));
+- strlcpy(info->version, lbs_driver_version, sizeof(info->version));
++ strscpy(info->driver, "libertas", sizeof(info->driver));
++ strscpy(info->version, lbs_driver_version, sizeof(info->version));
+ }
+
+ /*
+diff --git a/drivers/net/wireless/microchip/wilc1000/mon.c b/drivers/net/wireless/microchip/wilc1000/mon.c
+index b5a1b65c087ca..03b7229a0ff5a 100644
+--- a/drivers/net/wireless/microchip/wilc1000/mon.c
++++ b/drivers/net/wireless/microchip/wilc1000/mon.c
+@@ -229,7 +229,7 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
+ return NULL;
+
+ wl->monitor_dev->type = ARPHRD_IEEE80211_RADIOTAP;
+- strlcpy(wl->monitor_dev->name, name, IFNAMSIZ);
++ strscpy(wl->monitor_dev->name, name, IFNAMSIZ);
+ wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops;
+ wl->monitor_dev->needs_free_netdev = true;
+
+diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+index 54cdf3ad09d75..7b555bd365271 100644
+--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
++++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+@@ -1236,7 +1236,7 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
+ mac->macinfo.extended_capabilities_len;
+ }
+
+- strlcpy(wiphy->fw_version, hw_info->fw_version,
++ strscpy(wiphy->fw_version, hw_info->fw_version,
+ sizeof(wiphy->fw_version));
+ wiphy->hw_version = hw_info->hw_version;
+
+diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c
+index f3ccbd2b10847..c75241f505835 100644
+--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
++++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
+@@ -979,7 +979,7 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus,
+ hwinfo->total_rx_chain, hwinfo->total_tx_chain,
+ hwinfo->fw_ver);
+
+- strlcpy(hwinfo->fw_version, bld_label, sizeof(hwinfo->fw_version));
++ strscpy(hwinfo->fw_version, bld_label, sizeof(hwinfo->fw_version));
+ hwinfo->hw_version = hw_ver;
+
+ return 0;
+diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c
+index 49421d10e22bc..f7d95c9624a01 100644
+--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c
++++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c
+@@ -143,7 +143,7 @@ static int rtl8187_register_led(struct ieee80211_hw *dev,
+ led->dev = dev;
+ led->ledpin = ledpin;
+ led->is_radio = is_radio;
+- strlcpy(led->name, name, sizeof(led->name));
++ strscpy(led->name, name, sizeof(led->name));
+
+ led->led_dev.name = led->name;
+ led->led_dev.default_trigger = default_trigger;
+diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
+index 7351a2c127adc..7fb2f95134760 100644
+--- a/drivers/net/wireless/wl3501_cs.c
++++ b/drivers/net/wireless/wl3501_cs.c
+@@ -1441,7 +1441,7 @@ static void wl3501_detach(struct pcmcia_device *link)
+ static int wl3501_get_name(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+ {
+- strlcpy(wrqu->name, "IEEE 802.11-DS", sizeof(wrqu->name));
++ strscpy(wrqu->name, "IEEE 802.11-DS", sizeof(wrqu->name));
+ return 0;
+ }
+
+@@ -1652,7 +1652,7 @@ static int wl3501_set_nick(struct net_device *dev, struct iw_request_info *info,
+
+ if (wrqu->data.length > sizeof(this->nick))
+ return -E2BIG;
+- strlcpy(this->nick, extra, wrqu->data.length);
++ strscpy(this->nick, extra, wrqu->data.length);
+ return 0;
+ }
+
+@@ -1661,7 +1661,7 @@ static int wl3501_get_nick(struct net_device *dev, struct iw_request_info *info,
+ {
+ struct wl3501_card *this = netdev_priv(dev);
+
+- strlcpy(extra, this->nick, 32);
++ strscpy(extra, this->nick, 32);
+ wrqu->data.length = strlen(extra);
+ return 0;
+ }
+@@ -1965,7 +1965,7 @@ static int wl3501_config(struct pcmcia_device *link)
+ this->firmware_date[0] = '\0';
+ this->rssi = 255;
+ this->chan = iw_default_channel(this->reg_domain);
+- strlcpy(this->nick, "Planet WL3501", sizeof(this->nick));
++ strscpy(this->nick, "Planet WL3501", sizeof(this->nick));
+ spin_lock_init(&this->lock);
+ init_waitqueue_head(&this->wait);
+ netif_start_queue(dev);
+--
+2.39.2
+
--- /dev/null
+From 227e9a7967ceed7158ea464f193da3e1ea2aa24f 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 c2a685f63e959..78ef40e315b5c 100644
+--- a/drivers/net/wireless/marvell/mwifiex/scan.c
++++ b/drivers/net/wireless/marvell/mwifiex/scan.c
+@@ -2200,9 +2200,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 c84155721d34aafad0d34a01147f2c3955d5ec47 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 7c51d475a1a0793b78e05705900dea03691e091f 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 3b7b03dfb6a0876494093b5891c89d9964bbdd9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 19:44:14 +0300
+Subject: wifi: ray_cs: Drop useless status variable in parse_addr()
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 4dfc63c002a555a2c3c34d89009532ad803be876 ]
+
+The status variable assigned only once and used also only once.
+Replace it's usage by actual value.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220603164414.48436-2-andriy.shevchenko@linux.intel.com
+Stable-dep-of: 4f8d66a9fb2e ("wifi: ray_cs: Fix an error handling path in ray_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ray_cs.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
+index 5dcd86f81cbf1..95d5ce1b6dfa0 100644
+--- a/drivers/net/wireless/ray_cs.c
++++ b/drivers/net/wireless/ray_cs.c
+@@ -1643,7 +1643,6 @@ static int parse_addr(char *in_str, UCHAR *out)
+ {
+ int i, k;
+ int len;
+- int status;
+
+ if (in_str == NULL)
+ return 0;
+@@ -1652,7 +1651,6 @@ static int parse_addr(char *in_str, UCHAR *out)
+ return 0;
+ memset(out, 0, ADDRLEN);
+
+- status = 1;
+ i = 5;
+
+ while (len > 0) {
+@@ -1670,7 +1668,7 @@ static int parse_addr(char *in_str, UCHAR *out)
+ if (!i--)
+ break;
+ }
+- return status;
++ return 1;
+ }
+
+ /*===========================================================================*/
+--
+2.39.2
+
--- /dev/null
+From 75416f674d6b3feb81ca413013e0c2a08a4150bc 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 95d5ce1b6dfa0..bf1282702761f 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 ca7d3754e4c9c0985830cf1292d19258a9eeac7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 19:44:13 +0300
+Subject: wifi: ray_cs: Utilize strnlen() in parse_addr()
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 9e8e9187673cb24324f9165dd47b2b28f60b0b10 ]
+
+Instead of doing simple operations and using an additional variable on stack,
+utilize strnlen() and reuse len variable.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220603164414.48436-1-andriy.shevchenko@linux.intel.com
+Stable-dep-of: 4f8d66a9fb2e ("wifi: ray_cs: Fix an error handling path in ray_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ray_cs.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
+index 091eea0d958d1..5dcd86f81cbf1 100644
+--- a/drivers/net/wireless/ray_cs.c
++++ b/drivers/net/wireless/ray_cs.c
+@@ -1641,31 +1641,29 @@ static void authenticate_timeout(struct timer_list *t)
+ /*===========================================================================*/
+ static int parse_addr(char *in_str, UCHAR *out)
+ {
++ int i, k;
+ int len;
+- int i, j, k;
+ int status;
+
+ if (in_str == NULL)
+ return 0;
+- if ((len = strlen(in_str)) < 2)
++ len = strnlen(in_str, ADDRLEN * 2 + 1) - 1;
++ if (len < 1)
+ return 0;
+ memset(out, 0, ADDRLEN);
+
+ status = 1;
+- j = len - 1;
+- if (j > 12)
+- j = 12;
+ i = 5;
+
+- while (j > 0) {
+- if ((k = hex_to_bin(in_str[j--])) != -1)
++ while (len > 0) {
++ if ((k = hex_to_bin(in_str[len--])) != -1)
+ out[i] = k;
+ else
+ return 0;
+
+- if (j == 0)
++ if (len == 0)
+ break;
+- if ((k = hex_to_bin(in_str[j--])) != -1)
++ if ((k = hex_to_bin(in_str[len--])) != -1)
+ out[i] += k << 4;
+ else
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From 920fbffad648582276372819dc70c810566d03f1 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 8108f941ccd3f..2c26376faeacc 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 3abe9358cfab8364f6a71648b31de53a33f61500 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 2c26376faeacc..b1d3aea10d7df 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 3ea91bead1d28599a2f84d59f42573dff97e738c 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 b25847799138b..884f45e627a72 100644
+--- a/drivers/net/wireless/microchip/wilc1000/hif.c
++++ b/drivers/net/wireless/microchip/wilc1000/hif.c
+@@ -470,6 +470,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 */
+@@ -479,11 +482,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 1fe07891104600cf4221ecd2c760ecba4a6db7d6 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 8c38d9461b6c3569ba36559e3bfa282feb183637 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Nov 2020 11:23:53 +0000
+Subject: wl3501_cs: Fix misspelling and provide missing documentation
+
+From: Lee Jones <lee.jones@linaro.org>
+
+[ Upstream commit 8b8a6f8c3b50193d161c598a6784e721128d6dc3 ]
+
+Fixes the following W=1 kernel build warning(s):
+
+ In file included from drivers/net/wireless/wl3501_cs.c:57:
+ drivers/net/wireless/wl3501_cs.c:143: warning: Function parameter or member 'reg_domain' not described in 'iw_valid_channel'
+ drivers/net/wireless/wl3501_cs.c:143: warning: Excess function parameter 'reg_comain' description in 'iw_valid_channel'
+ drivers/net/wireless/wl3501_cs.c:469: warning: Function parameter or member 'data' not described in 'wl3501_send_pkt'
+ drivers/net/wireless/wl3501_cs.c:469: warning: Function parameter or member 'len' not described in 'wl3501_send_pkt'
+
+Cc: Kalle Valo <kvalo@codeaurora.org>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: Fox Chen <mhchen@golf.ccl.itri.org.tw>
+Cc: de Melo <acme@conectiva.com.br>
+Cc: Gustavo Niemeyer <niemeyer@conectiva.com>
+Cc: linux-wireless@vger.kernel.org
+Cc: netdev@vger.kernel.org
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20201102112410.1049272-25-lee.jones@linaro.org
+Stable-dep-of: 391af06a02e7 ("wifi: wl3501_cs: Fix an error handling path in wl3501_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/wl3501_cs.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
+index ccf6344ed6fd2..cb71b73853f4e 100644
+--- a/drivers/net/wireless/wl3501_cs.c
++++ b/drivers/net/wireless/wl3501_cs.c
+@@ -134,7 +134,7 @@ static const struct {
+
+ /**
+ * iw_valid_channel - validate channel in regulatory domain
+- * @reg_comain: regulatory domain
++ * @reg_domain: regulatory domain
+ * @channel: channel to validate
+ *
+ * Returns 0 if invalid in the specified regulatory domain, non-zero if valid.
+@@ -458,11 +458,9 @@ static int wl3501_pwr_mgmt(struct wl3501_card *this, int suspend)
+ /**
+ * wl3501_send_pkt - Send a packet.
+ * @this: Card
+- *
+- * Send a packet.
+- *
+- * data = Ethernet raw frame. (e.g. data[0] - data[5] is Dest MAC Addr,
++ * @data: Ethernet raw frame. (e.g. data[0] - data[5] is Dest MAC Addr,
+ * data[6] - data[11] is Src MAC Addr)
++ * @len: Packet length
+ * Ref: IEEE 802.11
+ */
+ static int wl3501_send_pkt(struct wl3501_card *this, u8 *data, u16 len)
+--
+2.39.2
+
--- /dev/null
+From 17db231bc4b0d2147547b3c448f5370e55bf7ad7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Oct 2021 16:50:20 -0700
+Subject: wl3501_cs: use eth_hw_addr_set()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 18774612246d036c04ce9fee7f67192f96f48725 ]
+
+Commit 406f42fa0d3c ("net-next: When a bond have a massive amount
+of VLANs...") introduced a rbtree for faster Ethernet address look
+up. To maintain netdev->dev_addr in this tree we need to make all
+the writes to it got through appropriate helpers.
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20211018235021.1279697-15-kuba@kernel.org
+Stable-dep-of: 391af06a02e7 ("wifi: wl3501_cs: Fix an error handling path in wl3501_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/wl3501_cs.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
+index cb71b73853f4e..7351a2c127adc 100644
+--- a/drivers/net/wireless/wl3501_cs.c
++++ b/drivers/net/wireless/wl3501_cs.c
+@@ -1945,8 +1945,7 @@ static int wl3501_config(struct pcmcia_device *link)
+ goto failed;
+ }
+
+- for (i = 0; i < 6; i++)
+- dev->dev_addr[i] = ((char *)&this->mac_addr)[i];
++ eth_hw_addr_set(dev, this->mac_addr);
+
+ /* print probe information */
+ printk(KERN_INFO "%s: wl3501 @ 0x%3.3x, IRQ %d, "
+--
+2.39.2
+
--- /dev/null
+From 007fafcff383149f46dba3c47dc37afd7e29db32 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 56d0399a0cd16..dd520b44e89cc 100644
+--- a/arch/x86/include/asm/pgtable_64.h
++++ b/arch/x86/include/asm/pgtable_64.h
+@@ -235,8 +235,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 int kern_addr_valid(unsigned long addr);
+ extern void cleanup_highmap(void);
+--
+2.39.2
+
--- /dev/null
+From f906861f841781539273d274cbace0847588efd6 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 1a943743cfe4b..1e73b6fae3b4c 100644
+--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
++++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+@@ -715,11 +715,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
+