--- /dev/null
+From 3583f7f071f6ce71393ac751a6ad739b7c9904c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Mar 2023 21:26:27 +0100
+Subject: ACPI: EC: Fix oops when removing custom query handlers
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit e5b492c6bb900fcf9722e05f4a10924410e170c1 ]
+
+When removing custom query handlers, the handler might still
+be used inside the EC query workqueue, causing a kernel oops
+if the module holding the callback function was already unloaded.
+
+Fix this by flushing the EC query workqueue when removing
+custom query handlers.
+
+Tested on a Acer Travelmate 4002WLMi
+
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/ec.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index 9751b84c1b221..ee4c812c8f6cc 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -1121,6 +1121,7 @@ static void acpi_ec_remove_query_handlers(struct acpi_ec *ec,
+ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
+ {
+ acpi_ec_remove_query_handlers(ec, false, query_bit);
++ flush_workqueue(ec_query_wq);
+ }
+ EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
+
+--
+2.39.2
+
--- /dev/null
+From d70839ce5d63641d748ec8fc8e468255abfe357e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 26 Feb 2023 13:54:27 +0800
+Subject: ACPI: processor: Check for null return of devm_kzalloc() in
+ fch_misc_setup()
+
+From: Kang Chen <void0red@gmail.com>
+
+[ Upstream commit 4dea41775d951ff1f7b472a346a8ca3ae7e74455 ]
+
+devm_kzalloc() may fail, clk_data->name might be NULL and will
+cause a NULL pointer dereference later.
+
+Signed-off-by: Kang Chen <void0red@gmail.com>
+[ rjw: Subject and changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpi_apd.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
+index 3bbe2276cac76..80f945cbec8a7 100644
+--- a/drivers/acpi/acpi_apd.c
++++ b/drivers/acpi/acpi_apd.c
+@@ -83,6 +83,8 @@ static int fch_misc_setup(struct apd_private_data *pdata)
+ if (!acpi_dev_get_property(adev, "clk-name", ACPI_TYPE_STRING, &obj)) {
+ clk_data->name = devm_kzalloc(&adev->dev, obj->string.length,
+ GFP_KERNEL);
++ if (!clk_data->name)
++ return -ENOMEM;
+
+ strcpy(clk_data->name, obj->string.pointer);
+ } else {
+--
+2.39.2
+
--- /dev/null
+From 047ff27618aa0767b67331579342c42873449e19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Apr 2023 13:02:51 +0200
+Subject: ACPI: video: Remove desktops without backlight DMI quirks
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit abe4f5ae5efa6a63c7d5abfa07eb02bb56b4654e ]
+
+After the recent backlight changes acpi_video# backlight devices are only
+registered when explicitly requested from the cmdline, by DMI quirk or by
+the GPU driver.
+
+This means that we no longer get false-positive backlight control support
+advertised on desktop boards.
+
+Remove the 3 DMI quirks for desktop boards where the false-positive issue
+was fixed through quirks before. Note many more desktop boards were
+affected but we never build a full quirk list for this.
+
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/video_detect.c | 35 -----------------------------------
+ 1 file changed, 35 deletions(-)
+
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
+index 0556c4720d3fa..b6d429a2bcb62 100644
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -130,12 +130,6 @@ static int video_detect_force_native(const struct dmi_system_id *d)
+ return 0;
+ }
+
+-static int video_detect_force_none(const struct dmi_system_id *d)
+-{
+- acpi_backlight_dmi = acpi_backlight_none;
+- return 0;
+-}
+-
+ static const struct dmi_system_id video_detect_dmi_table[] = {
+ /*
+ * Models which should use the vendor backlight interface,
+@@ -752,35 +746,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 15 3535"),
+ },
+ },
+-
+- /*
+- * Desktops which falsely report a backlight and which our heuristics
+- * for this do not catch.
+- */
+- {
+- .callback = video_detect_force_none,
+- /* Dell OptiPlex 9020M */
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"),
+- },
+- },
+- {
+- .callback = video_detect_force_none,
+- /* GIGABYTE GB-BXBT-2807 */
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+- DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
+- },
+- },
+- {
+- .callback = video_detect_force_none,
+- /* MSI MS-7721 */
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
+- DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"),
+- },
+- },
+ { },
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 00dc27b48c815bd66a50d32607181d4e6d2fb501 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Apr 2023 15:57:57 +0200
+Subject: ACPICA: ACPICA: check null return of ACPI_ALLOCATE_ZEROED in
+ acpi_db_display_objects
+
+From: void0red <30990023+void0red@users.noreply.github.com>
+
+[ Upstream commit ae5a0eccc85fc960834dd66e3befc2728284b86c ]
+
+ACPICA commit 0d5f467d6a0ba852ea3aad68663cbcbd43300fd4
+
+ACPI_ALLOCATE_ZEROED may fails, object_info might be null and will cause
+null pointer dereference later.
+
+Link: https://github.com/acpica/acpica/commit/0d5f467d
+Signed-off-by: Bob Moore <robert.moore@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpica/dbnames.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/acpi/acpica/dbnames.c b/drivers/acpi/acpica/dbnames.c
+index 3615e1a6efd8a..b91155ea9c343 100644
+--- a/drivers/acpi/acpica/dbnames.c
++++ b/drivers/acpi/acpica/dbnames.c
+@@ -652,6 +652,9 @@ acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg)
+ object_info =
+ ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));
+
++ if (!object_info)
++ return (AE_NO_MEMORY);
++
+ /* Walk the namespace from the root */
+
+ (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+--
+2.39.2
+
--- /dev/null
+From 6c05ad710228b594bb770906f5c2d2157ba8bbf0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Apr 2023 15:42:43 +0200
+Subject: ACPICA: Avoid undefined behavior: applying zero offset to null
+ pointer
+
+From: Tamir Duberstein <tamird@google.com>
+
+[ Upstream commit 05bb0167c80b8f93c6a4e0451b7da9b96db990c2 ]
+
+ACPICA commit 770653e3ba67c30a629ca7d12e352d83c2541b1e
+
+Before this change we see the following UBSAN stack trace in Fuchsia:
+
+ #0 0x000021e4213b3302 in acpi_ds_init_aml_walk(struct acpi_walk_state*, union acpi_parse_object*, struct acpi_namespace_node*, u8*, u32, struct acpi_evaluate_info*, u8) ../../third_party/acpica/source/components/dispatcher/dswstate.c:682 <platform-bus-x86.so>+0x233302
+ #1.2 0x000020d0f660777f in ubsan_get_stack_trace() compiler-rt/lib/ubsan/ubsan_diag.cpp:41 <libclang_rt.asan.so>+0x3d77f
+ #1.1 0x000020d0f660777f in maybe_print_stack_trace() compiler-rt/lib/ubsan/ubsan_diag.cpp:51 <libclang_rt.asan.so>+0x3d77f
+ #1 0x000020d0f660777f in ~scoped_report() compiler-rt/lib/ubsan/ubsan_diag.cpp:387 <libclang_rt.asan.so>+0x3d77f
+ #2 0x000020d0f660b96d in handlepointer_overflow_impl() compiler-rt/lib/ubsan/ubsan_handlers.cpp:809 <libclang_rt.asan.so>+0x4196d
+ #3 0x000020d0f660b50d in compiler-rt/lib/ubsan/ubsan_handlers.cpp:815 <libclang_rt.asan.so>+0x4150d
+ #4 0x000021e4213b3302 in acpi_ds_init_aml_walk(struct acpi_walk_state*, union acpi_parse_object*, struct acpi_namespace_node*, u8*, u32, struct acpi_evaluate_info*, u8) ../../third_party/acpica/source/components/dispatcher/dswstate.c:682 <platform-bus-x86.so>+0x233302
+ #5 0x000021e4213e2369 in acpi_ds_call_control_method(struct acpi_thread_state*, struct acpi_walk_state*, union acpi_parse_object*) ../../third_party/acpica/source/components/dispatcher/dsmethod.c:605 <platform-bus-x86.so>+0x262369
+ #6 0x000021e421437fac in acpi_ps_parse_aml(struct acpi_walk_state*) ../../third_party/acpica/source/components/parser/psparse.c:550 <platform-bus-x86.so>+0x2b7fac
+ #7 0x000021e4214464d2 in acpi_ps_execute_method(struct acpi_evaluate_info*) ../../third_party/acpica/source/components/parser/psxface.c:244 <platform-bus-x86.so>+0x2c64d2
+ #8 0x000021e4213aa052 in acpi_ns_evaluate(struct acpi_evaluate_info*) ../../third_party/acpica/source/components/namespace/nseval.c:250 <platform-bus-x86.so>+0x22a052
+ #9 0x000021e421413dd8 in acpi_ns_init_one_device(acpi_handle, u32, void*, void**) ../../third_party/acpica/source/components/namespace/nsinit.c:735 <platform-bus-x86.so>+0x293dd8
+ #10 0x000021e421429e98 in acpi_ns_walk_namespace(acpi_object_type, acpi_handle, u32, u32, acpi_walk_callback, acpi_walk_callback, void*, void**) ../../third_party/acpica/source/components/namespace/nswalk.c:298 <platform-bus-x86.so>+0x2a9e98
+ #11 0x000021e4214131ac in acpi_ns_initialize_devices(u32) ../../third_party/acpica/source/components/namespace/nsinit.c:268 <platform-bus-x86.so>+0x2931ac
+ #12 0x000021e42147c40d in acpi_initialize_objects(u32) ../../third_party/acpica/source/components/utilities/utxfinit.c:304 <platform-bus-x86.so>+0x2fc40d
+ #13 0x000021e42126d603 in acpi::acpi_impl::initialize_acpi(acpi::acpi_impl*) ../../src/devices/board/lib/acpi/acpi-impl.cc:224 <platform-bus-x86.so>+0xed603
+
+Add a simple check that avoids incrementing a pointer by zero, but
+otherwise behaves as before. Note that our findings are against ACPICA
+20221020, but the same code exists on master.
+
+Link: https://github.com/acpica/acpica/commit/770653e3
+Signed-off-by: Bob Moore <robert.moore@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpica/dswstate.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c
+index 0aa735d3b93cc..77076da2029d9 100644
+--- a/drivers/acpi/acpica/dswstate.c
++++ b/drivers/acpi/acpica/dswstate.c
+@@ -576,9 +576,14 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
+ ACPI_FUNCTION_TRACE(ds_init_aml_walk);
+
+ walk_state->parser_state.aml =
+- walk_state->parser_state.aml_start = aml_start;
+- walk_state->parser_state.aml_end =
+- walk_state->parser_state.pkg_end = aml_start + aml_length;
++ walk_state->parser_state.aml_start =
++ walk_state->parser_state.aml_end =
++ walk_state->parser_state.pkg_end = aml_start;
++ /* Avoid undefined behavior: applying zero offset to null pointer */
++ if (aml_length != 0) {
++ walk_state->parser_state.aml_end += aml_length;
++ walk_state->parser_state.pkg_end += aml_length;
++ }
+
+ /* The next_op of the next_walk will be the beginning of the method */
+
+--
+2.39.2
+
--- /dev/null
+From af4af340fd67abceca3ecef791ccc923b2af27eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 10:25:00 -0500
+Subject: ALSA: hda: LNL: add HD Audio PCI ID
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fred Oh <fred.oh@linux.intel.com>
+
+[ Upstream commit 714b2f025d767e7df1fe9da18bd70537d64cc157 ]
+
+Add HD Audio PCI ID for Intel Lunarlake platform.
+
+Signed-off-by: Fred Oh <fred.oh@linux.intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://lore.kernel.org/r/20230406152500.15104-1-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/hda_intel.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 77a592f219472..881b2f3a1551f 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2528,6 +2528,9 @@ static const struct pci_device_id azx_ids[] = {
+ /* Meteorlake-P */
+ { PCI_DEVICE(0x8086, 0x7e28),
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
++ /* Lunarlake-P */
++ { PCI_DEVICE(0x8086, 0xa828),
++ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+ /* Broxton-P(Apollolake) */
+ { PCI_DEVICE(0x8086, 0x5a98),
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
+--
+2.39.2
+
--- /dev/null
+From f3d7b39b70c91778e6f345aa0cc8dce43761c502 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Mar 2023 21:46:05 +0100
+Subject: arm64: dts: imx8mq-librem5: Remove dis_u3_susphy_quirk from
+ usb_dwc3_0
+
+From: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+
+[ Upstream commit cfe9de291bd2bbce18c5cd79e1dd582cbbacdb4f ]
+
+This reduces power consumption in system suspend by about 10%.
+
+Signed-off-by: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Signed-off-by: Martin Kepplinger <martin.kepplinger@puri.sm>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+index ae08556b2ef2f..1499d5d8bbc04 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+@@ -1299,7 +1299,6 @@
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dr_mode = "otg";
+- snps,dis_u3_susphy_quirk;
+ usb-role-switch;
+ status = "okay";
+
+--
+2.39.2
+
--- /dev/null
+From c44bcc7c4a5189c86ef11042aa7433674b82cba2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Mar 2023 02:18:49 +0100
+Subject: arm64: dts: qcom: msm8996: Add missing DWC3 quirks
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit d0af0537e28f6eace02deed63b585396de939213 ]
+
+Add missing dwc3 quirks from msm-3.18. Unfortunately, none of them
+make `dwc3-qcom 6af8800.usb: HS-PHY not in L2` go away.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230302011849.1873056-1-konrad.dybcio@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8996.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+index 67b87915d8224..9f89100542018 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -2979,8 +2979,11 @@
+ interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&hsusb_phy1>, <&ssusb_phy_0>;
+ phy-names = "usb2-phy", "usb3-phy";
++ snps,hird-threshold = /bits/ 8 <0>;
+ snps,dis_u2_susphy_quirk;
+ snps,dis_enblslpm_quirk;
++ snps,is-utmi-l1-suspend;
++ tx-fifo-resize;
+ };
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 1c575f21dcbc79f0a03b638567352228fc14dfcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 14:55:45 +0200
+Subject: arm64: dts: qcom: sdm845-polaris: Drop inexistent properties
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit fbc3a1df2866608ca43e7e6d602f66208a5afd88 ]
+
+Drop the qcom,snoc-host-cap-skip-quirk that was never introduced to
+solve schema warnings.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230406-topic-ath10k_bindings-v3-2-00895afc7764@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+index f982594896796..74c6832e05985 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+@@ -731,8 +731,6 @@
+ vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
+ vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
+ vdd-3.3-ch1-supply = <&vreg_l23a_3p3>;
+-
+- qcom,snoc-host-cap-skip-quirk;
+ status = "okay";
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 3d3ab80fd515446411c96a1101a69fc39b122412 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Apr 2023 20:38:15 +0200
+Subject: ASoC: amd: Add Dell G15 5525 to quirks list
+
+From: Cem Kaya <cemkaya.boun@gmail.com>
+
+[ Upstream commit faf15233e59052f4d61cad2da6e56daf33124d96 ]
+
+Add Dell G15 5525 Ryzen Edition to quirks list for acp6x so that
+internal mic works.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217155
+Signed-off-by: Cem Kaya <cemkaya.boun@gmail.com>
+Link: https://lore.kernel.org/r/20230410183814.260518-1-cemkaya.boun@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/yc/acp6x-mach.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index a428e17f03259..1d59163a882ca 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -45,6 +45,13 @@ static struct snd_soc_card acp6x_card = {
+ };
+
+ static const struct dmi_system_id yc_acp_quirk_table[] = {
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5525"),
++ }
++ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+--
+2.39.2
+
--- /dev/null
+From 0d7cb9e81aedb58c222ec10cab36d15726cc5b48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Apr 2023 02:21:30 +1100
+Subject: ASoC: amd: yc: Add DMI entries to support HP OMEN 16-n0xxx (8A42)
+
+From: Prajna Sariputra <putr4.s@gmail.com>
+
+[ Upstream commit ee4281de4d60288b9c802bb0906061ec355ecef2 ]
+
+This model requires an additional detection quirk to enable the internal microphone.
+
+Signed-off-by: Prajna Sariputra <putr4.s@gmail.com>
+Link: https://lore.kernel.org/r/2283110.ElGaqSPkdT@n0067ax-linux62
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/yc/acp6x-mach.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index 0acdf0156f075..a428e17f03259 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -262,6 +262,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),
+ }
+ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
++ DMI_MATCH(DMI_BOARD_NAME, "8A42"),
++ }
++ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+--
+2.39.2
+
--- /dev/null
+From 6f4dd8bc155d5e468925b0983e7728bee285e58c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Apr 2023 16:40:43 +0800
+Subject: ASoC: amd: yc: Add ThinkBook 14 G5+ ARP to quirks list for acp6x
+
+From: Baishan Jiang <bjiang400@outlook.com>
+
+[ Upstream commit a8f5da0bf4d85a6ad03810d902aba61c572102a6 ]
+
+ThinkBook 14 G5+ ARP uses Ryzen 7735H processor, and has the same
+microphone problem as ThinkBook 14 G4+ ARA.
+
+Adding 21HY to acp6x quirks table enables microphone for ThinkBook
+14 G5+ ARP.
+
+Signed-off-by: Baishan Jiang <bjiang400@outlook.com>
+Link: https://lore.kernel.org/r/OS3P286MB1711DD6556284B69C79C0C4FE19B9@OS3P286MB1711.JPNP286.PROD.OUTLOOK.COM
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/yc/acp6x-mach.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index 1d59163a882ca..b9958e5553674 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -185,6 +185,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "21EN"),
+ }
+ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "21HY"),
++ }
++ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+--
+2.39.2
+
--- /dev/null
+From 9d5cd664c339521fd01f6930953bb9210ed0cab5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Apr 2023 14:30:09 +0100
+Subject: block, bfq: Fix division by zero error on zero wsum
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+[ Upstream commit e53413f8deedf738a6782cc14cc00bd5852ccf18 ]
+
+When the weighted sum is zero the calculation of limit causes
+a division by zero error. Fix this by continuing to the next level.
+
+This was discovered by running as root:
+
+stress-ng --ioprio 0
+
+Fixes divison by error oops:
+
+[ 521.450556] divide error: 0000 [#1] SMP NOPTI
+[ 521.450766] CPU: 2 PID: 2684464 Comm: stress-ng-iopri Not tainted 6.2.1-1280.native #1
+[ 521.451117] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.1-0-g3208b098f51a-prebuilt.qemu.org 04/01/2014
+[ 521.451627] RIP: 0010:bfqq_request_over_limit+0x207/0x400
+[ 521.451875] Code: 01 48 8d 0c c8 74 0b 48 8b 82 98 00 00 00 48 8d 0c c8 8b 85 34 ff ff ff 48 89 ca 41 0f af 41 50 48 d1 ea 48 98 48 01 d0 31 d2 <48> f7 f1 41 39 41 48 89 85 34 ff ff ff 0f 8c 7b 01 00 00 49 8b 44
+[ 521.452699] RSP: 0018:ffffb1af84eb3948 EFLAGS: 00010046
+[ 521.452938] RAX: 000000000000003c RBX: 0000000000000000 RCX: 0000000000000000
+[ 521.453262] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffb1af84eb3978
+[ 521.453584] RBP: ffffb1af84eb3a30 R08: 0000000000000001 R09: ffff8f88ab8a4ba0
+[ 521.453905] R10: 0000000000000000 R11: 0000000000000001 R12: ffff8f88ab8a4b18
+[ 521.454224] R13: ffff8f8699093000 R14: 0000000000000001 R15: ffffb1af84eb3970
+[ 521.454549] FS: 00005640b6b0b580(0000) GS:ffff8f88b3880000(0000) knlGS:0000000000000000
+[ 521.454912] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 521.455170] CR2: 00007ffcbcae4e38 CR3: 00000002e46de001 CR4: 0000000000770ee0
+[ 521.455491] PKRU: 55555554
+[ 521.455619] Call Trace:
+[ 521.455736] <TASK>
+[ 521.455837] ? bfq_request_merge+0x3a/0xc0
+[ 521.456027] ? elv_merge+0x115/0x140
+[ 521.456191] bfq_limit_depth+0xc8/0x240
+[ 521.456366] __blk_mq_alloc_requests+0x21a/0x2c0
+[ 521.456577] blk_mq_submit_bio+0x23c/0x6c0
+[ 521.456766] __submit_bio+0xb8/0x140
+[ 521.457236] submit_bio_noacct_nocheck+0x212/0x300
+[ 521.457748] submit_bio_noacct+0x1a6/0x580
+[ 521.458220] submit_bio+0x43/0x80
+[ 521.458660] ext4_io_submit+0x23/0x80
+[ 521.459116] ext4_do_writepages+0x40a/0xd00
+[ 521.459596] ext4_writepages+0x65/0x100
+[ 521.460050] do_writepages+0xb7/0x1c0
+[ 521.460492] __filemap_fdatawrite_range+0xa6/0x100
+[ 521.460979] file_write_and_wait_range+0xbf/0x140
+[ 521.461452] ext4_sync_file+0x105/0x340
+[ 521.461882] __x64_sys_fsync+0x67/0x100
+[ 521.462305] ? syscall_exit_to_user_mode+0x2c/0x1c0
+[ 521.462768] do_syscall_64+0x3b/0xc0
+[ 521.463165] entry_SYSCALL_64_after_hwframe+0x5a/0xc4
+[ 521.463621] RIP: 0033:0x5640b6c56590
+[ 521.464006] Code: 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 80 3d 71 70 0e 00 00 74 17 b8 4a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 48 c3 0f 1f 80 00 00 00 00 48 83 ec 18 89 7c
+
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Link: https://lore.kernel.org/r/20230413133009.1605335-1-colin.i.king@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bfq-iosched.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index ff9d238894157..52eb79d60a3f3 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -637,6 +637,8 @@ static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit)
+ sched_data->service_tree[i].wsum;
+ }
+ }
++ if (!wsum)
++ continue;
+ limit = DIV_ROUND_CLOSEST(limit * entity->weight, wsum);
+ if (entity->allocated >= limit) {
+ bfq_log_bfqq(bfqq->bfqd, bfqq,
+--
+2.39.2
+
--- /dev/null
+From dc2e9542e8e68cc59f4662d19ff217bae05810a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 23:17:30 +0100
+Subject: Bluetooth: Add new quirk for broken local ext features page 2
+
+From: Vasily Khoruzhick <anarsoul@gmail.com>
+
+[ Upstream commit 8194f1ef5a815aea815a91daf2c721eab2674f1f ]
+
+Some adapters (e.g. RTL8723CS) advertise that they have more than
+2 pages for local ext features, but they don't support any features
+declared in these pages. RTL8723CS reports max_page = 2 and declares
+support for sync train and secure connection, but it responds with
+either garbage or with error in status on corresponding commands.
+
+Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
+Signed-off-by: Bastian Germann <bage@debian.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci.h | 7 +++++++
+ net/bluetooth/hci_event.c | 9 +++++++--
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index 7a381fcef939d..f80ae7d237342 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -294,6 +294,13 @@ enum {
+ * during the hdev->setup vendor callback.
+ */
+ HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG,
++
++ /* When this quirk is set, max_page for local extended features
++ * is set to 1, even if controller reports higher number. Some
++ * controllers (e.g. RTL8723CS) report more pages, but they
++ * don't actually support features declared there.
++ */
++ HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2,
+ };
+
+ /* HCI device flags */
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 42a3a19b111e3..21416ccc30ab2 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -881,8 +881,13 @@ static u8 hci_cc_read_local_ext_features(struct hci_dev *hdev, void *data,
+ if (rp->status)
+ return rp->status;
+
+- if (hdev->max_page < rp->max_page)
+- hdev->max_page = rp->max_page;
++ if (hdev->max_page < rp->max_page) {
++ if (test_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2,
++ &hdev->quirks))
++ bt_dev_warn(hdev, "broken local ext features page 2");
++ else
++ hdev->max_page = rp->max_page;
++ }
+
+ if (rp->page < HCI_MAX_PAGES)
+ memcpy(hdev->features[rp->page], rp->features, 8);
+--
+2.39.2
+
--- /dev/null
+From 03ebf2d0e774f5ca5d0fd0e152b6604cf873200a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Mar 2023 10:45:39 -0300
+Subject: Bluetooth: Add new quirk for broken set random RPA timeout for
+ ATS2851
+
+From: Raul Cheleguini <raul.cheleguini@gmail.com>
+
+[ Upstream commit 91b6d02ddcd113352bdd895990b252065c596de7 ]
+
+The ATS2851 based controller advertises support for command "LE Set Random
+Private Address Timeout" but does not actually implement it, impeding the
+controller initialization.
+
+Add the quirk HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT to unblock the controller
+initialization.
+
+< HCI Command: LE Set Resolvable Private... (0x08|0x002e) plen 2
+ Timeout: 900 seconds
+> HCI Event: Command Status (0x0f) plen 4
+ LE Set Resolvable Private Address Timeout (0x08|0x002e) ncmd 1
+ Status: Unknown HCI Command (0x01)
+
+Co-developed-by: imoc <wzj9912@gmail.com>
+Signed-off-by: imoc <wzj9912@gmail.com>
+Signed-off-by: Raul Cheleguini <raul.cheleguini@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 1 +
+ include/net/bluetooth/hci.h | 8 ++++++++
+ net/bluetooth/hci_sync.c | 6 +++++-
+ 3 files changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 3991dcd2ebf79..faad19b396d50 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4020,6 +4020,7 @@ static int btusb_probe(struct usb_interface *intf,
+ /* Support is advertised, but not implemented */
+ set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+ set_bit(HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, &hdev->quirks);
++ set_bit(HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT, &hdev->quirks);
+ set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks);
+ }
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index f80ae7d237342..b350d92136c8d 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -301,6 +301,14 @@ enum {
+ * don't actually support features declared there.
+ */
+ HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2,
++
++ /*
++ * When this quirk is set, the HCI_OP_LE_SET_RPA_TIMEOUT command is
++ * skipped during initialization. This is required for the Actions
++ * Semiconductor ATS2851 based controllers, which erroneously claims
++ * to support it.
++ */
++ HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT,
+ };
+
+ /* HCI device flags */
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 9361fb3685cc7..e8b78104a4071 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -4075,7 +4075,8 @@ static int hci_le_set_rpa_timeout_sync(struct hci_dev *hdev)
+ {
+ __le16 timeout = cpu_to_le16(hdev->rpa_timeout);
+
+- if (!(hdev->commands[35] & 0x04))
++ if (!(hdev->commands[35] & 0x04) ||
++ test_bit(HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT, &hdev->quirks))
+ return 0;
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_RPA_TIMEOUT,
+@@ -4515,6 +4516,9 @@ static const struct {
+ "HCI Set Event Filter command not supported."),
+ HCI_QUIRK_BROKEN(ENHANCED_SETUP_SYNC_CONN,
+ "HCI Enhanced Setup Synchronous Connection command is "
++ "advertised, but not supported."),
++ HCI_QUIRK_BROKEN(SET_RPA_TIMEOUT,
++ "HCI LE Set Random Private Address Timeout command is "
+ "advertised, but not supported.")
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 385c9b2b80539422a6422b9147c518d72aa1751f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Mar 2023 10:03:10 +0530
+Subject: Bluetooth: btintel: Add LE States quirk support
+
+From: Chethan T N <chethan.tumkur.narayan@intel.com>
+
+[ Upstream commit 77f542b10c535c9a93bf8afdd2665524935807c2 ]
+
+Basically all Intel controllers support both Central/Peripheral
+LE states.
+
+This patch enables the LE States quirk by default on all
+Solar and Magnertor Intel controllers.
+
+Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btintel.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
+index f6b4b7a1be4cc..bbad1207cdfd8 100644
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -2553,9 +2553,8 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ */
+ set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
+
+- /* Valid LE States quirk for GfP */
+- if (INTEL_HW_VARIANT(ver_tlv.cnvi_bt) == 0x18)
+- set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
++ /* Apply LE States quirk from solar onwards */
++ set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
+
+ /* Setup MSFT Extension support */
+ btintel_set_msft_opcode(hdev,
+--
+2.39.2
+
--- /dev/null
+From 167f13e380f2db817b71e03be682d87cb8f7b623 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 23:17:31 +0100
+Subject: Bluetooth: btrtl: add support for the RTL8723CS
+
+From: Vasily Khoruzhick <anarsoul@gmail.com>
+
+[ Upstream commit c0123cb6c4c7fc2a42ead6cd7d3e82b8e1c25c6f ]
+
+The Realtek RTL8723CS is a SDIO WiFi chip. It also contains a Bluetooth
+module which is connected via UART to the host.
+
+It shares lmp subversion with 8703B, so Realtek's userspace
+initialization tool (rtk_hciattach) differentiates varieties of RTL8723CS
+(CG, VF, XX) with RTL8703B using vendor's command to read chip type.
+
+Also this chip declares support for some features it doesn't support
+so add a quirk to indicate that these features are broken.
+
+Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
+Signed-off-by: Bastian Germann <bage@debian.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btrtl.c | 120 +++++++++++++++++++++++++++++++++++--
+ drivers/bluetooth/btrtl.h | 5 ++
+ drivers/bluetooth/hci_h5.c | 4 ++
+ 3 files changed, 125 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
+index fb52313a1d45a..6b3755345427a 100644
+--- a/drivers/bluetooth/btrtl.c
++++ b/drivers/bluetooth/btrtl.c
+@@ -17,7 +17,11 @@
+
+ #define VERSION "0.1"
+
++#define RTL_CHIP_8723CS_CG 3
++#define RTL_CHIP_8723CS_VF 4
++#define RTL_CHIP_8723CS_XX 5
+ #define RTL_EPATCH_SIGNATURE "Realtech"
++#define RTL_ROM_LMP_8703B 0x8703
+ #define RTL_ROM_LMP_8723A 0x1200
+ #define RTL_ROM_LMP_8723B 0x8723
+ #define RTL_ROM_LMP_8821A 0x8821
+@@ -30,6 +34,7 @@
+ #define IC_MATCH_FL_HCIREV (1 << 1)
+ #define IC_MATCH_FL_HCIVER (1 << 2)
+ #define IC_MATCH_FL_HCIBUS (1 << 3)
++#define IC_MATCH_FL_CHIP_TYPE (1 << 4)
+ #define IC_INFO(lmps, hcir, hciv, bus) \
+ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV | \
+ IC_MATCH_FL_HCIVER | IC_MATCH_FL_HCIBUS, \
+@@ -59,6 +64,7 @@ struct id_table {
+ __u16 hci_rev;
+ __u8 hci_ver;
+ __u8 hci_bus;
++ __u8 chip_type;
+ bool config_needed;
+ bool has_rom_version;
+ bool has_msft_ext;
+@@ -99,6 +105,39 @@ static const struct id_table ic_id_table[] = {
+ .fw_name = "rtl_bt/rtl8723b_fw.bin",
+ .cfg_name = "rtl_bt/rtl8723b_config" },
+
++ /* 8723CS-CG */
++ { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
++ IC_MATCH_FL_HCIBUS,
++ .lmp_subver = RTL_ROM_LMP_8703B,
++ .chip_type = RTL_CHIP_8723CS_CG,
++ .hci_bus = HCI_UART,
++ .config_needed = true,
++ .has_rom_version = true,
++ .fw_name = "rtl_bt/rtl8723cs_cg_fw.bin",
++ .cfg_name = "rtl_bt/rtl8723cs_cg_config" },
++
++ /* 8723CS-VF */
++ { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
++ IC_MATCH_FL_HCIBUS,
++ .lmp_subver = RTL_ROM_LMP_8703B,
++ .chip_type = RTL_CHIP_8723CS_VF,
++ .hci_bus = HCI_UART,
++ .config_needed = true,
++ .has_rom_version = true,
++ .fw_name = "rtl_bt/rtl8723cs_vf_fw.bin",
++ .cfg_name = "rtl_bt/rtl8723cs_vf_config" },
++
++ /* 8723CS-XX */
++ { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
++ IC_MATCH_FL_HCIBUS,
++ .lmp_subver = RTL_ROM_LMP_8703B,
++ .chip_type = RTL_CHIP_8723CS_XX,
++ .hci_bus = HCI_UART,
++ .config_needed = true,
++ .has_rom_version = true,
++ .fw_name = "rtl_bt/rtl8723cs_xx_fw.bin",
++ .cfg_name = "rtl_bt/rtl8723cs_xx_config" },
++
+ /* 8723D */
+ { IC_INFO(RTL_ROM_LMP_8723B, 0xd, 0x8, HCI_USB),
+ .config_needed = true,
+@@ -208,7 +247,8 @@ static const struct id_table ic_id_table[] = {
+ };
+
+ static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
+- u8 hci_ver, u8 hci_bus)
++ u8 hci_ver, u8 hci_bus,
++ u8 chip_type)
+ {
+ int i;
+
+@@ -225,6 +265,9 @@ static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
+ if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIBUS) &&
+ (ic_id_table[i].hci_bus != hci_bus))
+ continue;
++ if ((ic_id_table[i].match_flags & IC_MATCH_FL_CHIP_TYPE) &&
++ (ic_id_table[i].chip_type != chip_type))
++ continue;
+
+ break;
+ }
+@@ -307,6 +350,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
+ { RTL_ROM_LMP_8723B, 1 },
+ { RTL_ROM_LMP_8821A, 2 },
+ { RTL_ROM_LMP_8761A, 3 },
++ { RTL_ROM_LMP_8703B, 7 },
+ { RTL_ROM_LMP_8822B, 8 },
+ { RTL_ROM_LMP_8723B, 9 }, /* 8723D */
+ { RTL_ROM_LMP_8821A, 10 }, /* 8821C */
+@@ -587,6 +631,48 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev,
+ return ret;
+ }
+
++static bool rtl_has_chip_type(u16 lmp_subver)
++{
++ switch (lmp_subver) {
++ case RTL_ROM_LMP_8703B:
++ return true;
++ default:
++ break;
++ }
++
++ return false;
++}
++
++static int rtl_read_chip_type(struct hci_dev *hdev, u8 *type)
++{
++ struct rtl_chip_type_evt *chip_type;
++ struct sk_buff *skb;
++ const unsigned char cmd_buf[] = {0x00, 0x94, 0xa0, 0x00, 0xb0};
++
++ /* Read RTL chip type command */
++ skb = __hci_cmd_sync(hdev, 0xfc61, 5, cmd_buf, HCI_INIT_TIMEOUT);
++ if (IS_ERR(skb)) {
++ rtl_dev_err(hdev, "Read chip type failed (%ld)",
++ PTR_ERR(skb));
++ return PTR_ERR(skb);
++ }
++
++ chip_type = skb_pull_data(skb, sizeof(*chip_type));
++ if (!chip_type) {
++ rtl_dev_err(hdev, "RTL chip type event length mismatch");
++ kfree_skb(skb);
++ return -EIO;
++ }
++
++ rtl_dev_info(hdev, "chip_type status=%x type=%x",
++ chip_type->status, chip_type->type);
++
++ *type = chip_type->type & 0x0f;
++
++ kfree_skb(skb);
++ return 0;
++}
++
+ void btrtl_free(struct btrtl_device_info *btrtl_dev)
+ {
+ kvfree(btrtl_dev->fw_data);
+@@ -603,7 +689,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
+ struct hci_rp_read_local_version *resp;
+ char cfg_name[40];
+ u16 hci_rev, lmp_subver;
+- u8 hci_ver;
++ u8 hci_ver, chip_type = 0;
+ int ret;
+ u16 opcode;
+ u8 cmd[2];
+@@ -629,8 +715,14 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
+ hci_rev = le16_to_cpu(resp->hci_rev);
+ lmp_subver = le16_to_cpu(resp->lmp_subver);
+
++ if (rtl_has_chip_type(lmp_subver)) {
++ ret = rtl_read_chip_type(hdev, &chip_type);
++ if (ret)
++ goto err_free;
++ }
++
+ btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver,
+- hdev->bus);
++ hdev->bus, chip_type);
+
+ if (!btrtl_dev->ic_info)
+ btrtl_dev->drop_fw = true;
+@@ -673,7 +765,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
+ lmp_subver = le16_to_cpu(resp->lmp_subver);
+
+ btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver,
+- hdev->bus);
++ hdev->bus, chip_type);
+ }
+ out_free:
+ kfree_skb(skb);
+@@ -755,6 +847,7 @@ int btrtl_download_firmware(struct hci_dev *hdev,
+ case RTL_ROM_LMP_8761A:
+ case RTL_ROM_LMP_8822B:
+ case RTL_ROM_LMP_8852A:
++ case RTL_ROM_LMP_8703B:
+ return btrtl_setup_rtl8723b(hdev, btrtl_dev);
+ default:
+ rtl_dev_info(hdev, "assuming no firmware upload needed");
+@@ -788,6 +881,19 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
+ rtl_dev_dbg(hdev, "WBS supported not enabled.");
+ break;
+ }
++
++ switch (btrtl_dev->ic_info->lmp_subver) {
++ case RTL_ROM_LMP_8703B:
++ /* 8723CS reports two pages for local ext features,
++ * but it doesn't support any features from page 2 -
++ * it either responds with garbage or with error status
++ */
++ set_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2,
++ &hdev->quirks);
++ break;
++ default:
++ break;
++ }
+ }
+ EXPORT_SYMBOL_GPL(btrtl_set_quirks);
+
+@@ -946,6 +1052,12 @@ MODULE_FIRMWARE("rtl_bt/rtl8723b_fw.bin");
+ MODULE_FIRMWARE("rtl_bt/rtl8723b_config.bin");
+ MODULE_FIRMWARE("rtl_bt/rtl8723bs_fw.bin");
+ MODULE_FIRMWARE("rtl_bt/rtl8723bs_config.bin");
++MODULE_FIRMWARE("rtl_bt/rtl8723cs_cg_fw.bin");
++MODULE_FIRMWARE("rtl_bt/rtl8723cs_cg_config.bin");
++MODULE_FIRMWARE("rtl_bt/rtl8723cs_vf_fw.bin");
++MODULE_FIRMWARE("rtl_bt/rtl8723cs_vf_config.bin");
++MODULE_FIRMWARE("rtl_bt/rtl8723cs_xx_fw.bin");
++MODULE_FIRMWARE("rtl_bt/rtl8723cs_xx_config.bin");
+ MODULE_FIRMWARE("rtl_bt/rtl8723ds_fw.bin");
+ MODULE_FIRMWARE("rtl_bt/rtl8723ds_config.bin");
+ MODULE_FIRMWARE("rtl_bt/rtl8761a_fw.bin");
+diff --git a/drivers/bluetooth/btrtl.h b/drivers/bluetooth/btrtl.h
+index 2c441bda390a0..1c6282241d2d2 100644
+--- a/drivers/bluetooth/btrtl.h
++++ b/drivers/bluetooth/btrtl.h
+@@ -14,6 +14,11 @@
+
+ struct btrtl_device_info;
+
++struct rtl_chip_type_evt {
++ __u8 status;
++ __u8 type;
++} __packed;
++
+ struct rtl_download_cmd {
+ __u8 index;
+ __u8 data[RTL_FRAG_LEN];
+diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
+index 6455bc4fb5bb3..e90670955df2c 100644
+--- a/drivers/bluetooth/hci_h5.c
++++ b/drivers/bluetooth/hci_h5.c
+@@ -936,6 +936,8 @@ static int h5_btrtl_setup(struct h5 *h5)
+ err = btrtl_download_firmware(h5->hu->hdev, btrtl_dev);
+ /* Give the device some time before the hci-core sends it a reset */
+ usleep_range(10000, 20000);
++ if (err)
++ goto out_free;
+
+ btrtl_set_quirks(h5->hu->hdev, btrtl_dev);
+
+@@ -1100,6 +1102,8 @@ static const struct of_device_id rtl_bluetooth_of_match[] = {
+ .data = (const void *)&h5_data_rtl8822cs },
+ { .compatible = "realtek,rtl8723bs-bt",
+ .data = (const void *)&h5_data_rtl8723bs },
++ { .compatible = "realtek,rtl8723cs-bt",
++ .data = (const void *)&h5_data_rtl8723bs },
+ { .compatible = "realtek,rtl8723ds-bt",
+ .data = (const void *)&h5_data_rtl8723bs },
+ #endif
+--
+2.39.2
+
--- /dev/null
+From fe155f88efbbdb8e13ca56005282af6e9b352e1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Apr 2023 13:43:54 +0800
+Subject: Bluetooth: btrtl: Add the support for RTL8851B
+
+From: Max Chou <max.chou@realtek.com>
+
+[ Upstream commit 7948fe1c92d92313eea5453f83deb7f0141355e8 ]
+
+Add the support for RTL8851B BT controller on USB interface.
+The necessary firmware will be submitted to linux-firmware project.
+
+Note that the Bluetooth devices WITH the VID=0x0bda would be set the
+feature quirk in btrtl_setup_realtek(). It's able to ignore the
+feature flag set for the specific VID and PID in blacklist_table[] of
+btusb.c. (check [1])
+
+If Realtek Bluetooth chips WITHOUT the VID=0x0bda, it shall be added
+the feature flag for the specific VID and PID in blacklist_table[] of
+btusb.c. (check [2])
+
+[1] '9ab9235fe5cf ("Bluetooth: btrtl: Enable WBS for the specific
+ Realtek devices")'
+[2] '73280f13c9bb ("Bluetooth: btusb: Add the more support IDs for
+ Realtek RTL8822CE")'
+
+The device info from /sys/kernel/debug/usb/devices as below.
+
+T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 33 Spd=480 MxCh= 0
+D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
+P: Vendor=0bda ProdID=b851 Rev= 0.00
+S: Manufacturer=Realtek
+S: Product=802.11ax WLAN Adapter
+S: SerialNumber=00E04C885A01
+C:* #Ifs= 3 Cfg#= 1 Atr=80 MxPwr=500mA
+A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=01
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+I:* If#= 2 Alt= 0 #EPs= 8 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
+E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=09(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+Signed-off-by: Max Chou <max.chou@realtek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btrtl.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
+index 88f8c604d70a2..ead632595ce06 100644
+--- a/drivers/bluetooth/btrtl.c
++++ b/drivers/bluetooth/btrtl.c
+@@ -28,6 +28,7 @@
+ #define RTL_ROM_LMP_8761A 0x8761
+ #define RTL_ROM_LMP_8822B 0x8822
+ #define RTL_ROM_LMP_8852A 0x8852
++#define RTL_ROM_LMP_8851B 0x8851
+ #define RTL_CONFIG_MAGIC 0x8723ab55
+
+ #define IC_MATCH_FL_LMPSUBV (1 << 0)
+@@ -56,6 +57,7 @@ enum btrtl_chip_id {
+ CHIP_ID_8852A = 18,
+ CHIP_ID_8852B = 20,
+ CHIP_ID_8852C = 25,
++ CHIP_ID_8851B = 36,
+ };
+
+ struct id_table {
+@@ -244,6 +246,14 @@ static const struct id_table ic_id_table[] = {
+ .has_msft_ext = true,
+ .fw_name = "rtl_bt/rtl8852cu_fw.bin",
+ .cfg_name = "rtl_bt/rtl8852cu_config" },
++
++ /* 8851B */
++ { IC_INFO(RTL_ROM_LMP_8851B, 0xb, 0xc, HCI_USB),
++ .config_needed = false,
++ .has_rom_version = true,
++ .has_msft_ext = false,
++ .fw_name = "rtl_bt/rtl8851bu_fw.bin",
++ .cfg_name = "rtl_bt/rtl8851bu_config" },
+ };
+
+ static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
+@@ -359,6 +369,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
+ { RTL_ROM_LMP_8852A, 18 }, /* 8852A */
+ { RTL_ROM_LMP_8852A, 20 }, /* 8852B */
+ { RTL_ROM_LMP_8852A, 25 }, /* 8852C */
++ { RTL_ROM_LMP_8851B, 36 }, /* 8851B */
+ };
+
+ min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
+@@ -848,6 +859,7 @@ int btrtl_download_firmware(struct hci_dev *hdev,
+ case RTL_ROM_LMP_8822B:
+ case RTL_ROM_LMP_8852A:
+ case RTL_ROM_LMP_8703B:
++ case RTL_ROM_LMP_8851B:
+ return btrtl_setup_rtl8723b(hdev, btrtl_dev);
+ default:
+ rtl_dev_info(hdev, "assuming no firmware upload needed");
+@@ -872,6 +884,7 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
+ case CHIP_ID_8852A:
+ case CHIP_ID_8852B:
+ case CHIP_ID_8852C:
++ case CHIP_ID_8851B:
+ set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
+ set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
+ hci_set_aosp_capable(hdev);
+@@ -1075,3 +1088,5 @@ MODULE_FIRMWARE("rtl_bt/rtl8852bu_fw.bin");
+ MODULE_FIRMWARE("rtl_bt/rtl8852bu_config.bin");
+ MODULE_FIRMWARE("rtl_bt/rtl8852cu_fw.bin");
+ MODULE_FIRMWARE("rtl_bt/rtl8852cu_config.bin");
++MODULE_FIRMWARE("rtl_bt/rtl8851bu_fw.bin");
++MODULE_FIRMWARE("rtl_bt/rtl8851bu_config.bin");
+--
+2.39.2
+
--- /dev/null
+From a6f36e35e162346f7978a4558f67f905c6361358 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Mar 2023 19:48:26 +0800
+Subject: Bluetooth: btrtl: check for NULL in btrtl_set_quirks()
+
+From: Max Chou <max.chou@realtek.com>
+
+[ Upstream commit 253cf30e8d3d001850a95c4729d668f916b037ab ]
+
+The btrtl_set_quirks() has accessed btrtl_dev->ic_info->lmp_subver since
+b8e482d02513. However, if installing a Realtek Bluetooth controller
+without the driver supported, it will hit the NULL point accessed.
+
+Add a check for NULL to avoid the Kernel Oops.
+
+Signed-off-by: Max Chou <max.chou@realtek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btrtl.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
+index 6b3755345427a..88f8c604d70a2 100644
+--- a/drivers/bluetooth/btrtl.c
++++ b/drivers/bluetooth/btrtl.c
+@@ -882,6 +882,9 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
+ break;
+ }
+
++ if (!btrtl_dev->ic_info)
++ return;
++
+ switch (btrtl_dev->ic_info->lmp_subver) {
+ case RTL_ROM_LMP_8703B:
+ /* 8723CS reports two pages for local ext features,
+--
+2.39.2
+
--- /dev/null
+From 753e7995846141d6b46390a0d1f9b53a60eedeec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Feb 2023 13:55:17 +0800
+Subject: Bluetooth: btusb: Add new PID/VID 04ca:3801 for MT7663
+
+From: Meng Tang <tangmeng@uniontech.com>
+
+[ Upstream commit 13209415d0e88396d99d346b184864834d70d68a ]
+
+This bluetooth device is found in a combo WLAN/BT card
+for a MediaTek 7663.
+
+Tested on Acer Aspire A315-24P Notebook
+
+The device information:
+
+T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=480 MxCh= 0
+D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
+P: Vendor=04ca ProdID=3801 Rev= 1.00
+S: Manufacturer=MediaTek Inc.
+S: Product=Wireless_Device
+S: SerialNumber=000000000
+C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
+A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=01
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us
+E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms
+E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms
+
+Signed-off-by: Meng Tang <tangmeng@uniontech.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 90b85dcb138df..8ee147ad76b79 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -549,6 +549,9 @@ static const struct usb_device_id blacklist_table[] = {
+ { USB_DEVICE(0x043e, 0x310c), .driver_info = BTUSB_MEDIATEK |
+ BTUSB_WIDEBAND_SPEECH |
+ BTUSB_VALID_LE_STATES },
++ { USB_DEVICE(0x04ca, 0x3801), .driver_info = BTUSB_MEDIATEK |
++ BTUSB_WIDEBAND_SPEECH |
++ BTUSB_VALID_LE_STATES },
+
+ /* Additional MediaTek MT7668 Bluetooth devices */
+ { USB_DEVICE(0x043e, 0x3109), .driver_info = BTUSB_MEDIATEK |
+--
+2.39.2
+
--- /dev/null
+From afe651252484db7324e7a661abdc45a0ad9071ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Mar 2023 23:11:21 +0200
+Subject: Bluetooth: hci_bcm: Fall back to getting bdaddr from EFI if not set
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 0d218c3642b9ccf71f44987cd03c19320f3bd918 ]
+
+On some devices the BCM Bluetooth adapter does not have a valid bdaddr set.
+
+btbcm.c currently sets HCI_QUIRK_INVALID_BDADDR to indicate when this is
+the case. But this requires users to manual setup a btaddr, by doing e.g.:
+
+btmgmt -i hci0 public-addr 'B0:F1:EC:82:1D:B3'
+
+Which means that Bluetooth will not work out of the box on such devices.
+To avoid this (where possible) hci_bcm sets: HCI_QUIRK_USE_BDADDR_PROPERTY
+which tries to get the bdaddr from devicetree.
+
+But this only works on devicetree platforms. On UEFI based platforms
+there is a special Broadcom UEFI variable which when present contains
+the devices bdaddr, just like how there is another UEFI variable which
+contains wifi nvram contents including the wifi MAC address.
+
+Add support for getting the bdaddr from this Broadcom UEFI variable,
+so that Bluetooth will work OOTB for users on devices where this
+UEFI variable is present.
+
+This fixes Bluetooth not working on for example Asus T100HA 2-in-1s.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btbcm.c | 47 ++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 44 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
+index 43e98a598bd9a..de2ea589aa49b 100644
+--- a/drivers/bluetooth/btbcm.c
++++ b/drivers/bluetooth/btbcm.c
+@@ -6,6 +6,7 @@
+ * Copyright (C) 2015 Intel Corporation
+ */
+
++#include <linux/efi.h>
+ #include <linux/module.h>
+ #include <linux/firmware.h>
+ #include <linux/dmi.h>
+@@ -34,6 +35,43 @@
+ /* For kmalloc-ing the fw-name array instead of putting it on the stack */
+ typedef char bcm_fw_name[BCM_FW_NAME_LEN];
+
++#ifdef CONFIG_EFI
++static int btbcm_set_bdaddr_from_efi(struct hci_dev *hdev)
++{
++ efi_guid_t guid = EFI_GUID(0x74b00bd9, 0x805a, 0x4d61, 0xb5, 0x1f,
++ 0x43, 0x26, 0x81, 0x23, 0xd1, 0x13);
++ bdaddr_t efi_bdaddr, bdaddr;
++ efi_status_t status;
++ unsigned long len;
++ int ret;
++
++ if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
++ return -EOPNOTSUPP;
++
++ len = sizeof(efi_bdaddr);
++ status = efi.get_variable(L"BDADDR", &guid, NULL, &len, &efi_bdaddr);
++ if (status != EFI_SUCCESS)
++ return -ENXIO;
++
++ if (len != sizeof(efi_bdaddr))
++ return -EIO;
++
++ baswap(&bdaddr, &efi_bdaddr);
++
++ ret = btbcm_set_bdaddr(hdev, &bdaddr);
++ if (ret)
++ return ret;
++
++ bt_dev_info(hdev, "BCM: Using EFI device address (%pMR)", &bdaddr);
++ return 0;
++}
++#else
++static int btbcm_set_bdaddr_from_efi(struct hci_dev *hdev)
++{
++ return -EOPNOTSUPP;
++}
++#endif
++
+ int btbcm_check_bdaddr(struct hci_dev *hdev)
+ {
+ struct hci_rp_read_bd_addr *bda;
+@@ -87,9 +125,12 @@ int btbcm_check_bdaddr(struct hci_dev *hdev)
+ !bacmp(&bda->bdaddr, BDADDR_BCM4345C5) ||
+ !bacmp(&bda->bdaddr, BDADDR_BCM43430A0) ||
+ !bacmp(&bda->bdaddr, BDADDR_BCM43341B)) {
+- bt_dev_info(hdev, "BCM: Using default device address (%pMR)",
+- &bda->bdaddr);
+- set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
++ /* Try falling back to BDADDR EFI variable */
++ if (btbcm_set_bdaddr_from_efi(hdev) != 0) {
++ bt_dev_info(hdev, "BCM: Using default device address (%pMR)",
++ &bda->bdaddr);
++ set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
++ }
+ }
+
+ kfree_skb(skb);
+--
+2.39.2
+
--- /dev/null
+From 968ae72ea233d2fa036f95d6676c865f8bf40742 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Mar 2023 15:14:10 +0000
+Subject: Bluetooth: Improve support for Actions Semi ATS2851 based devices
+
+From: Raul Cheleguini <rcheleguini@google.com>
+
+[ Upstream commit 7c2b2d2d0cb658aa543e11e90ae95621d3cb5fe6 ]
+
+Add two more quirks to resume the device initialization and basic
+operation as the device seems not to support "Read Transmit Power"
+and "Set Extended Scan Parameters".
+
+< HCI Command: LE Read Transmit Power (0x08|0x004b) plen 0
+> HCI Event: Command Status (0x0f) plen 4
+ LE Read Transmit Power (0x08|0x004b) ncmd 1
+ Status: Unknown HCI Command (0x01)
+
+< HCI Command: LE Set Extended Scan Parameters (0x08|0x0041) plen 8
+ Own address type: Random (0x01)
+ Filter policy: Accept all advertisement (0x00)
+ PHYs: 0x01
+ Entry 0: LE 1M
+ Type: Active (0x01)
+ Interval: 11.250 msec (0x0012)
+ Window: 11.250 msec (0x0012)
+> HCI Event: Command Status (0x0f) plen 4
+ LE Set Extended Scan Parameters (0x08|0x0041) ncmd 1
+ Status: Unknown HCI Command (0x01)
+
+Signed-off-by: Raul Cheleguini <rcheleguini@google.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 8ee147ad76b79..3991dcd2ebf79 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4019,6 +4019,8 @@ static int btusb_probe(struct usb_interface *intf,
+ if (id->driver_info & BTUSB_ACTIONS_SEMI) {
+ /* Support is advertised, but not implemented */
+ set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
++ set_bit(HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, &hdev->quirks);
++ set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks);
+ }
+
+ if (!reset)
+--
+2.39.2
+
--- /dev/null
+From 876dfc5c1f4a3d3e843be0112150042092dead7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 10:27:54 +0800
+Subject: Bluetooth: L2CAP: fix "bad unlock balance" in l2cap_disconnect_rsp
+
+From: Min Li <lm0963hack@gmail.com>
+
+[ Upstream commit 25e97f7b1866e6b8503be349eeea44bb52d661ce ]
+
+conn->chan_lock isn't acquired before l2cap_get_chan_by_scid,
+if l2cap_get_chan_by_scid returns NULL, then 'bad unlock balance'
+is triggered.
+
+Reported-by: syzbot+9519d6b5b79cf7787cf3@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/000000000000894f5f05f95e9f4d@google.com/
+Signed-off-by: Min Li <lm0963hack@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index e62dadad81b31..ee8f806534dfb 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -4694,7 +4694,6 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
+
+ chan = l2cap_get_chan_by_scid(conn, scid);
+ if (!chan) {
+- mutex_unlock(&conn->chan_lock);
+ return 0;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 30160327f5352d586313158c5b6a20bece05b685 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Mar 2023 20:43:47 +0300
+Subject: bnxt: avoid overflow in bnxt_get_nvram_directory()
+
+From: Maxim Korotkov <korotkov.maxim.s@gmail.com>
+
+[ Upstream commit 7c6dddc239abe660598c49ec95ea0ed6399a4b2a ]
+
+The value of an arithmetic expression is subject
+of possible overflow due to a failure to cast operands to a larger data
+type before performing arithmetic. Used macro for multiplication instead
+operator for avoiding overflow.
+
+Found by Security Code and Linux Verification
+Center (linuxtesting.org) with SVACE.
+
+Signed-off-by: Maxim Korotkov <korotkov.maxim.s@gmail.com>
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Link: https://lore.kernel.org/r/20230309174347.3515-1-korotkov.maxim.s@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+index 01b973bc509f5..b2d531e014c57 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+@@ -2822,7 +2822,7 @@ static int bnxt_get_nvram_directory(struct net_device *dev, u32 len, u8 *data)
+ if (rc)
+ return rc;
+
+- buflen = dir_entries * entry_length;
++ buflen = mul_u32_u32(dir_entries, entry_length);
+ buf = hwrm_req_dma_slice(bp, req, buflen, &dma_handle);
+ if (!buf) {
+ hwrm_req_drop(bp, req);
+--
+2.39.2
+
--- /dev/null
+From 2c95642ad283cf0e0d1a667dd2eb727f78dd5673 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Apr 2023 02:52:48 +0000
+Subject: bpf: Add preempt_count_{sub,add} into btf id deny list
+
+From: Yafang <laoar.shao@gmail.com>
+
+[ Upstream commit c11bd046485d7bf1ca200db0e7d0bdc4bafdd395 ]
+
+The recursion check in __bpf_prog_enter* and __bpf_prog_exit*
+leave preempt_count_{sub,add} unprotected. When attaching trampoline to
+them we get panic as follows,
+
+[ 867.843050] BUG: TASK stack guard page was hit at 0000000009d325cf (stack is 0000000046a46a15..00000000537e7b28)
+[ 867.843064] stack guard page: 0000 [#1] PREEMPT SMP NOPTI
+[ 867.843067] CPU: 8 PID: 11009 Comm: trace Kdump: loaded Not tainted 6.2.0+ #4
+[ 867.843100] Call Trace:
+[ 867.843101] <TASK>
+[ 867.843104] asm_exc_int3+0x3a/0x40
+[ 867.843108] RIP: 0010:preempt_count_sub+0x1/0xa0
+[ 867.843135] __bpf_prog_enter_recur+0x17/0x90
+[ 867.843148] bpf_trampoline_6442468108_0+0x2e/0x1000
+[ 867.843154] ? preempt_count_sub+0x1/0xa0
+[ 867.843157] preempt_count_sub+0x5/0xa0
+[ 867.843159] ? migrate_enable+0xac/0xf0
+[ 867.843164] __bpf_prog_exit_recur+0x2d/0x40
+[ 867.843168] bpf_trampoline_6442468108_0+0x55/0x1000
+...
+[ 867.843788] preempt_count_sub+0x5/0xa0
+[ 867.843793] ? migrate_enable+0xac/0xf0
+[ 867.843829] __bpf_prog_exit_recur+0x2d/0x40
+[ 867.843837] BUG: IRQ stack guard page was hit at 0000000099bd8228 (stack is 00000000b23e2bc4..000000006d95af35)
+[ 867.843841] BUG: IRQ stack guard page was hit at 000000005ae07924 (stack is 00000000ffd69623..0000000014eb594c)
+[ 867.843843] BUG: IRQ stack guard page was hit at 00000000028320f0 (stack is 00000000034b6438..0000000078d1bcec)
+[ 867.843842] bpf_trampoline_6442468108_0+0x55/0x1000
+...
+
+That is because in __bpf_prog_exit_recur, the preempt_count_{sub,add} are
+called after prog->active is decreased.
+
+Fixing this by adding these two functions into btf ids deny list.
+
+Suggested-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Yafang <laoar.shao@gmail.com>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Jiri Olsa <olsajiri@gmail.com>
+Acked-by: Hao Luo <haoluo@google.com>
+Link: https://lore.kernel.org/r/20230413025248.79764-1-laoar.shao@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 8726161076134..322a2ae8f88b0 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -15133,6 +15133,10 @@ BTF_ID(func, migrate_enable)
+ #if !defined CONFIG_PREEMPT_RCU && !defined CONFIG_TINY_RCU
+ BTF_ID(func, rcu_read_unlock_strict)
+ #endif
++#if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_TRACE_PREEMPT_TOGGLE)
++BTF_ID(func, preempt_count_add)
++BTF_ID(func, preempt_count_sub)
++#endif
+ BTF_SET_END(btf_id_deny)
+
+ static int check_attach_btf_id(struct bpf_verifier_env *env)
+--
+2.39.2
+
--- /dev/null
+From 206b702cb2c980bd6f6c51ae33779ea9384d50fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Feb 2023 21:06:42 +0100
+Subject: bpf: Annotate data races in bpf_local_storage
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit 0a09a2f933c73dc76ab0b72da6855f44342a8903 ]
+
+There are a few cases where hlist_node is checked to be unhashed without
+holding the lock protecting its modification. In this case, one must use
+hlist_unhashed_lockless to avoid load tearing and KCSAN reports. Fix
+this by using lockless variant in places not protected by the lock.
+
+Since this is not prompted by any actual KCSAN reports but only from
+code review, I have not included a fixes tag.
+
+Cc: Martin KaFai Lau <martin.lau@kernel.org>
+Cc: KP Singh <kpsingh@kernel.org>
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Link: https://lore.kernel.org/r/20230221200646.2500777-4-memxor@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/bpf_local_storage.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c
+index f27fa5ba7d722..d9d88a2cda5e5 100644
+--- a/kernel/bpf/bpf_local_storage.c
++++ b/kernel/bpf/bpf_local_storage.c
+@@ -51,11 +51,21 @@ owner_storage(struct bpf_local_storage_map *smap, void *owner)
+ return map->ops->map_owner_storage_ptr(owner);
+ }
+
++static bool selem_linked_to_storage_lockless(const struct bpf_local_storage_elem *selem)
++{
++ return !hlist_unhashed_lockless(&selem->snode);
++}
++
+ static bool selem_linked_to_storage(const struct bpf_local_storage_elem *selem)
+ {
+ return !hlist_unhashed(&selem->snode);
+ }
+
++static bool selem_linked_to_map_lockless(const struct bpf_local_storage_elem *selem)
++{
++ return !hlist_unhashed_lockless(&selem->map_node);
++}
++
+ static bool selem_linked_to_map(const struct bpf_local_storage_elem *selem)
+ {
+ return !hlist_unhashed(&selem->map_node);
+@@ -165,7 +175,7 @@ static void __bpf_selem_unlink_storage(struct bpf_local_storage_elem *selem,
+ bool free_local_storage = false;
+ unsigned long flags;
+
+- if (unlikely(!selem_linked_to_storage(selem)))
++ if (unlikely(!selem_linked_to_storage_lockless(selem)))
+ /* selem has already been unlinked from sk */
+ return;
+
+@@ -199,7 +209,7 @@ void bpf_selem_unlink_map(struct bpf_local_storage_elem *selem)
+ struct bpf_local_storage_map_bucket *b;
+ unsigned long flags;
+
+- if (unlikely(!selem_linked_to_map(selem)))
++ if (unlikely(!selem_linked_to_map_lockless(selem)))
+ /* selem has already be unlinked from smap */
+ return;
+
+@@ -410,7 +420,7 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap,
+ err = check_flags(old_sdata, map_flags);
+ if (err)
+ return ERR_PTR(err);
+- if (old_sdata && selem_linked_to_storage(SELEM(old_sdata))) {
++ if (old_sdata && selem_linked_to_storage_lockless(SELEM(old_sdata))) {
+ copy_map_value_locked(&smap->map, old_sdata->data,
+ value, false);
+ return old_sdata;
+--
+2.39.2
+
--- /dev/null
+From a3aa043c1b9ac3447d01848e246b1fd043138e36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Mar 2023 09:03:52 +0200
+Subject: crypto: jitter - permanent and intermittent health errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Stephan Müller <smueller@chronox.de>
+
+[ Upstream commit 3fde2fe99aa6dacd4151c87382b07ce7f30f0a52 ]
+
+According to SP800-90B, two health failures are allowed: the intermittend
+and the permanent failure. So far, only the intermittent failure was
+implemented. The permanent failure was achieved by resetting the entire
+entropy source including its health test state and waiting for two or
+more back-to-back health errors.
+
+This approach is appropriate for RCT, but not for APT as APT has a
+non-linear cutoff value. Thus, this patch implements 2 cutoff values
+for both RCT/APT. This implies that the health state is left untouched
+when an intermittent failure occurs. The noise source is reset
+and a new APT powerup-self test is performed. Yet, whith the unchanged
+health test state, the counting of failures continues until a permanent
+failure is reached.
+
+Any non-failing raw entropy value causes the health tests to reset.
+
+The intermittent error has an unchanged significance level of 2^-30.
+The permanent error has a significance level of 2^-60. Considering that
+this level also indicates a false-positive rate (see SP800-90B section 4.2)
+a false-positive must only be incurred with a low probability when
+considering a fleet of Linux kernels as a whole. Hitting the permanent
+error may cause a panic(), the following calculation applies: Assuming
+that a fleet of 10^9 Linux kernels run concurrently with this patch in
+FIPS mode and on each kernel 2 health tests are performed every minute
+for one year, the chances of a false positive is about 1:1000
+based on the binomial distribution.
+
+In addition, any power-up health test errors triggered with
+jent_entropy_init are treated as permanent errors.
+
+A permanent failure causes the entire entropy source to permanently
+return an error. This implies that a caller can only remedy the situation
+by re-allocating a new instance of the Jitter RNG. In a subsequent
+patch, a transparent re-allocation will be provided which also changes
+the implied heuristic entropy assessment.
+
+In addition, when the kernel is booted with fips=1, the Jitter RNG
+is defined to be part of a FIPS module. The permanent error of the
+Jitter RNG is translated as a FIPS module error. In this case, the entire
+FIPS module must cease operation. This is implemented in the kernel by
+invoking panic().
+
+The patch also fixes an off-by-one in the RCT cutoff value which is now
+set to 30 instead of 31. This is because the counting of the values
+starts with 0.
+
+Reviewed-by: Vladis Dronov <vdronov@redhat.com>
+Signed-off-by: Stephan Mueller <smueller@chronox.de>
+Reviewed-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/jitterentropy-kcapi.c | 51 ++++++-------
+ crypto/jitterentropy.c | 144 +++++++++++++----------------------
+ crypto/jitterentropy.h | 1 -
+ 3 files changed, 76 insertions(+), 120 deletions(-)
+
+diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
+index 2d115bec15aeb..b9edfaa51b273 100644
+--- a/crypto/jitterentropy-kcapi.c
++++ b/crypto/jitterentropy-kcapi.c
+@@ -37,6 +37,7 @@
+ * DAMAGE.
+ */
+
++#include <linux/fips.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+@@ -59,11 +60,6 @@ void jent_zfree(void *ptr)
+ kfree_sensitive(ptr);
+ }
+
+-void jent_panic(char *s)
+-{
+- panic("%s", s);
+-}
+-
+ void jent_memcpy(void *dest, const void *src, unsigned int n)
+ {
+ memcpy(dest, src, n);
+@@ -102,7 +98,6 @@ void jent_get_nstime(__u64 *out)
+ struct jitterentropy {
+ spinlock_t jent_lock;
+ struct rand_data *entropy_collector;
+- unsigned int reset_cnt;
+ };
+
+ static int jent_kcapi_init(struct crypto_tfm *tfm)
+@@ -138,32 +133,30 @@ static int jent_kcapi_random(struct crypto_rng *tfm,
+
+ spin_lock(&rng->jent_lock);
+
+- /* Return a permanent error in case we had too many resets in a row. */
+- if (rng->reset_cnt > (1<<10)) {
+- ret = -EFAULT;
+- goto out;
+- }
+-
+ ret = jent_read_entropy(rng->entropy_collector, rdata, dlen);
+
+- /* Reset RNG in case of health failures */
+- if (ret < -1) {
+- pr_warn_ratelimited("Reset Jitter RNG due to health test failure: %s failure\n",
+- (ret == -2) ? "Repetition Count Test" :
+- "Adaptive Proportion Test");
+-
+- rng->reset_cnt++;
+-
++ if (ret == -3) {
++ /* Handle permanent health test error */
++ /*
++ * If the kernel was booted with fips=1, it implies that
++ * the entire kernel acts as a FIPS 140 module. In this case
++ * an SP800-90B permanent health test error is treated as
++ * a FIPS module error.
++ */
++ if (fips_enabled)
++ panic("Jitter RNG permanent health test failure\n");
++
++ pr_err("Jitter RNG permanent health test failure\n");
++ ret = -EFAULT;
++ } else if (ret == -2) {
++ /* Handle intermittent health test error */
++ pr_warn_ratelimited("Reset Jitter RNG due to intermittent health test failure\n");
+ ret = -EAGAIN;
+- } else {
+- rng->reset_cnt = 0;
+-
+- /* Convert the Jitter RNG error into a usable error code */
+- if (ret == -1)
+- ret = -EINVAL;
++ } else if (ret == -1) {
++ /* Handle other errors */
++ ret = -EINVAL;
+ }
+
+-out:
+ spin_unlock(&rng->jent_lock);
+
+ return ret;
+@@ -197,6 +190,10 @@ static int __init jent_mod_init(void)
+
+ ret = jent_entropy_init();
+ if (ret) {
++ /* Handle permanent health test error */
++ if (fips_enabled)
++ panic("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
++
+ pr_info("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
+ return -EFAULT;
+ }
+diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
+index 93bff32138238..22f48bf4c6f57 100644
+--- a/crypto/jitterentropy.c
++++ b/crypto/jitterentropy.c
+@@ -85,10 +85,14 @@ struct rand_data {
+ * bit generation */
+
+ /* Repetition Count Test */
+- int rct_count; /* Number of stuck values */
++ unsigned int rct_count; /* Number of stuck values */
+
+- /* Adaptive Proportion Test for a significance level of 2^-30 */
++ /* Intermittent health test failure threshold of 2^-30 */
++#define JENT_RCT_CUTOFF 30 /* Taken from SP800-90B sec 4.4.1 */
+ #define JENT_APT_CUTOFF 325 /* Taken from SP800-90B sec 4.4.2 */
++ /* Permanent health test failure threshold of 2^-60 */
++#define JENT_RCT_CUTOFF_PERMANENT 60
++#define JENT_APT_CUTOFF_PERMANENT 355
+ #define JENT_APT_WINDOW_SIZE 512 /* Data window size */
+ /* LSB of time stamp to process */
+ #define JENT_APT_LSB 16
+@@ -97,8 +101,6 @@ struct rand_data {
+ unsigned int apt_count; /* APT counter */
+ unsigned int apt_base; /* APT base reference */
+ unsigned int apt_base_set:1; /* APT base reference set? */
+-
+- unsigned int health_failure:1; /* Permanent health failure */
+ };
+
+ /* Flags that can be used to initialize the RNG */
+@@ -169,19 +171,26 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
+ return;
+ }
+
+- if (delta_masked == ec->apt_base) {
++ if (delta_masked == ec->apt_base)
+ ec->apt_count++;
+
+- if (ec->apt_count >= JENT_APT_CUTOFF)
+- ec->health_failure = 1;
+- }
+-
+ ec->apt_observations++;
+
+ if (ec->apt_observations >= JENT_APT_WINDOW_SIZE)
+ jent_apt_reset(ec, delta_masked);
+ }
+
++/* APT health test failure detection */
++static int jent_apt_permanent_failure(struct rand_data *ec)
++{
++ return (ec->apt_count >= JENT_APT_CUTOFF_PERMANENT) ? 1 : 0;
++}
++
++static int jent_apt_failure(struct rand_data *ec)
++{
++ return (ec->apt_count >= JENT_APT_CUTOFF) ? 1 : 0;
++}
++
+ /***************************************************************************
+ * Stuck Test and its use as Repetition Count Test
+ *
+@@ -206,55 +215,14 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
+ */
+ static void jent_rct_insert(struct rand_data *ec, int stuck)
+ {
+- /*
+- * If we have a count less than zero, a previous RCT round identified
+- * a failure. We will not overwrite it.
+- */
+- if (ec->rct_count < 0)
+- return;
+-
+ if (stuck) {
+ ec->rct_count++;
+-
+- /*
+- * The cutoff value is based on the following consideration:
+- * alpha = 2^-30 as recommended in FIPS 140-2 IG 9.8.
+- * In addition, we require an entropy value H of 1/OSR as this
+- * is the minimum entropy required to provide full entropy.
+- * Note, we collect 64 * OSR deltas for inserting them into
+- * the entropy pool which should then have (close to) 64 bits
+- * of entropy.
+- *
+- * Note, ec->rct_count (which equals to value B in the pseudo
+- * code of SP800-90B section 4.4.1) starts with zero. Hence
+- * we need to subtract one from the cutoff value as calculated
+- * following SP800-90B.
+- */
+- if ((unsigned int)ec->rct_count >= (31 * ec->osr)) {
+- ec->rct_count = -1;
+- ec->health_failure = 1;
+- }
+ } else {
++ /* Reset RCT */
+ ec->rct_count = 0;
+ }
+ }
+
+-/*
+- * Is there an RCT health test failure?
+- *
+- * @ec [in] Reference to entropy collector
+- *
+- * @return
+- * 0 No health test failure
+- * 1 Permanent health test failure
+- */
+-static int jent_rct_failure(struct rand_data *ec)
+-{
+- if (ec->rct_count < 0)
+- return 1;
+- return 0;
+-}
+-
+ static inline __u64 jent_delta(__u64 prev, __u64 next)
+ {
+ #define JENT_UINT64_MAX (__u64)(~((__u64) 0))
+@@ -303,18 +271,26 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta)
+ return 0;
+ }
+
+-/*
+- * Report any health test failures
+- *
+- * @ec [in] Reference to entropy collector
+- *
+- * @return
+- * 0 No health test failure
+- * 1 Permanent health test failure
+- */
++/* RCT health test failure detection */
++static int jent_rct_permanent_failure(struct rand_data *ec)
++{
++ return (ec->rct_count >= JENT_RCT_CUTOFF_PERMANENT) ? 1 : 0;
++}
++
++static int jent_rct_failure(struct rand_data *ec)
++{
++ return (ec->rct_count >= JENT_RCT_CUTOFF) ? 1 : 0;
++}
++
++/* Report of health test failures */
+ static int jent_health_failure(struct rand_data *ec)
+ {
+- return ec->health_failure;
++ return jent_rct_failure(ec) | jent_apt_failure(ec);
++}
++
++static int jent_permanent_health_failure(struct rand_data *ec)
++{
++ return jent_rct_permanent_failure(ec) | jent_apt_permanent_failure(ec);
+ }
+
+ /***************************************************************************
+@@ -600,8 +576,8 @@ static void jent_gen_entropy(struct rand_data *ec)
+ *
+ * The following error codes can occur:
+ * -1 entropy_collector is NULL
+- * -2 RCT failed
+- * -3 APT test failed
++ * -2 Intermittent health failure
++ * -3 Permanent health failure
+ */
+ int jent_read_entropy(struct rand_data *ec, unsigned char *data,
+ unsigned int len)
+@@ -616,39 +592,23 @@ int jent_read_entropy(struct rand_data *ec, unsigned char *data,
+
+ jent_gen_entropy(ec);
+
+- if (jent_health_failure(ec)) {
+- int ret;
+-
+- if (jent_rct_failure(ec))
+- ret = -2;
+- else
+- ret = -3;
+-
++ if (jent_permanent_health_failure(ec)) {
+ /*
+- * Re-initialize the noise source
+- *
+- * If the health test fails, the Jitter RNG remains
+- * in failure state and will return a health failure
+- * during next invocation.
++ * At this point, the Jitter RNG instance is considered
++ * as a failed instance. There is no rerun of the
++ * startup test any more, because the caller
++ * is assumed to not further use this instance.
+ */
+- if (jent_entropy_init())
+- return ret;
+-
+- /* Set APT to initial state */
+- jent_apt_reset(ec, 0);
+- ec->apt_base_set = 0;
+-
+- /* Set RCT to initial state */
+- ec->rct_count = 0;
+-
+- /* Re-enable Jitter RNG */
+- ec->health_failure = 0;
+-
++ return -3;
++ } else if (jent_health_failure(ec)) {
+ /*
+- * Return the health test failure status to the
+- * caller as the generated value is not appropriate.
++ * Perform startup health tests and return permanent
++ * error if it fails.
+ */
+- return ret;
++ if (jent_entropy_init())
++ return -3;
++
++ return -2;
+ }
+
+ if ((DATA_SIZE_BITS / 8) < len)
+diff --git a/crypto/jitterentropy.h b/crypto/jitterentropy.h
+index b7397b617ef05..5cc583f6bc6b8 100644
+--- a/crypto/jitterentropy.h
++++ b/crypto/jitterentropy.h
+@@ -2,7 +2,6 @@
+
+ extern void *jent_zalloc(unsigned int len);
+ extern void jent_zfree(void *ptr);
+-extern void jent_panic(char *s);
+ extern void jent_memcpy(void *dest, const void *src, unsigned int n);
+ extern void jent_get_nstime(__u64 *out);
+
+--
+2.39.2
+
--- /dev/null
+From b9e11ee2eb6b10c5d24f975675118c92f5cf3893 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 12:00:16 +0800
+Subject: drm/amd/display: Correct DML calculation to align HW formula
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Paul Hsieh <Paul.Hsieh@amd.com>
+
+[ Upstream commit 26a9f53198c955b15161da48cdb51041a38d5325 ]
+
+[Why]
+In 2560x1440@240p eDP panel, some use cases will enable MPC
+combine with RGB MPO then underflow happened. This case is
+not allowed from HW formula.Â
+
+[How]
+Correct eDP, DP and DP2 output bpp calculation to align HW
+formula.
+
+Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Paul Hsieh <Paul.Hsieh@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>
+---
+ .../dc/dml/dcn31/display_mode_vba_31.c | 298 ++++++++++++------
+ .../dc/dml/dcn314/display_mode_vba_314.c | 298 ++++++++++++------
+ 2 files changed, 392 insertions(+), 204 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
+index b612edb144172..77094035a26af 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
+@@ -4305,11 +4305,11 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ v->AudioSampleRate[k],
+ v->AudioSampleLayout[k],
+ v->ODMCombineEnablePerState[i][k]);
+- } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) {
++ } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_dp2p0) {
+ if (v->DSCEnable[k] == true) {
+ v->RequiresDSC[i][k] = true;
+ v->LinkDSCEnable = true;
+- if (v->Output[k] == dm_dp) {
++ if (v->Output[k] == dm_dp || v->Output[k] == dm_dp2p0) {
+ v->RequiresFEC[i][k] = true;
+ } else {
+ v->RequiresFEC[i][k] = false;
+@@ -4317,107 +4317,201 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ } else {
+ v->RequiresDSC[i][k] = false;
+ v->LinkDSCEnable = false;
+- v->RequiresFEC[i][k] = false;
+- }
+-
+- v->Outbpp = BPP_INVALID;
+- if (v->PHYCLKPerState[i] >= 270.0) {
+- v->Outbpp = TruncToValidBPP(
+- (1.0 - v->Downspreading / 100.0) * 2700,
+- v->OutputLinkDPLanes[k],
+- v->HTotal[k],
+- v->HActive[k],
+- v->PixelClockBackEnd[k],
+- v->ForcedOutputLinkBPP[k],
+- v->LinkDSCEnable,
+- v->Output[k],
+- v->OutputFormat[k],
+- v->DSCInputBitPerComponent[k],
+- v->NumberOfDSCSlices[k],
+- v->AudioSampleRate[k],
+- v->AudioSampleLayout[k],
+- v->ODMCombineEnablePerState[i][k]);
+- v->OutputBppPerState[i][k] = v->Outbpp;
+- // TODO: Need some other way to handle this nonsense
+- // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
+- }
+- if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
+- v->Outbpp = TruncToValidBPP(
+- (1.0 - v->Downspreading / 100.0) * 5400,
+- v->OutputLinkDPLanes[k],
+- v->HTotal[k],
+- v->HActive[k],
+- v->PixelClockBackEnd[k],
+- v->ForcedOutputLinkBPP[k],
+- v->LinkDSCEnable,
+- v->Output[k],
+- v->OutputFormat[k],
+- v->DSCInputBitPerComponent[k],
+- v->NumberOfDSCSlices[k],
+- v->AudioSampleRate[k],
+- v->AudioSampleLayout[k],
+- v->ODMCombineEnablePerState[i][k]);
+- v->OutputBppPerState[i][k] = v->Outbpp;
+- // TODO: Need some other way to handle this nonsense
+- // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
+- }
+- if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
+- v->Outbpp = TruncToValidBPP(
+- (1.0 - v->Downspreading / 100.0) * 8100,
+- v->OutputLinkDPLanes[k],
+- v->HTotal[k],
+- v->HActive[k],
+- v->PixelClockBackEnd[k],
+- v->ForcedOutputLinkBPP[k],
+- v->LinkDSCEnable,
+- v->Output[k],
+- v->OutputFormat[k],
+- v->DSCInputBitPerComponent[k],
+- v->NumberOfDSCSlices[k],
+- v->AudioSampleRate[k],
+- v->AudioSampleLayout[k],
+- v->ODMCombineEnablePerState[i][k]);
+- v->OutputBppPerState[i][k] = v->Outbpp;
+- // TODO: Need some other way to handle this nonsense
+- // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
+- }
+- if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) {
+- v->Outbpp = TruncToValidBPP(
+- (1.0 - v->Downspreading / 100.0) * 10000,
+- 4,
+- v->HTotal[k],
+- v->HActive[k],
+- v->PixelClockBackEnd[k],
+- v->ForcedOutputLinkBPP[k],
+- v->LinkDSCEnable,
+- v->Output[k],
+- v->OutputFormat[k],
+- v->DSCInputBitPerComponent[k],
+- v->NumberOfDSCSlices[k],
+- v->AudioSampleRate[k],
+- v->AudioSampleLayout[k],
+- v->ODMCombineEnablePerState[i][k]);
+- v->OutputBppPerState[i][k] = v->Outbpp;
+- //v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4";
++ if (v->Output[k] == dm_dp2p0) {
++ v->RequiresFEC[i][k] = true;
++ } else {
++ v->RequiresFEC[i][k] = false;
++ }
+ }
+- if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) {
+- v->Outbpp = TruncToValidBPP(
+- 12000,
+- 4,
+- v->HTotal[k],
+- v->HActive[k],
+- v->PixelClockBackEnd[k],
+- v->ForcedOutputLinkBPP[k],
+- v->LinkDSCEnable,
+- v->Output[k],
+- v->OutputFormat[k],
+- v->DSCInputBitPerComponent[k],
+- v->NumberOfDSCSlices[k],
+- v->AudioSampleRate[k],
+- v->AudioSampleLayout[k],
+- v->ODMCombineEnablePerState[i][k]);
+- v->OutputBppPerState[i][k] = v->Outbpp;
+- //v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4";
++ if (v->Output[k] == dm_dp2p0) {
++ v->Outbpp = BPP_INVALID;
++ if ((v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr10) &&
++ v->PHYCLKD18PerState[k] >= 10000.0 / 18.0) {
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 10000,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 13500.0 / 18.0 &&
++ v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
++ v->RequiresDSC[i][k] = true;
++ v->LinkDSCEnable = true;
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 10000,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ }
++ v->OutputBppPerState[i][k] = v->Outbpp;
++ // TODO: Need some other way to handle this nonsense
++ // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR10"
++ }
++ if (v->Outbpp == BPP_INVALID &&
++ (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr13p5) &&
++ v->PHYCLKD18PerState[k] >= 13500.0 / 18.0) {
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 13500,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 20000.0 / 18.0 &&
++ v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
++ v->RequiresDSC[i][k] = true;
++ v->LinkDSCEnable = true;
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 13500,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ }
++ v->OutputBppPerState[i][k] = v->Outbpp;
++ // TODO: Need some other way to handle this nonsense
++ // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR13p5"
++ }
++ if (v->Outbpp == BPP_INVALID &&
++ (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr20) &&
++ v->PHYCLKD18PerState[k] >= 20000.0 / 18.0) {
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 20000,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ if (v->Outbpp == BPP_INVALID && v->DSCEnable[k] == true &&
++ v->ForcedOutputLinkBPP[k] == 0) {
++ v->RequiresDSC[i][k] = true;
++ v->LinkDSCEnable = true;
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 20000,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ }
++ v->OutputBppPerState[i][k] = v->Outbpp;
++ // TODO: Need some other way to handle this nonsense
++ // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR20"
++ }
++ } else {
++ v->Outbpp = BPP_INVALID;
++ if (v->PHYCLKPerState[i] >= 270.0) {
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 2700,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ v->OutputBppPerState[i][k] = v->Outbpp;
++ // TODO: Need some other way to handle this nonsense
++ // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
++ }
++ if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 5400,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ v->OutputBppPerState[i][k] = v->Outbpp;
++ // TODO: Need some other way to handle this nonsense
++ // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
++ }
++ if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 8100,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ v->OutputBppPerState[i][k] = v->Outbpp;
++ // TODO: Need some other way to handle this nonsense
++ // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
++ }
+ }
+ }
+ } else {
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
+index 3afd3c80e6da8..69516cfdbc64a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
+@@ -4403,11 +4403,11 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
+ v->AudioSampleRate[k],
+ v->AudioSampleLayout[k],
+ v->ODMCombineEnablePerState[i][k]);
+- } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) {
++ } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_dp2p0) {
+ if (v->DSCEnable[k] == true) {
+ v->RequiresDSC[i][k] = true;
+ v->LinkDSCEnable = true;
+- if (v->Output[k] == dm_dp) {
++ if (v->Output[k] == dm_dp || v->Output[k] == dm_dp2p0) {
+ v->RequiresFEC[i][k] = true;
+ } else {
+ v->RequiresFEC[i][k] = false;
+@@ -4415,107 +4415,201 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
+ } else {
+ v->RequiresDSC[i][k] = false;
+ v->LinkDSCEnable = false;
+- v->RequiresFEC[i][k] = false;
+- }
+-
+- v->Outbpp = BPP_INVALID;
+- if (v->PHYCLKPerState[i] >= 270.0) {
+- v->Outbpp = TruncToValidBPP(
+- (1.0 - v->Downspreading / 100.0) * 2700,
+- v->OutputLinkDPLanes[k],
+- v->HTotal[k],
+- v->HActive[k],
+- v->PixelClockBackEnd[k],
+- v->ForcedOutputLinkBPP[k],
+- v->LinkDSCEnable,
+- v->Output[k],
+- v->OutputFormat[k],
+- v->DSCInputBitPerComponent[k],
+- v->NumberOfDSCSlices[k],
+- v->AudioSampleRate[k],
+- v->AudioSampleLayout[k],
+- v->ODMCombineEnablePerState[i][k]);
+- v->OutputBppPerState[i][k] = v->Outbpp;
+- // TODO: Need some other way to handle this nonsense
+- // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
+- }
+- if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
+- v->Outbpp = TruncToValidBPP(
+- (1.0 - v->Downspreading / 100.0) * 5400,
+- v->OutputLinkDPLanes[k],
+- v->HTotal[k],
+- v->HActive[k],
+- v->PixelClockBackEnd[k],
+- v->ForcedOutputLinkBPP[k],
+- v->LinkDSCEnable,
+- v->Output[k],
+- v->OutputFormat[k],
+- v->DSCInputBitPerComponent[k],
+- v->NumberOfDSCSlices[k],
+- v->AudioSampleRate[k],
+- v->AudioSampleLayout[k],
+- v->ODMCombineEnablePerState[i][k]);
+- v->OutputBppPerState[i][k] = v->Outbpp;
+- // TODO: Need some other way to handle this nonsense
+- // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
+- }
+- if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
+- v->Outbpp = TruncToValidBPP(
+- (1.0 - v->Downspreading / 100.0) * 8100,
+- v->OutputLinkDPLanes[k],
+- v->HTotal[k],
+- v->HActive[k],
+- v->PixelClockBackEnd[k],
+- v->ForcedOutputLinkBPP[k],
+- v->LinkDSCEnable,
+- v->Output[k],
+- v->OutputFormat[k],
+- v->DSCInputBitPerComponent[k],
+- v->NumberOfDSCSlices[k],
+- v->AudioSampleRate[k],
+- v->AudioSampleLayout[k],
+- v->ODMCombineEnablePerState[i][k]);
+- v->OutputBppPerState[i][k] = v->Outbpp;
+- // TODO: Need some other way to handle this nonsense
+- // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
+- }
+- if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) {
+- v->Outbpp = TruncToValidBPP(
+- (1.0 - v->Downspreading / 100.0) * 10000,
+- 4,
+- v->HTotal[k],
+- v->HActive[k],
+- v->PixelClockBackEnd[k],
+- v->ForcedOutputLinkBPP[k],
+- v->LinkDSCEnable,
+- v->Output[k],
+- v->OutputFormat[k],
+- v->DSCInputBitPerComponent[k],
+- v->NumberOfDSCSlices[k],
+- v->AudioSampleRate[k],
+- v->AudioSampleLayout[k],
+- v->ODMCombineEnablePerState[i][k]);
+- v->OutputBppPerState[i][k] = v->Outbpp;
+- //v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4";
++ if (v->Output[k] == dm_dp2p0) {
++ v->RequiresFEC[i][k] = true;
++ } else {
++ v->RequiresFEC[i][k] = false;
++ }
+ }
+- if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) {
+- v->Outbpp = TruncToValidBPP(
+- 12000,
+- 4,
+- v->HTotal[k],
+- v->HActive[k],
+- v->PixelClockBackEnd[k],
+- v->ForcedOutputLinkBPP[k],
+- v->LinkDSCEnable,
+- v->Output[k],
+- v->OutputFormat[k],
+- v->DSCInputBitPerComponent[k],
+- v->NumberOfDSCSlices[k],
+- v->AudioSampleRate[k],
+- v->AudioSampleLayout[k],
+- v->ODMCombineEnablePerState[i][k]);
+- v->OutputBppPerState[i][k] = v->Outbpp;
+- //v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4";
++ if (v->Output[k] == dm_dp2p0) {
++ v->Outbpp = BPP_INVALID;
++ if ((v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr10) &&
++ v->PHYCLKD18PerState[k] >= 10000.0 / 18.0) {
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 10000,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 13500.0 / 18.0 &&
++ v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
++ v->RequiresDSC[i][k] = true;
++ v->LinkDSCEnable = true;
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 10000,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ }
++ v->OutputBppPerState[i][k] = v->Outbpp;
++ // TODO: Need some other way to handle this nonsense
++ // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR10"
++ }
++ if (v->Outbpp == BPP_INVALID &&
++ (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr13p5) &&
++ v->PHYCLKD18PerState[k] >= 13500.0 / 18.0) {
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 13500,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 20000.0 / 18.0 &&
++ v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
++ v->RequiresDSC[i][k] = true;
++ v->LinkDSCEnable = true;
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 13500,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ }
++ v->OutputBppPerState[i][k] = v->Outbpp;
++ // TODO: Need some other way to handle this nonsense
++ // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR13p5"
++ }
++ if (v->Outbpp == BPP_INVALID &&
++ (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr20) &&
++ v->PHYCLKD18PerState[k] >= 20000.0 / 18.0) {
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 20000,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ if (v->Outbpp == BPP_INVALID && v->DSCEnable[k] == true &&
++ v->ForcedOutputLinkBPP[k] == 0) {
++ v->RequiresDSC[i][k] = true;
++ v->LinkDSCEnable = true;
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 20000,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ }
++ v->OutputBppPerState[i][k] = v->Outbpp;
++ // TODO: Need some other way to handle this nonsense
++ // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR20"
++ }
++ } else {
++ v->Outbpp = BPP_INVALID;
++ if (v->PHYCLKPerState[i] >= 270.0) {
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 2700,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ v->OutputBppPerState[i][k] = v->Outbpp;
++ // TODO: Need some other way to handle this nonsense
++ // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
++ }
++ if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 5400,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ v->OutputBppPerState[i][k] = v->Outbpp;
++ // TODO: Need some other way to handle this nonsense
++ // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
++ }
++ if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
++ v->Outbpp = TruncToValidBPP(
++ (1.0 - v->Downspreading / 100.0) * 8100,
++ v->OutputLinkDPLanes[k],
++ v->HTotal[k],
++ v->HActive[k],
++ v->PixelClockBackEnd[k],
++ v->ForcedOutputLinkBPP[k],
++ v->LinkDSCEnable,
++ v->Output[k],
++ v->OutputFormat[k],
++ v->DSCInputBitPerComponent[k],
++ v->NumberOfDSCSlices[k],
++ v->AudioSampleRate[k],
++ v->AudioSampleLayout[k],
++ v->ODMCombineEnablePerState[i][k]);
++ v->OutputBppPerState[i][k] = v->Outbpp;
++ // TODO: Need some other way to handle this nonsense
++ // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
++ }
+ }
+ }
+ } else {
+--
+2.39.2
+
--- /dev/null
+From 447727b6bf23d86a7e34df2c111e4cead7f4bdae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Mar 2023 17:46:31 +0800
+Subject: drm/amd/display: Correct DML calculation to follow HW SPEC
+
+From: Paul Hsieh <Paul.Hsieh@amd.com>
+
+[ Upstream commit 385c3e4c29e1d4ce8f68687a8c84621e4c0e0416 ]
+
+[Why]
+In 2560x1600@240p eDP panel, driver use lowest voltage level
+to play 1080p video cause underflow. According to HW SPEC,
+the senario should use high voltage level.
+
+[How]
+ChromaPre value is zero when bandwidth validation.
+Correct ChromaPre calculation.
+
+Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
+Reviewed-by: Jun Lei <Jun.Lei@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Paul Hsieh <Paul.Hsieh@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/dml/dcn30/display_mode_vba_30.c | 2 +-
+ drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c | 2 +-
+ .../gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c | 2 +-
+ drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
+index 49da8119b28e9..861f32b3248e7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
+@@ -4866,7 +4866,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ v->DETBufferSizeCThisState[k],
+ &v->UrgentBurstFactorCursorPre[k],
+ &v->UrgentBurstFactorLumaPre[k],
+- &v->UrgentBurstFactorChroma[k],
++ &v->UrgentBurstFactorChromaPre[k],
+ &v->NoUrgentLatencyHidingPre[k]);
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
+index 77094035a26af..cf8f3d690fa66 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
+@@ -5189,7 +5189,7 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ v->DETBufferSizeCThisState[k],
+ &v->UrgentBurstFactorCursorPre[k],
+ &v->UrgentBurstFactorLumaPre[k],
+- &v->UrgentBurstFactorChroma[k],
++ &v->UrgentBurstFactorChromaPre[k],
+ &v->NotUrgentLatencyHidingPre[k]);
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
+index 69516cfdbc64a..4998b211ccac7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
+@@ -5286,7 +5286,7 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
+ v->DETBufferSizeCThisState[k],
+ &v->UrgentBurstFactorCursorPre[k],
+ &v->UrgentBurstFactorLumaPre[k],
+- &v->UrgentBurstFactorChroma[k],
++ &v->UrgentBurstFactorChromaPre[k],
+ &v->NotUrgentLatencyHidingPre[k]);
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+index e02e9d4b04a95..2bb768413c92a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+@@ -3333,7 +3333,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ /* Output */
+ &mode_lib->vba.UrgentBurstFactorCursorPre[k],
+ &mode_lib->vba.UrgentBurstFactorLumaPre[k],
+- &mode_lib->vba.UrgentBurstFactorChroma[k],
++ &mode_lib->vba.UrgentBurstFactorChromaPre[k],
+ &mode_lib->vba.NotUrgentLatencyHidingPre[k]);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 515b59e5bc494314306dad99e530b374cc6900e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Feb 2023 11:30:31 -0500
+Subject: drm/amd/display: Enable HostVM based on rIOMMU active
+
+From: Gabe Teeger <gabe.teeger@amd.com>
+
+[ Upstream commit 97fa4dfa66fdd52ad3d0c9fadeaaa1e87605bac7 ]
+
+[Why]
+There is underflow and flickering occuring. The
+underflow stops when hostvm is forced to active.
+According to policy, hostvm should be enabled if riommu
+is active, but this is not taken into account when
+deciding whether to enable hostvm.
+
+[What]
+For DCN314, set hostvm to true if riommu is active.
+
+Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Gabe Teeger <gabe.teeger@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/dml/dcn314/dcn314_fpu.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
+index 4f91e64754239..bf77e56c3f3ef 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
+@@ -310,6 +310,10 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c
+ pipe->plane_state->src_rect.width < pipe->plane_state->dst_rect.width))
+ upscaled = true;
+
++ /* Apply HostVM policy - either based on hypervisor globally enabled, or rIOMMU active */
++ if (dc->debug.dml_hostvm_override == DML_HOSTVM_NO_OVERRIDE)
++ pipes[i].pipe.src.hostvm = dc->vm_pa_config.is_hvm_enabled || dc->res_pool->hubbub->riommu_active;
++
+ /*
+ * Immediate flip can be set dynamically after enabling the plane.
+ * We need to require support for immediate flip or underflow can be
+--
+2.39.2
+
--- /dev/null
+From b502792d5325ad72089da19248528cab25803e0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Mar 2023 15:57:30 -0400
+Subject: drm/amd/display: fixed dcn30+ underflow issue
+
+From: Ayush Gupta <ayugupta@amd.com>
+
+[ Upstream commit 37403ced9f2873fab7f39ab4ac963bbb33fb0bc0 ]
+
+[Why]
+Observing underflow on dcn30+ system config at 4k144hz
+
+[How]
+We set the UCLK hardmax on AC/DC switch if softmax is enabled
+and also on boot. While booting up the UCLK Hardmax is set
+to softmax before the init sequence and the init sequence
+resets the hardmax to UCLK max which enables P-state switching.
+Just added a conditional check to avoid setting hardmax on init.
+
+Reviewed-by: Alvin Lee <Alvin.Lee2@amd.com>
+Reviewed-by: Martin Leung <Martin.Leung@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Ayush Gupta <ayugupta@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/dcn30/dcn30_hwseq.c | 3 ++-
+ drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c | 2 +-
+ drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 2 +-
+ 3 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+index c20e9f76f0213..a1b312483d7f1 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+@@ -629,7 +629,8 @@ void dcn30_init_hw(struct dc *dc)
+ if (dc->clk_mgr->funcs->notify_wm_ranges)
+ dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
+
+- if (dc->clk_mgr->funcs->set_hard_max_memclk)
++ //if softmax is enabled then hardmax will be set by a different call
++ if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+ dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
+
+ if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
+index bdf101547484a..d4ee533deff32 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
+@@ -284,7 +284,7 @@ void dcn31_init_hw(struct dc *dc)
+ if (dc->clk_mgr->funcs->notify_wm_ranges)
+ dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
+
+- if (dc->clk_mgr->funcs->set_hard_max_memclk)
++ if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+ dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
+
+ if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+index e9188bce62e0b..2f4afe40f3e68 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -970,7 +970,7 @@ void dcn32_init_hw(struct dc *dc)
+ if (dc->clk_mgr->funcs->notify_wm_ranges)
+ dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
+
+- if (dc->clk_mgr->funcs->set_hard_max_memclk)
++ if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+ dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
+
+ if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
+--
+2.39.2
+
--- /dev/null
+From 20ee874db30e41d2690db3d0ae7d657af80365e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 13:02:09 -0500
+Subject: drm/amd/display: populate subvp cmd info only for the top pipe
+
+From: Ayush Gupta <ayush.gupta@amd.com>
+
+[ Upstream commit 9bb10b7aaec3b6278f9cc410c17dcaa129bbbbf0 ]
+
+[Why]
+System restart observed while changing the display resolution
+to 8k with extended mode. Sytem restart was caused by a page fault.
+
+[How]
+When the driver populates subvp info it did it for both the pipes using
+vblank which caused an outof bounds array access causing the page fault.
+added checks to allow the top pipe only to fix this issue.
+
+Co-authored-by: Ayush Gupta <ayush.gupta@amd.com>
+Reviewed-by: Alvin Lee <Alvin.Lee2@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Ayush Gupta <ayush.gupta@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/dc_dmub_srv.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+index 0541e87e4f389..a461e9463534b 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+@@ -764,7 +764,8 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
+ !pipe->top_pipe && !pipe->prev_odm_pipe &&
+ pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
+ populate_subvp_cmd_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++);
+- } else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE) {
++ } else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE &&
++ !pipe->top_pipe && !pipe->prev_odm_pipe) {
+ // Don't need to check for ActiveDRAMClockChangeMargin < 0, not valid in cases where
+ // we run through DML without calculating "natural" P-state support
+ populate_subvp_cmd_vblank_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++);
+--
+2.39.2
+
--- /dev/null
+From 930ad28a487e6aea4ffcf9c08089d308d237f256 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 10:20:09 -0400
+Subject: drm/amd/display: Use DC_LOG_DC in the trasform pixel function
+
+From: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+
+[ Upstream commit 7222f5841ff49709ca666b05ff336776e0664a20 ]
+
+[Why & How]
+DC now uses a new commit sequence which is more robust since it
+addresses cases where we need to reorganize pipes based on planes and
+other parameters. As a result, this new commit sequence reset the DC
+state by cleaning plane states and re-creating them accordingly with the
+need. For this reason, the dce_transform_set_pixel_storage_depth can be
+invoked after a plane state is destroyed and before its re-creation. In
+this situation and on DCE devices, DC will hit a condition that will
+trigger a dmesg log that looks like this:
+
+Console: switching to colour frame buffer device 240x67
+------------[ cut here ]------------
+[..]
+Hardware name: System manufacturer System Product Name/PRIME X370-PRO, BIOS 5603 07/28/2020
+RIP: 0010:dce_transform_set_pixel_storage_depth+0x3f8/0x480 [amdgpu]
+[..]
+RSP: 0018:ffffc9000202b850 EFLAGS: 00010293
+RAX: ffffffffa081d100 RBX: ffff888110790000 RCX: 000000000000000c
+RDX: ffff888100bedbf8 RSI: 0000000000001a50 RDI: ffff88810463c900
+RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000007
+R10: 0000000000000001 R11: 0000000000000f00 R12: ffff88810f500010
+R13: ffff888100bedbf8 R14: ffff88810f515688 R15: 0000000000000000
+FS: 00007ff0159249c0(0000) GS:ffff88840e940000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007ff01528e550 CR3: 0000000002a10000 CR4: 00000000003506e0
+Call Trace:
+ <TASK>
+ ? dm_write_reg_func+0x21/0x80 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8]
+ dc_stream_set_dither_option+0xfb/0x130 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8]
+ amdgpu_dm_crtc_configure_crc_source+0x10b/0x190 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8]
+ amdgpu_dm_atomic_commit_tail+0x20a8/0x2a90 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8]
+ ? free_unref_page_commit+0x98/0x170
+ ? free_unref_page+0xcc/0x150
+ commit_tail+0x94/0x120
+ drm_atomic_helper_commit+0x10f/0x140
+ drm_atomic_commit+0x94/0xc0
+ ? drm_plane_get_damage_clips.cold+0x1c/0x1c
+ drm_client_modeset_commit_atomic+0x203/0x250
+ drm_client_modeset_commit_locked+0x56/0x150
+ drm_client_modeset_commit+0x21/0x40
+ drm_fb_helper_lastclose+0x42/0x70
+ amdgpu_driver_lastclose_kms+0xa/0x10 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8]
+ drm_release+0xda/0x110
+ __fput+0x89/0x240
+ task_work_run+0x5c/0x90
+ do_exit+0x333/0xae0
+ do_group_exit+0x2d/0x90
+ __x64_sys_exit_group+0x14/0x20
+ do_syscall_64+0x5b/0x80
+ ? exit_to_user_mode_prepare+0x1e/0x140
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+RIP: 0033:0x7ff016ceaca1
+Code: Unable to access opcode bytes at RIP 0x7ff016ceac77.
+RSP: 002b:00007ffe7a2357e8 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
+RAX: ffffffffffffffda RBX: 00007ff016e15a00 RCX: 00007ff016ceaca1
+RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000000
+RBP: 0000000000000000 R08: ffffffffffffff78 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 00007ff016e15a00
+R13: 0000000000000000 R14: 00007ff016e1aee8 R15: 00007ff016e1af00
+ </TASK>
+
+Since this issue only happens in a transition state on DC, this commit
+replace BREAK_TO_DEBUGGER with DC_LOG_DC.
+
+Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@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/dce/dce_transform.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
+index d9fd4ec60588f..670d5ab9d9984 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
+@@ -1009,7 +1009,7 @@ static void dce_transform_set_pixel_storage_depth(
+ color_depth = COLOR_DEPTH_101010;
+ pixel_depth = 0;
+ expan_mode = 1;
+- BREAK_TO_DEBUGGER();
++ DC_LOG_DC("The pixel depth %d is not valid, set COLOR_DEPTH_101010 instead.", depth);
+ break;
+ }
+
+@@ -1023,8 +1023,7 @@ static void dce_transform_set_pixel_storage_depth(
+ if (!(xfm_dce->lb_pixel_depth_supported & depth)) {
+ /*we should use unsupported capabilities
+ * unless it is required by w/a*/
+- DC_LOG_WARNING("%s: Capability not supported",
+- __func__);
++ DC_LOG_DC("%s: Capability not supported", __func__);
+ }
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 72806a061ffe43858dcdaeb83093bd6e8eb20268 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Mar 2023 14:07:06 -0500
+Subject: drm/amd: Fix an out of bounds error in BIOS parser
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit d116db180decec1b21bba31d2ff495ac4d8e1b83 ]
+
+The array is hardcoded to 8 in atomfirmware.h, but firmware provides
+a bigger one sometimes. Deferencing the larger array causes an out
+of bounds error.
+
+commit 4fc1ba4aa589 ("drm/amd/display: fix array index out of bound error
+in bios parser") fixed some of this, but there are two other cases
+not covered by it. Fix those as well.
+
+Reported-by: erhard_f@mailbox.org
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=214853
+Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2473
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Harry Wentland <harry.wentland@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/bios/bios_parser2.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+index 074e70a5c458e..e507d2e1410b7 100644
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+@@ -516,11 +516,8 @@ static enum bp_result get_gpio_i2c_info(
+ info->i2c_slave_address = record->i2c_slave_addr;
+
+ /* TODO: check how to get register offset for en, Y, etc. */
+- info->gpio_info.clk_a_register_index =
+- le16_to_cpu(
+- header->gpio_pin[table_index].data_a_reg_index);
+- info->gpio_info.clk_a_shift =
+- header->gpio_pin[table_index].gpio_bitshift;
++ info->gpio_info.clk_a_register_index = le16_to_cpu(pin->data_a_reg_index);
++ info->gpio_info.clk_a_shift = pin->gpio_bitshift;
+
+ return BP_RESULT_OK;
+ }
+--
+2.39.2
+
--- /dev/null
+From a544308f8add0f4424c14f39f2fe5ef5793cbf98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 15:30:34 +0800
+Subject: drm/amdgpu: Fix sdma v4 sw fini error
+
+From: lyndonli <Lyndon.Li@amd.com>
+
+[ Upstream commit 5e08e9c742a00384e5abe74bd40cf4dc15cb3a2e ]
+
+Fix sdma v4 sw fini error for sdma 4.2.2 to
+solve the following general protection fault
+
+[ +0.108196] general protection fault, probably for non-canonical
+address 0xd5e5a4ae79d24a32: 0000 [#1] PREEMPT SMP PTI
+[ +0.000018] RIP: 0010:free_fw_priv+0xd/0x70
+[ +0.000022] Call Trace:
+[ +0.000012] <TASK>
+[ +0.000011] release_firmware+0x55/0x80
+[ +0.000021] amdgpu_ucode_release+0x11/0x20 [amdgpu]
+[ +0.000415] amdgpu_sdma_destroy_inst_ctx+0x4f/0x90 [amdgpu]
+[ +0.000360] sdma_v4_0_sw_fini+0xce/0x110 [amdgpu]
+
+Signed-off-by: lyndonli <Lyndon.Li@amd.com>
+Reviewed-by: Likun Gao <Likun.Gao@amd.com>
+Reviewed-by: Feifei Xu <Feifei.Xu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+index 77d5a6f304094..5b251d0094678 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+@@ -1908,7 +1908,7 @@ static int sdma_v4_0_sw_fini(void *handle)
+ amdgpu_ring_fini(&adev->sdma.instance[i].page);
+ }
+
+- if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 0) ||
++ if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 2) ||
+ adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 4, 0))
+ amdgpu_sdma_destroy_inst_ctx(adev, true);
+ else
+--
+2.39.2
+
--- /dev/null
+From 1b84e6fd95656a62a02486ea3cbaeb7b6c0034c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Feb 2023 22:44:58 +0200
+Subject: drm/displayid: add displayid_get_header() and check bounds better
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+[ Upstream commit 5bacecc3c56131c31f18b23d366f2184328fd9cf ]
+
+Add a helper to get a pointer to struct displayid_header. To be
+pedantic, add buffer overflow checks to not touch the base if that
+itself would overflow.
+
+Cc: Iaroslav Boliukin <iam@lach.pw>
+Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/4a03b3a5132642d3cdb6d4c2641422955a917292.1676580180.git.jani.nikula@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_displayid.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
+index 38ea8203df45b..7d03159dc1461 100644
+--- a/drivers/gpu/drm/drm_displayid.c
++++ b/drivers/gpu/drm/drm_displayid.c
+@@ -7,13 +7,28 @@
+ #include <drm/drm_edid.h>
+ #include <drm/drm_print.h>
+
++static const struct displayid_header *
++displayid_get_header(const u8 *displayid, int length, int index)
++{
++ const struct displayid_header *base;
++
++ if (sizeof(*base) > length - index)
++ return ERR_PTR(-EINVAL);
++
++ base = (const struct displayid_header *)&displayid[index];
++
++ return base;
++}
++
+ static int validate_displayid(const u8 *displayid, int length, int idx)
+ {
+ int i, dispid_length;
+ u8 csum = 0;
+ const struct displayid_header *base;
+
+- base = (const struct displayid_header *)&displayid[idx];
++ base = displayid_get_header(displayid, length, idx);
++ if (IS_ERR(base))
++ return PTR_ERR(base);
+
+ DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
+ base->rev, base->bytes, base->prod_id, base->ext_count);
+--
+2.39.2
+
--- /dev/null
+From 61c6235f2a99564709277c611950c87436db41bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Jan 2023 17:09:12 -0800
+Subject: drm/msm/dp: Clean up handling of DP AUX interrupts
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit b20566cdef05cd40d95f10869d2a7646f48b1bbe ]
+
+The DP AUX interrupt handling was a bit of a mess.
+* There were two functions (one for "native" transfers and one for
+ "i2c" transfers) that were quite similar. It was hard to say how
+ many of the differences between the two functions were on purpose
+ and how many of them were just an accident of how they were coded.
+* Each function sometimes used "else if" to test for error bits and
+ sometimes didn't and again it was hard to say if this was on purpose
+ or just an accident.
+* The two functions wouldn't notice whether "unknown" bits were
+ set. For instance, there seems to be a bit "DP_INTR_PLL_UNLOCKED"
+ and if it was set there would be no indication.
+* The two functions wouldn't notice if more than one error was set.
+
+Let's fix this by being more consistent / explicit about what we're
+doing.
+
+By design this could cause different handling for AUX transfers,
+though I'm not actually aware of any bug fixed as a result of
+this patch (this patch was created because we simply noticed how odd
+the old code was by code inspection). Specific notes here:
+1. In the old native transfer case if we got "done + wrong address"
+ we'd ignore the "wrong address" (because of the "else if"). Now we
+ won't.
+2. In the old native transfer case if we got "done + timeout" we'd
+ ignore the "timeout" (because of the "else if"). Now we won't.
+3. In the old native transfer case we'd see "nack_defer" and translate
+ it to the error number for "nack". This differed from the i2c
+ transfer case where "nack_defer" was given the error number for
+ "nack_defer". This 100% can't matter because the only user of this
+ error number treats "nack defer" the same as "nack", so it's clear
+ that the difference between the "native" and "i2c" was pointless
+ here.
+4. In the old i2c transfer case if we got "done" plus any error
+ besides "nack" or "defer" then we'd ignore the error. Now we don't.
+5. If there is more than one error signaled by the hardware it's
+ possible that we'll report a different one than we used to. I don't
+ know if this matters. If someone is aware of a case this matters we
+ should document it and change the code to make it explicit.
+6. One quirk we keep (I don't know if this is important) is that in
+ the i2c transfer case if we see "done + defer" we report that as a
+ "nack". That seemed too intentional in the old code to just drop.
+
+After this change we will add extra logging, including:
+* A warning if we see more than one error bit set.
+* A warning if we see an unexpected interrupt.
+* A warning if we get an AUX transfer interrupt when shouldn't.
+
+It actually turns out that as a result of this change then at boot we
+sometimes see an error:
+ [drm:dp_aux_isr] *ERROR* Unexpected DP AUX IRQ 0x01000000 when not busy
+That means that, during init, we are seeing DP_INTR_PLL_UNLOCKED. For
+now I'm going to say that leaving this error reported in the logs is
+OK-ish and hopefully it will encourage someone to track down what's
+going on at init time.
+
+One last note here is that this change renames one of the interrupt
+bits. The bit named "i2c done" clearly was used for native transfers
+being done too, so I renamed it to indicate this.
+
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
+Reviewed-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/520658/
+Link: https://lore.kernel.org/r/20230126170745.v2.1.I90ffed3ddd21e818ae534f820cb4d6d8638859ab@changeid
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dp/dp_aux.c | 80 ++++++++++++-----------------
+ drivers/gpu/drm/msm/dp/dp_catalog.c | 2 +-
+ drivers/gpu/drm/msm/dp/dp_catalog.h | 2 +-
+ 3 files changed, 36 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
+index cc3efed593aa1..84f9e3e5f9642 100644
+--- a/drivers/gpu/drm/msm/dp/dp_aux.c
++++ b/drivers/gpu/drm/msm/dp/dp_aux.c
+@@ -162,47 +162,6 @@ static ssize_t dp_aux_cmd_fifo_rx(struct dp_aux_private *aux,
+ return i;
+ }
+
+-static void dp_aux_native_handler(struct dp_aux_private *aux, u32 isr)
+-{
+- if (isr & DP_INTR_AUX_I2C_DONE)
+- aux->aux_error_num = DP_AUX_ERR_NONE;
+- else if (isr & DP_INTR_WRONG_ADDR)
+- aux->aux_error_num = DP_AUX_ERR_ADDR;
+- else if (isr & DP_INTR_TIMEOUT)
+- aux->aux_error_num = DP_AUX_ERR_TOUT;
+- if (isr & DP_INTR_NACK_DEFER)
+- aux->aux_error_num = DP_AUX_ERR_NACK;
+- if (isr & DP_INTR_AUX_ERROR) {
+- aux->aux_error_num = DP_AUX_ERR_PHY;
+- dp_catalog_aux_clear_hw_interrupts(aux->catalog);
+- }
+-}
+-
+-static void dp_aux_i2c_handler(struct dp_aux_private *aux, u32 isr)
+-{
+- if (isr & DP_INTR_AUX_I2C_DONE) {
+- if (isr & (DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER))
+- aux->aux_error_num = DP_AUX_ERR_NACK;
+- else
+- aux->aux_error_num = DP_AUX_ERR_NONE;
+- } else {
+- if (isr & DP_INTR_WRONG_ADDR)
+- aux->aux_error_num = DP_AUX_ERR_ADDR;
+- else if (isr & DP_INTR_TIMEOUT)
+- aux->aux_error_num = DP_AUX_ERR_TOUT;
+- if (isr & DP_INTR_NACK_DEFER)
+- aux->aux_error_num = DP_AUX_ERR_NACK_DEFER;
+- if (isr & DP_INTR_I2C_NACK)
+- aux->aux_error_num = DP_AUX_ERR_NACK;
+- if (isr & DP_INTR_I2C_DEFER)
+- aux->aux_error_num = DP_AUX_ERR_DEFER;
+- if (isr & DP_INTR_AUX_ERROR) {
+- aux->aux_error_num = DP_AUX_ERR_PHY;
+- dp_catalog_aux_clear_hw_interrupts(aux->catalog);
+- }
+- }
+-}
+-
+ static void dp_aux_update_offset_and_segment(struct dp_aux_private *aux,
+ struct drm_dp_aux_msg *input_msg)
+ {
+@@ -427,13 +386,42 @@ void dp_aux_isr(struct drm_dp_aux *dp_aux)
+ if (!isr)
+ return;
+
+- if (!aux->cmd_busy)
++ if (!aux->cmd_busy) {
++ DRM_ERROR("Unexpected DP AUX IRQ %#010x when not busy\n", isr);
+ return;
++ }
+
+- if (aux->native)
+- dp_aux_native_handler(aux, isr);
+- else
+- dp_aux_i2c_handler(aux, isr);
++ /*
++ * The logic below assumes only one error bit is set (other than "done"
++ * which can apparently be set at the same time as some of the other
++ * bits). Warn if more than one get set so we know we need to improve
++ * the logic.
++ */
++ if (hweight32(isr & ~DP_INTR_AUX_XFER_DONE) > 1)
++ DRM_WARN("Some DP AUX interrupts unhandled: %#010x\n", isr);
++
++ if (isr & DP_INTR_AUX_ERROR) {
++ aux->aux_error_num = DP_AUX_ERR_PHY;
++ dp_catalog_aux_clear_hw_interrupts(aux->catalog);
++ } else if (isr & DP_INTR_NACK_DEFER) {
++ aux->aux_error_num = DP_AUX_ERR_NACK_DEFER;
++ } else if (isr & DP_INTR_WRONG_ADDR) {
++ aux->aux_error_num = DP_AUX_ERR_ADDR;
++ } else if (isr & DP_INTR_TIMEOUT) {
++ aux->aux_error_num = DP_AUX_ERR_TOUT;
++ } else if (!aux->native && (isr & DP_INTR_I2C_NACK)) {
++ aux->aux_error_num = DP_AUX_ERR_NACK;
++ } else if (!aux->native && (isr & DP_INTR_I2C_DEFER)) {
++ if (isr & DP_INTR_AUX_XFER_DONE)
++ aux->aux_error_num = DP_AUX_ERR_NACK;
++ else
++ aux->aux_error_num = DP_AUX_ERR_DEFER;
++ } else if (isr & DP_INTR_AUX_XFER_DONE) {
++ aux->aux_error_num = DP_AUX_ERR_NONE;
++ } else {
++ DRM_WARN("Unexpected interrupt: %#010x\n", isr);
++ return;
++ }
+
+ complete(&aux->comp);
+ }
+diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
+index 676279d0ca8d9..421391755427d 100644
+--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
++++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
+@@ -27,7 +27,7 @@
+ #define DP_INTF_CONFIG_DATABUS_WIDEN BIT(4)
+
+ #define DP_INTERRUPT_STATUS1 \
+- (DP_INTR_AUX_I2C_DONE| \
++ (DP_INTR_AUX_XFER_DONE| \
+ DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
+ DP_INTR_NACK_DEFER | DP_INTR_WRONG_DATA_CNT | \
+ DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER | \
+diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
+index 1f717f45c1158..f36b7b372a065 100644
+--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
++++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
+@@ -13,7 +13,7 @@
+
+ /* interrupts */
+ #define DP_INTR_HPD BIT(0)
+-#define DP_INTR_AUX_I2C_DONE BIT(3)
++#define DP_INTR_AUX_XFER_DONE BIT(3)
+ #define DP_INTR_WRONG_ADDR BIT(6)
+ #define DP_INTR_TIMEOUT BIT(9)
+ #define DP_INTR_NACK_DEFER BIT(12)
+--
+2.39.2
+
--- /dev/null
+From 7f3645d9ac323d0c93ef9eb909713a521ee80008 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Mar 2023 17:51:26 -0700
+Subject: drm/rockchip: dw_hdmi: cleanup drm encoder during unbind
+
+From: Toby Chen <tobyc@nvidia.com>
+
+[ Upstream commit b5af48eedcb53491c02ded55d5991e03d6da6dbf ]
+
+This fixes a use-after-free crash during rmmod.
+
+The DRM encoder is embedded inside the larger rockchip_hdmi,
+which is allocated with the component. The component memory
+gets freed before the main drm device is destroyed. Fix it
+by running encoder cleanup before tearing down its container.
+
+Signed-off-by: Toby Chen <tobyc@nvidia.com>
+[moved encoder cleanup above clk_disable, similar to bind-error-path]
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230317005126.496-1-tobyc@nvidia.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+index 2f4b8f64cbad3..ae857bf8bd624 100644
+--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+@@ -640,6 +640,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
+ struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
+
+ dw_hdmi_unbind(hdmi->hdmi);
++ drm_encoder_cleanup(&hdmi->encoder.encoder);
+ clk_disable_unprepare(hdmi->ref_clk);
+
+ regulator_disable(hdmi->avdd_1v8);
+--
+2.39.2
+
--- /dev/null
+From a47e7f229a4439295a94c5be28214f5a2a044977 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 04:25:59 +0800
+Subject: drm/tegra: Avoid potential 32-bit integer overflow
+
+From: Nur Hussein <hussein@unixcat.org>
+
+[ Upstream commit 2429b3c529da29d4277d519bd66d034842dcd70c ]
+
+In tegra_sor_compute_config(), the 32-bit value mode->clock is
+multiplied by 1000, and assigned to the u64 variable pclk. We can avoid
+a potential 32-bit integer overflow by casting mode->clock to u64 before
+we do the arithmetic and assignment.
+
+Signed-off-by: Nur Hussein <hussein@unixcat.org>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/sor.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
+index 8af632740673a..77723d5f1d3fd 100644
+--- a/drivers/gpu/drm/tegra/sor.c
++++ b/drivers/gpu/drm/tegra/sor.c
+@@ -1153,7 +1153,7 @@ static int tegra_sor_compute_config(struct tegra_sor *sor,
+ struct drm_dp_link *link)
+ {
+ const u64 f = 100000, link_rate = link->rate * 1000;
+- const u64 pclk = mode->clock * 1000;
++ const u64 pclk = (u64)mode->clock * 1000;
+ u64 input, output, watermark, num;
+ struct tegra_sor_params params;
+ u32 num_syms_per_line;
+--
+2.39.2
+
--- /dev/null
+From f81ab63f17705bbfcb6cae647a0592927b23f64f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Mar 2023 11:59:39 +0100
+Subject: ext2: Check block size validity during mount
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 62aeb94433fcec80241754b70d0d1836d5926b0a ]
+
+Check that log of block size stored in the superblock has sensible
+value. Otherwise the shift computing the block size can overflow leading
+to undefined behavior.
+
+Reported-by: syzbot+4fec412f59eba8c01b77@syzkaller.appspotmail.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext2/ext2.h | 1 +
+ fs/ext2/super.c | 7 +++++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
+index 28de11a22e5f6..dc5dcb78bc27f 100644
+--- a/fs/ext2/ext2.h
++++ b/fs/ext2/ext2.h
+@@ -180,6 +180,7 @@ static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb)
+ #define EXT2_MIN_BLOCK_SIZE 1024
+ #define EXT2_MAX_BLOCK_SIZE 4096
+ #define EXT2_MIN_BLOCK_LOG_SIZE 10
++#define EXT2_MAX_BLOCK_LOG_SIZE 16
+ #define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize)
+ #define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+ #define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits)
+diff --git a/fs/ext2/super.c b/fs/ext2/super.c
+index 03f2af98b1b48..3feea4b31fa7e 100644
+--- a/fs/ext2/super.c
++++ b/fs/ext2/super.c
+@@ -945,6 +945,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
+ goto failed_mount;
+ }
+
++ if (le32_to_cpu(es->s_log_block_size) >
++ (EXT2_MAX_BLOCK_LOG_SIZE - BLOCK_SIZE_BITS)) {
++ ext2_msg(sb, KERN_ERR,
++ "Invalid log block size: %u",
++ le32_to_cpu(es->s_log_block_size));
++ goto failed_mount;
++ }
+ blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
+
+ if (test_opt(sb, DAX)) {
+--
+2.39.2
+
--- /dev/null
+From 55e21b8a0c9fe784979ddce7e4a6989ee7514e05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Mar 2023 13:43:39 +0530
+Subject: ext4: Fix best extent lstart adjustment logic in
+ ext4_mb_new_inode_pa()
+
+From: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+
+[ Upstream commit 93cdf49f6eca5e23f6546b8f28457b2e6a6961d9 ]
+
+When the length of best extent found is less than the length of goal extent
+we need to make sure that the best extent atleast covers the start of the
+original request. This is done by adjusting the ac_b_ex.fe_logical (logical
+start) of the extent.
+
+While doing so, the current logic sometimes results in the best extent's
+logical range overflowing the goal extent. Since this best extent is later
+added to the inode preallocation list, we have a possibility of introducing
+overlapping preallocations. This is discussed in detail here [1].
+
+As per Jan's suggestion, to fix this, replace the existing logic with the
+below logic for adjusting best extent as it keeps fragmentation in check
+while ensuring logical range of best extent doesn't overflow out of goal
+extent:
+
+1. Check if best extent can be kept at end of goal range and still cover
+ original start.
+2. Else, check if best extent can be kept at start of goal range and still
+ cover original start.
+3. Else, keep the best extent at start of original request.
+
+Also, add a few extra BUG_ONs that might help catch errors faster.
+
+[1] https://lore.kernel.org/r/Y+OGkVvzPN0RMv0O@li-bb2b2a4c-3307-11b2-a85c-8fa5c3a69313.ibm.com
+
+Suggested-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/f96aca6d415b36d1f90db86c1a8cd7e2e9d7ab0e.1679731817.git.ojaswin@linux.ibm.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 49 ++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 31 insertions(+), 18 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 21f09bcffbbaa..32d88757a780e 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -4321,6 +4321,7 @@ static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac,
+ BUG_ON(start < pa->pa_pstart);
+ BUG_ON(end > pa->pa_pstart + EXT4_C2B(sbi, pa->pa_len));
+ BUG_ON(pa->pa_free < len);
++ BUG_ON(ac->ac_b_ex.fe_len <= 0);
+ pa->pa_free -= len;
+
+ mb_debug(ac->ac_sb, "use %llu/%d from inode pa %p\n", start, len, pa);
+@@ -4650,10 +4651,8 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
+ pa = ac->ac_pa;
+
+ if (ac->ac_b_ex.fe_len < ac->ac_g_ex.fe_len) {
+- int winl;
+- int wins;
+- int win;
+- int offs;
++ int new_bex_start;
++ int new_bex_end;
+
+ /* we can't allocate as much as normalizer wants.
+ * so, found space must get proper lstart
+@@ -4661,26 +4660,40 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
+ BUG_ON(ac->ac_g_ex.fe_logical > ac->ac_o_ex.fe_logical);
+ BUG_ON(ac->ac_g_ex.fe_len < ac->ac_o_ex.fe_len);
+
+- /* we're limited by original request in that
+- * logical block must be covered any way
+- * winl is window we can move our chunk within */
+- winl = ac->ac_o_ex.fe_logical - ac->ac_g_ex.fe_logical;
++ /*
++ * Use the below logic for adjusting best extent as it keeps
++ * fragmentation in check while ensuring logical range of best
++ * extent doesn't overflow out of goal extent:
++ *
++ * 1. Check if best ex can be kept at end of goal and still
++ * cover original start
++ * 2. Else, check if best ex can be kept at start of goal and
++ * still cover original start
++ * 3. Else, keep the best ex at start of original request.
++ */
++ new_bex_end = ac->ac_g_ex.fe_logical +
++ EXT4_C2B(sbi, ac->ac_g_ex.fe_len);
++ new_bex_start = new_bex_end - EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
++ if (ac->ac_o_ex.fe_logical >= new_bex_start)
++ goto adjust_bex;
+
+- /* also, we should cover whole original request */
+- wins = EXT4_C2B(sbi, ac->ac_b_ex.fe_len - ac->ac_o_ex.fe_len);
++ new_bex_start = ac->ac_g_ex.fe_logical;
++ new_bex_end =
++ new_bex_start + EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
++ if (ac->ac_o_ex.fe_logical < new_bex_end)
++ goto adjust_bex;
+
+- /* the smallest one defines real window */
+- win = min(winl, wins);
++ new_bex_start = ac->ac_o_ex.fe_logical;
++ new_bex_end =
++ new_bex_start + EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
+
+- offs = ac->ac_o_ex.fe_logical %
+- EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
+- if (offs && offs < win)
+- win = offs;
++adjust_bex:
++ ac->ac_b_ex.fe_logical = new_bex_start;
+
+- ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical -
+- EXT4_NUM_B2C(sbi, win);
+ BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical);
+ BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len);
++ BUG_ON(new_bex_end > (ac->ac_g_ex.fe_logical +
++ EXT4_C2B(sbi, ac->ac_g_ex.fe_len)));
+ }
+
+ /* preallocation can change ac_b_ex, thus we store actually
+--
+2.39.2
+
--- /dev/null
+From 035692bbd2dca7e4c00c63ce3007870ba6fe20ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Mar 2023 01:21:01 +0800
+Subject: ext4: set goal start correctly in ext4_mb_normalize_request
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+[ Upstream commit b07ffe6927c75d99af534d685282ea188d9f71a6 ]
+
+We need to set ac_g_ex to notify the goal start used in
+ext4_mb_find_by_goal. Set ac_g_ex instead of ac_f_ex in
+ext4_mb_normalize_request.
+Besides we should assure goal start is in range [first_data_block,
+blocks_count) as ext4_mb_initialize_context does.
+
+[ Added a check to make sure size is less than ar->pright; otherwise
+ we could end up passing an underflowed value of ar->pright - size to
+ ext4_get_group_no_and_offset(), which will trigger a BUG_ON later on.
+ - TYT ]
+
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Link: https://lore.kernel.org/r/20230303172120.3800725-2-shikemeng@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 09bb1dae40cf0..21f09bcffbbaa 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -4018,6 +4018,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
+ struct ext4_allocation_request *ar)
+ {
+ struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
++ struct ext4_super_block *es = sbi->s_es;
+ int bsbits, max;
+ ext4_lblk_t end;
+ loff_t size, start_off;
+@@ -4213,18 +4214,21 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
+ ac->ac_g_ex.fe_len = EXT4_NUM_B2C(sbi, size);
+
+ /* define goal start in order to merge */
+- if (ar->pright && (ar->lright == (start + size))) {
++ if (ar->pright && (ar->lright == (start + size)) &&
++ ar->pright >= size &&
++ ar->pright - size >= le32_to_cpu(es->s_first_data_block)) {
+ /* merge to the right */
+ ext4_get_group_no_and_offset(ac->ac_sb, ar->pright - size,
+- &ac->ac_f_ex.fe_group,
+- &ac->ac_f_ex.fe_start);
++ &ac->ac_g_ex.fe_group,
++ &ac->ac_g_ex.fe_start);
+ ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL;
+ }
+- if (ar->pleft && (ar->lleft + 1 == start)) {
++ if (ar->pleft && (ar->lleft + 1 == start) &&
++ ar->pleft + 1 < ext4_blocks_count(es)) {
+ /* merge to the left */
+ ext4_get_group_no_and_offset(ac->ac_sb, ar->pleft + 1,
+- &ac->ac_f_ex.fe_group,
+- &ac->ac_f_ex.fe_start);
++ &ac->ac_g_ex.fe_group,
++ &ac->ac_g_ex.fe_start);
+ ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 938f274c1087c3418ce058d14f9e7cac95082b10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Mar 2023 09:12:51 +0900
+Subject: f2fs: Fix system crash due to lack of free space in LFS
+
+From: Yonggil Song <yonggil.song@samsung.com>
+
+[ Upstream commit d11cef14f8146f3babd286c2cc8ca09c166295e2 ]
+
+When f2fs tries to checkpoint during foreground gc in LFS mode, system
+crash occurs due to lack of free space if the amount of dirty node and
+dentry pages generated by data migration exceeds free space.
+The reproduction sequence is as follows.
+
+ - 20GiB capacity block device (null_blk)
+ - format and mount with LFS mode
+ - create a file and write 20,000MiB
+ - 4k random write on full range of the file
+
+ RIP: 0010:new_curseg+0x48a/0x510 [f2fs]
+ Code: 55 e7 f5 89 c0 48 0f af c3 48 8b 5d c0 48 c1 e8 20 83 c0 01 89 43 6c 48 83 c4 28 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc <0f> 0b f0 41 80 4f 48 04 45 85 f6 0f 84 ba fd ff ff e9 ef fe ff ff
+ RSP: 0018:ffff977bc397b218 EFLAGS: 00010246
+ RAX: 00000000000027b9 RBX: 0000000000000000 RCX: 00000000000027c0
+ RDX: 0000000000000000 RSI: 00000000000027b9 RDI: ffff8c25ab4e74f8
+ RBP: ffff977bc397b268 R08: 00000000000027b9 R09: ffff8c29e4a34b40
+ R10: 0000000000000001 R11: ffff977bc397b0d8 R12: 0000000000000000
+ R13: ffff8c25b4dd81a0 R14: 0000000000000000 R15: ffff8c2f667f9000
+ FS: 0000000000000000(0000) GS:ffff8c344ec80000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 000000c00055d000 CR3: 0000000e30810003 CR4: 00000000003706e0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ Call Trace:
+ <TASK>
+ allocate_segment_by_default+0x9c/0x110 [f2fs]
+ f2fs_allocate_data_block+0x243/0xa30 [f2fs]
+ ? __mod_lruvec_page_state+0xa0/0x150
+ do_write_page+0x80/0x160 [f2fs]
+ f2fs_do_write_node_page+0x32/0x50 [f2fs]
+ __write_node_page+0x339/0x730 [f2fs]
+ f2fs_sync_node_pages+0x5a6/0x780 [f2fs]
+ block_operations+0x257/0x340 [f2fs]
+ f2fs_write_checkpoint+0x102/0x1050 [f2fs]
+ f2fs_gc+0x27c/0x630 [f2fs]
+ ? folio_mark_dirty+0x36/0x70
+ f2fs_balance_fs+0x16f/0x180 [f2fs]
+
+This patch adds checking whether free sections are enough before checkpoint
+during gc.
+
+Signed-off-by: Yonggil Song <yonggil.song@samsung.com>
+[Jaegeuk Kim: code clean-up]
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/gc.c | 10 ++++++++--
+ fs/f2fs/gc.h | 2 ++
+ fs/f2fs/segment.h | 39 ++++++++++++++++++++++++++++++---------
+ 3 files changed, 40 insertions(+), 11 deletions(-)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 5cd19fdc10596..7e497f5b349ce 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1811,6 +1811,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control)
+ .iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS),
+ };
+ unsigned int skipped_round = 0, round = 0;
++ unsigned int upper_secs;
+
+ trace_f2fs_gc_begin(sbi->sb, gc_type, gc_control->no_bg_gc,
+ gc_control->nr_free_secs,
+@@ -1896,8 +1897,13 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control)
+ }
+ }
+
+- /* Write checkpoint to reclaim prefree segments */
+- if (free_sections(sbi) < NR_CURSEG_PERSIST_TYPE &&
++ __get_secs_required(sbi, NULL, &upper_secs, NULL);
++
++ /*
++ * Write checkpoint to reclaim prefree segments.
++ * We need more three extra sections for writer's data/node/dentry.
++ */
++ if (free_sections(sbi) <= upper_secs + NR_GC_CHECKPOINT_SECS &&
+ prefree_segments(sbi)) {
+ ret = f2fs_write_checkpoint(sbi, &cpc);
+ if (ret)
+diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
+index ca84024b9c9e7..47357101b03cd 100644
+--- a/fs/f2fs/gc.h
++++ b/fs/f2fs/gc.h
+@@ -30,6 +30,8 @@
+ /* Search max. number of dirty segments to select a victim segment */
+ #define DEF_MAX_VICTIM_SEARCH 4096 /* covers 8GB */
+
++#define NR_GC_CHECKPOINT_SECS (3) /* data/node/dentry sections */
++
+ struct f2fs_gc_kthread {
+ struct task_struct *f2fs_gc_task;
+ wait_queue_head_t gc_wait_queue_head;
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index cd65778fc9822..f3951e8ad3948 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -608,8 +608,12 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi,
+ return true;
+ }
+
+-static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi,
+- int freed, int needed)
++/*
++ * calculate needed sections for dirty node/dentry
++ * and call has_curseg_enough_space
++ */
++static inline void __get_secs_required(struct f2fs_sb_info *sbi,
++ unsigned int *lower_p, unsigned int *upper_p, bool *curseg_p)
+ {
+ unsigned int total_node_blocks = get_pages(sbi, F2FS_DIRTY_NODES) +
+ get_pages(sbi, F2FS_DIRTY_DENTS) +
+@@ -619,20 +623,37 @@ static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi,
+ unsigned int dent_secs = total_dent_blocks / CAP_BLKS_PER_SEC(sbi);
+ unsigned int node_blocks = total_node_blocks % CAP_BLKS_PER_SEC(sbi);
+ unsigned int dent_blocks = total_dent_blocks % CAP_BLKS_PER_SEC(sbi);
+- unsigned int free, need_lower, need_upper;
++
++ if (lower_p)
++ *lower_p = node_secs + dent_secs;
++ if (upper_p)
++ *upper_p = node_secs + dent_secs +
++ (node_blocks ? 1 : 0) + (dent_blocks ? 1 : 0);
++ if (curseg_p)
++ *curseg_p = has_curseg_enough_space(sbi,
++ node_blocks, dent_blocks);
++}
++
++static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi,
++ int freed, int needed)
++{
++ unsigned int free_secs, lower_secs, upper_secs;
++ bool curseg_space;
+
+ if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
+ return false;
+
+- free = free_sections(sbi) + freed;
+- need_lower = node_secs + dent_secs + reserved_sections(sbi) + needed;
+- need_upper = need_lower + (node_blocks ? 1 : 0) + (dent_blocks ? 1 : 0);
++ __get_secs_required(sbi, &lower_secs, &upper_secs, &curseg_space);
++
++ free_secs = free_sections(sbi) + freed;
++ lower_secs += needed + reserved_sections(sbi);
++ upper_secs += needed + reserved_sections(sbi);
+
+- if (free > need_upper)
++ if (free_secs > upper_secs)
+ return false;
+- else if (free <= need_lower)
++ else if (free_secs <= lower_secs)
+ return true;
+- return !has_curseg_enough_space(sbi, node_blocks, dent_blocks);
++ return !curseg_space;
+ }
+
+ static inline bool f2fs_is_checkpoint_ready(struct f2fs_sb_info *sbi)
+--
+2.39.2
+
--- /dev/null
+From 7e5c8debc29b5cc222d94b9d310b1138dbde099c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Apr 2023 23:28:07 +0800
+Subject: f2fs: fix to check readonly condition correctly
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit d78dfefcde9d311284434560d69c0478c55a657e ]
+
+With below case, it can mount multi-device image w/ rw option, however
+one of secondary device is set as ro, later update will cause panic, so
+let's introduce f2fs_dev_is_readonly(), and check multi-devices rw status
+in f2fs_remount() w/ it in order to avoid such inconsistent mount status.
+
+mkfs.f2fs -c /dev/zram1 /dev/zram0 -f
+blockdev --setro /dev/zram1
+mount -t f2fs dev/zram0 /mnt/f2fs
+mount: /mnt/f2fs: WARNING: source write-protected, mounted read-only.
+mount -t f2fs -o remount,rw mnt/f2fs
+dd if=/dev/zero of=/mnt/f2fs/file bs=1M count=8192
+
+kernel BUG at fs/f2fs/inline.c:258!
+RIP: 0010:f2fs_write_inline_data+0x23e/0x2d0 [f2fs]
+Call Trace:
+ f2fs_write_single_data_page+0x26b/0x9f0 [f2fs]
+ f2fs_write_cache_pages+0x389/0xa60 [f2fs]
+ __f2fs_write_data_pages+0x26b/0x2d0 [f2fs]
+ f2fs_write_data_pages+0x2e/0x40 [f2fs]
+ do_writepages+0xd3/0x1b0
+ __writeback_single_inode+0x5b/0x420
+ writeback_sb_inodes+0x236/0x5a0
+ __writeback_inodes_wb+0x56/0xf0
+ wb_writeback+0x2a3/0x490
+ wb_do_writeback+0x2b2/0x330
+ wb_workfn+0x6a/0x260
+ process_one_work+0x270/0x5e0
+ worker_thread+0x52/0x3e0
+ kthread+0xf4/0x120
+ ret_from_fork+0x29/0x50
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h | 5 +++++
+ fs/f2fs/super.c | 2 +-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index a0a232551da97..8d7dc76e6f935 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -4435,6 +4435,11 @@ static inline bool f2fs_hw_is_readonly(struct f2fs_sb_info *sbi)
+ return false;
+ }
+
++static inline bool f2fs_dev_is_readonly(struct f2fs_sb_info *sbi)
++{
++ return f2fs_sb_has_readonly(sbi) || f2fs_hw_is_readonly(sbi);
++}
++
+ static inline bool f2fs_lfs_mode(struct f2fs_sb_info *sbi)
+ {
+ return F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS;
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index c46533d65372c..b6dad389fa144 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -2258,7 +2258,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+ if (f2fs_readonly(sb) && (*flags & SB_RDONLY))
+ goto skip;
+
+- if (f2fs_sb_has_readonly(sbi) && !(*flags & SB_RDONLY)) {
++ if (f2fs_dev_is_readonly(sbi) && !(*flags & SB_RDONLY)) {
+ err = -EROFS;
+ goto restore_opts;
+ }
+--
+2.39.2
+
--- /dev/null
+From 3fee00cc080a17059df7b5b5e9ee8d56862a4936 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Apr 2023 10:12:22 +0800
+Subject: f2fs: fix to drop all dirty pages during umount() if cp_error is set
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit c9b3649a934d131151111354bcbb638076f03a30 ]
+
+xfstest generic/361 reports a bug as below:
+
+f2fs_bug_on(sbi, sbi->fsync_node_num);
+
+kernel BUG at fs/f2fs/super.c:1627!
+RIP: 0010:f2fs_put_super+0x3a8/0x3b0
+Call Trace:
+ generic_shutdown_super+0x8c/0x1b0
+ kill_block_super+0x2b/0x60
+ kill_f2fs_super+0x87/0x110
+ deactivate_locked_super+0x39/0x80
+ deactivate_super+0x46/0x50
+ cleanup_mnt+0x109/0x170
+ __cleanup_mnt+0x16/0x20
+ task_work_run+0x65/0xa0
+ exit_to_user_mode_prepare+0x175/0x190
+ syscall_exit_to_user_mode+0x25/0x50
+ do_syscall_64+0x4c/0x90
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+
+During umount(), if cp_error is set, f2fs_wait_on_all_pages() should
+not stop waiting all F2FS_WB_CP_DATA pages to be writebacked, otherwise,
+fsync_node_num can be non-zero after f2fs_wait_on_all_pages() causing
+this bug.
+
+In this case, to avoid deadloop in f2fs_wait_on_all_pages(), it needs
+to drop all dirty pages rather than redirtying them.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/checkpoint.c | 12 ++++++++++--
+ fs/f2fs/data.c | 3 ++-
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index 0c82dae082aa9..5df04ed010cae 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -322,8 +322,15 @@ static int __f2fs_write_meta_page(struct page *page,
+
+ trace_f2fs_writepage(page, META);
+
+- if (unlikely(f2fs_cp_error(sbi)))
++ if (unlikely(f2fs_cp_error(sbi))) {
++ if (is_sbi_flag_set(sbi, SBI_IS_CLOSE)) {
++ ClearPageUptodate(page);
++ dec_page_count(sbi, F2FS_DIRTY_META);
++ unlock_page(page);
++ return 0;
++ }
+ goto redirty_out;
++ }
+ if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
+ goto redirty_out;
+ if (wbc->for_reclaim && page->index < GET_SUM_BLOCK(sbi, 0))
+@@ -1301,7 +1308,8 @@ void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type)
+ if (!get_pages(sbi, type))
+ break;
+
+- if (unlikely(f2fs_cp_error(sbi)))
++ if (unlikely(f2fs_cp_error(sbi) &&
++ !is_sbi_flag_set(sbi, SBI_IS_CLOSE)))
+ break;
+
+ if (type == F2FS_DIRTY_META)
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index de6b056f090b3..36db9aab47790 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -2788,7 +2788,8 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
+ * don't drop any dirty dentry pages for keeping lastest
+ * directory structure.
+ */
+- if (S_ISDIR(inode->i_mode))
++ if (S_ISDIR(inode->i_mode) &&
++ !is_sbi_flag_set(sbi, SBI_IS_CLOSE))
+ goto redirty_out;
+ goto out;
+ }
+--
+2.39.2
+
--- /dev/null
+From a9c5c8f411f906366c32ab2d93b7955f2ba5423c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Feb 2023 09:49:19 +0100
+Subject: firmware: arm_sdei: Fix sleep from invalid context BUG
+
+From: Pierre Gondois <pierre.gondois@arm.com>
+
+[ Upstream commit d2c48b2387eb89e0bf2a2e06e30987cf410acad4 ]
+
+Running a preempt-rt (v6.2-rc3-rt1) based kernel on an Ampere Altra
+triggers:
+
+ BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:46
+ in_atomic(): 0, irqs_disabled(): 128, non_block: 0, pid: 24, name: cpuhp/0
+ preempt_count: 0, expected: 0
+ RCU nest depth: 0, expected: 0
+ 3 locks held by cpuhp/0/24:
+ #0: ffffda30217c70d0 (cpu_hotplug_lock){++++}-{0:0}, at: cpuhp_thread_fun+0x5c/0x248
+ #1: ffffda30217c7120 (cpuhp_state-up){+.+.}-{0:0}, at: cpuhp_thread_fun+0x5c/0x248
+ #2: ffffda3021c711f0 (sdei_list_lock){....}-{3:3}, at: sdei_cpuhp_up+0x3c/0x130
+ irq event stamp: 36
+ hardirqs last enabled at (35): [<ffffda301e85b7bc>] finish_task_switch+0xb4/0x2b0
+ hardirqs last disabled at (36): [<ffffda301e812fec>] cpuhp_thread_fun+0x21c/0x248
+ softirqs last enabled at (0): [<ffffda301e80b184>] copy_process+0x63c/0x1ac0
+ softirqs last disabled at (0): [<0000000000000000>] 0x0
+ CPU: 0 PID: 24 Comm: cpuhp/0 Not tainted 5.19.0-rc3-rt5-[...]
+ Hardware name: WIWYNN Mt.Jade Server [...]
+ Call trace:
+ dump_backtrace+0x114/0x120
+ show_stack+0x20/0x70
+ dump_stack_lvl+0x9c/0xd8
+ dump_stack+0x18/0x34
+ __might_resched+0x188/0x228
+ rt_spin_lock+0x70/0x120
+ sdei_cpuhp_up+0x3c/0x130
+ cpuhp_invoke_callback+0x250/0xf08
+ cpuhp_thread_fun+0x120/0x248
+ smpboot_thread_fn+0x280/0x320
+ kthread+0x130/0x140
+ ret_from_fork+0x10/0x20
+
+sdei_cpuhp_up() is called in the STARTING hotplug section,
+which runs with interrupts disabled. Use a CPUHP_AP_ONLINE_DYN entry
+instead to execute the cpuhp cb later, with preemption enabled.
+
+SDEI originally got its own cpuhp slot to allow interacting
+with perf. It got superseded by pNMI and this early slot is not
+relevant anymore. [1]
+
+Some SDEI calls (e.g. SDEI_1_0_FN_SDEI_PE_MASK) take actions on the
+calling CPU. It is checked that preemption is disabled for them.
+_ONLINE cpuhp cb are executed in the 'per CPU hotplug thread'.
+Preemption is enabled in those threads, but their cpumask is limited
+to 1 CPU.
+Move 'WARN_ON_ONCE(preemptible())' statements so that SDEI cpuhp cb
+don't trigger them.
+
+Also add a check for the SDEI_1_0_FN_SDEI_PRIVATE_RESET SDEI call
+which acts on the calling CPU.
+
+[1]:
+https://lore.kernel.org/all/5813b8c5-ae3e-87fd-fccc-94c9cd08816d@arm.com/
+
+Suggested-by: James Morse <james.morse@arm.com>
+Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
+Reviewed-by: James Morse <james.morse@arm.com>
+Link: https://lore.kernel.org/r/20230216084920.144064-1-pierre.gondois@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_sdei.c | 37 ++++++++++++++++++++-----------------
+ include/linux/cpuhotplug.h | 1 -
+ 2 files changed, 20 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
+index 1e1a51510e83b..f9040bd610812 100644
+--- a/drivers/firmware/arm_sdei.c
++++ b/drivers/firmware/arm_sdei.c
+@@ -43,6 +43,8 @@ static asmlinkage void (*sdei_firmware_call)(unsigned long function_id,
+ /* entry point from firmware to arch asm code */
+ static unsigned long sdei_entry_point;
+
++static int sdei_hp_state;
++
+ struct sdei_event {
+ /* These three are protected by the sdei_list_lock */
+ struct list_head list;
+@@ -301,8 +303,6 @@ int sdei_mask_local_cpu(void)
+ {
+ int err;
+
+- WARN_ON_ONCE(preemptible());
+-
+ err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PE_MASK, 0, 0, 0, 0, 0, NULL);
+ if (err && err != -EIO) {
+ pr_warn_once("failed to mask CPU[%u]: %d\n",
+@@ -315,6 +315,7 @@ int sdei_mask_local_cpu(void)
+
+ static void _ipi_mask_cpu(void *ignored)
+ {
++ WARN_ON_ONCE(preemptible());
+ sdei_mask_local_cpu();
+ }
+
+@@ -322,8 +323,6 @@ int sdei_unmask_local_cpu(void)
+ {
+ int err;
+
+- WARN_ON_ONCE(preemptible());
+-
+ err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PE_UNMASK, 0, 0, 0, 0, 0, NULL);
+ if (err && err != -EIO) {
+ pr_warn_once("failed to unmask CPU[%u]: %d\n",
+@@ -336,6 +335,7 @@ int sdei_unmask_local_cpu(void)
+
+ static void _ipi_unmask_cpu(void *ignored)
+ {
++ WARN_ON_ONCE(preemptible());
+ sdei_unmask_local_cpu();
+ }
+
+@@ -343,6 +343,8 @@ static void _ipi_private_reset(void *ignored)
+ {
+ int err;
+
++ WARN_ON_ONCE(preemptible());
++
+ err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PRIVATE_RESET, 0, 0, 0, 0, 0,
+ NULL);
+ if (err && err != -EIO)
+@@ -389,8 +391,6 @@ static void _local_event_enable(void *data)
+ int err;
+ struct sdei_crosscall_args *arg = data;
+
+- WARN_ON_ONCE(preemptible());
+-
+ err = sdei_api_event_enable(arg->event->event_num);
+
+ sdei_cross_call_return(arg, err);
+@@ -479,8 +479,6 @@ static void _local_event_unregister(void *data)
+ int err;
+ struct sdei_crosscall_args *arg = data;
+
+- WARN_ON_ONCE(preemptible());
+-
+ err = sdei_api_event_unregister(arg->event->event_num);
+
+ sdei_cross_call_return(arg, err);
+@@ -561,8 +559,6 @@ static void _local_event_register(void *data)
+ struct sdei_registered_event *reg;
+ struct sdei_crosscall_args *arg = data;
+
+- WARN_ON(preemptible());
+-
+ reg = per_cpu_ptr(arg->event->private_registered, smp_processor_id());
+ err = sdei_api_event_register(arg->event->event_num, sdei_entry_point,
+ reg, 0, 0);
+@@ -717,6 +713,8 @@ static int sdei_pm_notifier(struct notifier_block *nb, unsigned long action,
+ {
+ int rv;
+
++ WARN_ON_ONCE(preemptible());
++
+ switch (action) {
+ case CPU_PM_ENTER:
+ rv = sdei_mask_local_cpu();
+@@ -765,7 +763,7 @@ static int sdei_device_freeze(struct device *dev)
+ int err;
+
+ /* unregister private events */
+- cpuhp_remove_state(CPUHP_AP_ARM_SDEI_STARTING);
++ cpuhp_remove_state(sdei_entry_point);
+
+ err = sdei_unregister_shared();
+ if (err)
+@@ -786,12 +784,15 @@ static int sdei_device_thaw(struct device *dev)
+ return err;
+ }
+
+- err = cpuhp_setup_state(CPUHP_AP_ARM_SDEI_STARTING, "SDEI",
++ err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "SDEI",
+ &sdei_cpuhp_up, &sdei_cpuhp_down);
+- if (err)
++ if (err < 0) {
+ pr_warn("Failed to re-register CPU hotplug notifier...\n");
++ return err;
++ }
+
+- return err;
++ sdei_hp_state = err;
++ return 0;
+ }
+
+ static int sdei_device_restore(struct device *dev)
+@@ -823,7 +824,7 @@ static int sdei_reboot_notifier(struct notifier_block *nb, unsigned long action,
+ * We are going to reset the interface, after this there is no point
+ * doing work when we take CPUs offline.
+ */
+- cpuhp_remove_state(CPUHP_AP_ARM_SDEI_STARTING);
++ cpuhp_remove_state(sdei_hp_state);
+
+ sdei_platform_reset();
+
+@@ -1003,13 +1004,15 @@ static int sdei_probe(struct platform_device *pdev)
+ goto remove_cpupm;
+ }
+
+- err = cpuhp_setup_state(CPUHP_AP_ARM_SDEI_STARTING, "SDEI",
++ err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "SDEI",
+ &sdei_cpuhp_up, &sdei_cpuhp_down);
+- if (err) {
++ if (err < 0) {
+ pr_warn("Failed to register CPU hotplug notifier...\n");
+ goto remove_reboot;
+ }
+
++ sdei_hp_state = err;
++
+ return 0;
+
+ remove_reboot:
+diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
+index f61447913db97..2be2091c2b447 100644
+--- a/include/linux/cpuhotplug.h
++++ b/include/linux/cpuhotplug.h
+@@ -161,7 +161,6 @@ enum cpuhp_state {
+ CPUHP_AP_PERF_X86_CSTATE_STARTING,
+ CPUHP_AP_PERF_XTENSA_STARTING,
+ CPUHP_AP_MIPS_OP_LOONGSON3_STARTING,
+- CPUHP_AP_ARM_SDEI_STARTING,
+ CPUHP_AP_ARM_VFP_STARTING,
+ CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING,
+ CPUHP_AP_PERF_ARM_HW_BREAKPOINT_STARTING,
+--
+2.39.2
+
--- /dev/null
+From e5e67dd72a4e96fa9487d066d7c77a2981ba4e87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Apr 2023 19:57:33 +0900
+Subject: fs: hfsplus: remove WARN_ON() from hfsplus_cat_{read,write}_inode()
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+[ Upstream commit 81b21c0f0138ff5a499eafc3eb0578ad2a99622c ]
+
+syzbot is hitting WARN_ON() in hfsplus_cat_{read,write}_inode(), for
+crafted filesystem image can contain bogus length. There conditions are
+not kernel bugs that can justify kernel to panic.
+
+Reported-by: syzbot <syzbot+e2787430e752a92b8750@syzkaller.appspotmail.com>
+Link: https://syzkaller.appspot.com/bug?extid=e2787430e752a92b8750
+Reported-by: syzbot <syzbot+4913dca2ea6e4d43f3f1@syzkaller.appspotmail.com>
+Link: https://syzkaller.appspot.com/bug?extid=4913dca2ea6e4d43f3f1
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Message-Id: <15308173-5252-d6a3-ae3b-e96d46cb6f41@I-love.SAKURA.ne.jp>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/hfsplus/inode.c | 28 +++++++++++++++++++++++-----
+ 1 file changed, 23 insertions(+), 5 deletions(-)
+
+diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
+index b675581aa9d0f..399a6354f0cc5 100644
+--- a/fs/hfsplus/inode.c
++++ b/fs/hfsplus/inode.c
+@@ -511,7 +511,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
+ if (type == HFSPLUS_FOLDER) {
+ struct hfsplus_cat_folder *folder = &entry.folder;
+
+- WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_folder));
++ if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) {
++ pr_err("bad catalog folder entry\n");
++ res = -EIO;
++ goto out;
++ }
+ hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
+ sizeof(struct hfsplus_cat_folder));
+ hfsplus_get_perms(inode, &folder->permissions, 1);
+@@ -531,7 +535,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
+ } else if (type == HFSPLUS_FILE) {
+ struct hfsplus_cat_file *file = &entry.file;
+
+- WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_file));
++ if (fd->entrylength < sizeof(struct hfsplus_cat_file)) {
++ pr_err("bad catalog file entry\n");
++ res = -EIO;
++ goto out;
++ }
+ hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
+ sizeof(struct hfsplus_cat_file));
+
+@@ -562,6 +570,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
+ pr_err("bad catalog entry used to create inode\n");
+ res = -EIO;
+ }
++out:
+ return res;
+ }
+
+@@ -570,6 +579,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
+ struct inode *main_inode = inode;
+ struct hfs_find_data fd;
+ hfsplus_cat_entry entry;
++ int res = 0;
+
+ if (HFSPLUS_IS_RSRC(inode))
+ main_inode = HFSPLUS_I(inode)->rsrc_inode;
+@@ -588,7 +598,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
+ if (S_ISDIR(main_inode->i_mode)) {
+ struct hfsplus_cat_folder *folder = &entry.folder;
+
+- WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_folder));
++ if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) {
++ pr_err("bad catalog folder entry\n");
++ res = -EIO;
++ goto out;
++ }
+ hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
+ sizeof(struct hfsplus_cat_folder));
+ /* simple node checks? */
+@@ -613,7 +627,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
+ } else {
+ struct hfsplus_cat_file *file = &entry.file;
+
+- WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_file));
++ if (fd.entrylength < sizeof(struct hfsplus_cat_file)) {
++ pr_err("bad catalog file entry\n");
++ res = -EIO;
++ goto out;
++ }
+ hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
+ sizeof(struct hfsplus_cat_file));
+ hfsplus_inode_write_fork(inode, &file->data_fork);
+@@ -634,7 +652,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
+ set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags);
+ out:
+ hfs_find_exit(&fd);
+- return 0;
++ return res;
+ }
+
+ int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa)
+--
+2.39.2
+
--- /dev/null
+From c4a0b04e8d4e6cc536f09ff1ceac08ca02c31709 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Mar 2023 00:43:16 +0200
+Subject: gfs2: Fix inode height consistency check
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit cfcdb5bad34f600aed7613c3c1a5e618111f77b7 ]
+
+The maximum allowed height of an inode's metadata tree depends on the
+filesystem block size; it is lower for bigger-block filesystems. When
+reading in an inode, make sure that the height doesn't exceed the
+maximum allowed height.
+
+Arrays like sd_heightsize are sized to be big enough for any filesystem
+block size; they will often be slightly bigger than what's needed for a
+specific filesystem.
+
+Reported-by: syzbot+45d4691b1ed3c48eba05@syzkaller.appspotmail.com
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/glops.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
+index d78b61ecc1cdf..7762483f5f20f 100644
+--- a/fs/gfs2/glops.c
++++ b/fs/gfs2/glops.c
+@@ -393,6 +393,7 @@ static int inode_go_demote_ok(const struct gfs2_glock *gl)
+
+ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
+ {
++ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+ const struct gfs2_dinode *str = buf;
+ struct timespec64 atime;
+ u16 height, depth;
+@@ -439,7 +440,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
+ /* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */
+ gfs2_set_inode_flags(inode);
+ height = be16_to_cpu(str->di_height);
+- if (unlikely(height > GFS2_MAX_META_HEIGHT))
++ if (unlikely(height > sdp->sd_max_height))
+ goto corrupt;
+ ip->i_height = (u8)height;
+
+--
+2.39.2
+
--- /dev/null
+From a39c7f373843639ade37590834039fefcc7f2eba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Apr 2023 20:48:29 -0600
+Subject: HID: apple: Set the tilde quirk flag on the Geyser 3
+
+From: Alex Henrie <alexhenrie24@gmail.com>
+
+[ Upstream commit 29e1ecc197d410ee59c8877098d54cf417075f7d ]
+
+I was finally able to obtain a MacBook1,1 to test and I've now confirmed
+that it has the tilde key quirk as well:
+
+Product Model Year System CPU Shape Labels Country Quirky
+============================================================================
+05ac:0218 A1181 2006 MacBook1,1 T2500 ISO British 13 Yes
+
+Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
+Link: https://lore.kernel.org/r/20230404024829.13982-1-alexhenrie24@gmail.com
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-apple.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
+index f21b1c4ca8254..37b2ce9b50fe8 100644
+--- a/drivers/hid/hid-apple.c
++++ b/drivers/hid/hid-apple.c
+@@ -854,7 +854,8 @@ static const struct hid_device_id apple_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO),
+- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
++ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
++ APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+ APPLE_RDESC_JIS },
+--
+2.39.2
+
--- /dev/null
+From 4db440ae1aed5aa51bc24f788180697a3dec0fd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 26 Feb 2023 20:06:13 -0700
+Subject: HID: apple: Set the tilde quirk flag on the Geyser 4 and later
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alex Henrie <alexhenrie24@gmail.com>
+
+[ Upstream commit c3388ddc74a863466c7c3fa24d3a9cea9c9bca53 ]
+
+I recently tested several old MacBooks and as far as I can tell, all
+MacBooks that have an ISO keyboard have the tilde key quirk:
+
+Product Model Year System CPU Shape Labels Country Quirky
+============================================================================
+05ac:021b A1181 2006 MacBook2,1 T5600 ISO British 13 Yes
+05ac:021b A1181 2007 MacBook2,1 T7200 ISO Québécois 13 Yes
+05ac:0229 A1181 2007 MacBook4,1 T8300 ANSI Usonian 33 No
+05ac:022a A1181 2007 MacBook4,1 T8100 ISO English 13 Yes
+05ac:022a A1181 2007 MacBook5,2 P7350 ISO Québécois 13 Yes
+05ac:0237 A1278 2008 MacBook5,1 P7350 ISO Dutch 13 Yes
+05ac:0237 A1278 2009 MacBook5,5 P7550 ISO British 13 Yes
+
+The model number and year are from the laptop case. Since Apple printed
+the same model and year on many different laptops, the system name (as
+reported in the SMBIOS tables) and CPU form a more precise identifier.
+
+Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-apple.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
+index c671ce94671ca..f21b1c4ca8254 100644
+--- a/drivers/hid/hid-apple.c
++++ b/drivers/hid/hid-apple.c
+@@ -861,7 +861,8 @@ static const struct hid_device_id apple_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO),
+- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
++ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
++ APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+ APPLE_RDESC_JIS },
+@@ -880,7 +881,8 @@ static const struct hid_device_id apple_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO),
+- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
++ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
++ APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+ APPLE_RDESC_JIS },
+@@ -921,31 +923,31 @@ static const struct hid_device_id apple_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
+- .driver_data = APPLE_HAS_FN },
++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
+- .driver_data = APPLE_HAS_FN },
++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
+- .driver_data = APPLE_HAS_FN },
++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO),
+- .driver_data = APPLE_HAS_FN },
++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO),
+- .driver_data = APPLE_HAS_FN },
++ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI),
+--
+2.39.2
+
--- /dev/null
+From 8db50d208d52c765397edc0c0129fe9d3ff292b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Mar 2023 19:56:38 +0800
+Subject: HID: Ignore battery for ELAN touchscreen on ROG Flow X13 GV301RA
+
+From: weiliang1503 <weiliang1503@gmail.com>
+
+[ Upstream commit 35903009dbde804a1565dc89e431c0f15179f054 ]
+
+Ignore the reported battery level of the built-in touchscreen to suppress
+battery warnings when a stylus is used. The device ID was added and the
+battery ignore quirk was enabled.
+
+Signed-off-by: weiliang1503 <weiliang1503@gmail.com>
+Link: https://lore.kernel.org/r/20230330115638.16146-1-weiliang1503@gmail.com
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-ids.h | 1 +
+ drivers/hid/hid-input.c | 2 ++
+ 2 files changed, 3 insertions(+)
+
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 2235d78784b1b..53c6692d77714 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -415,6 +415,7 @@
+ #define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817
+ #define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG 0x29DF
+ #define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8
++#define I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN 0x2C82
+ #define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
+ #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
+ #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index c3f80b516f398..3acaaca888acd 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -372,6 +372,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
+ HID_BATTERY_QUIRK_IGNORE },
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN),
+ HID_BATTERY_QUIRK_IGNORE },
++ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN),
++ HID_BATTERY_QUIRK_IGNORE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
+ HID_BATTERY_QUIRK_IGNORE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
+--
+2.39.2
+
--- /dev/null
+From 94c1c6d4cb3bb2f8156aee7305e815cf1c3a6f21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Mar 2023 14:01:16 +0100
+Subject: HID: logitech-hidpp: Don't use the USB serial for USB devices
+
+From: Bastien Nocera <hadess@hadess.net>
+
+[ Upstream commit 7ad1fe0da0fa91bf920b79ab05ae97bfabecc4f4 ]
+
+For devices that support the 0x0003 feature (Device Information) version 4,
+set the serial based on the output of that feature, rather than relying
+on the usbhid code setting the USB serial.
+
+This should allow the serial when connected through USB to (nearly)
+match the one when connected through a unifying receiver.
+
+For example, on the serials on a G903 wired/wireless mouse:
+- Unifying: 4067-e8-ce-cd-45
+- USB before patch: 017C385C3837
+- USB after patch: c086-e8-ce-cd-45
+
+Signed-off-by: Bastien Nocera <hadess@hadess.net>
+Link: https://lore.kernel.org/r/20230302130117.3975-1-hadess@hadess.net
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-hidpp.c | 51 ++++++++++++++++++++++++++++++++
+ 1 file changed, 51 insertions(+)
+
+diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
+index e906ee375298a..c39a4c56678de 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -932,6 +932,55 @@ static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp)
+ return 0;
+ }
+
++/* -------------------------------------------------------------------------- */
++/* 0x0003: Device Information */
++/* -------------------------------------------------------------------------- */
++
++#define HIDPP_PAGE_DEVICE_INFORMATION 0x0003
++
++#define CMD_GET_DEVICE_INFO 0x00
++
++static int hidpp_get_serial(struct hidpp_device *hidpp, u32 *serial)
++{
++ struct hidpp_report response;
++ u8 feature_type;
++ u8 feature_index;
++ int ret;
++
++ ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_DEVICE_INFORMATION,
++ &feature_index,
++ &feature_type);
++ if (ret)
++ return ret;
++
++ ret = hidpp_send_fap_command_sync(hidpp, feature_index,
++ CMD_GET_DEVICE_INFO,
++ NULL, 0, &response);
++ if (ret)
++ return ret;
++
++ /* See hidpp_unifying_get_serial() */
++ *serial = *((u32 *)&response.rap.params[1]);
++ return 0;
++}
++
++static int hidpp_serial_init(struct hidpp_device *hidpp)
++{
++ struct hid_device *hdev = hidpp->hid_dev;
++ u32 serial;
++ int ret;
++
++ ret = hidpp_get_serial(hidpp, &serial);
++ if (ret)
++ return ret;
++
++ snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD",
++ hdev->product, &serial);
++ dbg_hid("HID++ DeviceInformation: Got serial: %s\n", hdev->uniq);
++
++ return 0;
++}
++
+ /* -------------------------------------------------------------------------- */
+ /* 0x0005: GetDeviceNameType */
+ /* -------------------------------------------------------------------------- */
+@@ -4194,6 +4243,8 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+
+ if (hidpp->quirks & HIDPP_QUIRK_UNIFYING)
+ hidpp_unifying_init(hidpp);
++ else if (hid_is_usb(hidpp->hid_dev))
++ hidpp_serial_init(hidpp);
+
+ connected = hidpp_root_get_protocol_version(hidpp) == 0;
+ atomic_set(&hidpp->connected, connected);
+--
+2.39.2
+
--- /dev/null
+From 7b748021d38db5efb04b4341008408664b2b482d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Mar 2023 14:01:17 +0100
+Subject: HID: logitech-hidpp: Reconcile USB and Unifying serials
+
+From: Bastien Nocera <hadess@hadess.net>
+
+[ Upstream commit 5b3691d15e04b6d5a32c915577b8dbc5cfb56382 ]
+
+Now that USB HID++ devices can gather a serial number that matches the
+one that would be gathered when connected through a Unifying receiver,
+remove the last difference by dropping the product ID as devices
+usually have different product IDs when connected through USB or
+Unifying.
+
+For example, on the serials on a G903 wired/wireless mouse:
+- Unifying before patch: 4067-e8-ce-cd-45
+- USB before patch: c086-e8-ce-cd-45
+- Unifying and USB after patch: e8-ce-cd-45
+
+Signed-off-by: Bastien Nocera <hadess@hadess.net>
+Link: https://lore.kernel.org/r/20230302130117.3975-2-hadess@hadess.net
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-hidpp.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
+index c39a4c56678de..b2cd7527de195 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -838,8 +838,7 @@ static int hidpp_unifying_init(struct hidpp_device *hidpp)
+ if (ret)
+ return ret;
+
+- snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD",
+- hdev->product, &serial);
++ snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial);
+ dbg_hid("HID++ Unifying: Got serial: %s\n", hdev->uniq);
+
+ name = hidpp_unifying_get_name(hidpp);
+@@ -974,8 +973,7 @@ static int hidpp_serial_init(struct hidpp_device *hidpp)
+ if (ret)
+ return ret;
+
+- snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD",
+- hdev->product, &serial);
++ snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial);
+ dbg_hid("HID++ DeviceInformation: Got serial: %s\n", hdev->uniq);
+
+ return 0;
+--
+2.39.2
+
--- /dev/null
+From 6c3bb62c462da2669ab367350f538a86faaf8814 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Apr 2023 11:17:43 -0700
+Subject: HID: wacom: generic: Set battery quirk only when we see battery data
+
+From: Jason Gerecke <killertofu@gmail.com>
+
+[ Upstream commit bea407a427baa019758f29f4d31b26f008bb8cc6 ]
+
+Some devices will include battery status usages in the HID descriptor
+but we won't see that battery data for one reason or another. For example,
+AES sensors won't send battery data unless an AES pen is in proximity.
+If a user does not have an AES pen but instead only interacts with the
+AES touchscreen with their fingers then there is no need for us to create
+a battery object. Similarly, if a family of peripherals shares the same
+HID descriptor between wired-only and wireless-capable SKUs, users of the
+former may never see a battery event and will not want a power_supply
+object created.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217062
+Link: https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2354
+Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
+Tested-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/wacom_wac.c | 33 +++++++++++----------------------
+ 1 file changed, 11 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
+index 0c6a82c665c1d..d2f500242ed40 100644
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -1963,18 +1963,7 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
+ static void wacom_wac_battery_usage_mapping(struct hid_device *hdev,
+ struct hid_field *field, struct hid_usage *usage)
+ {
+- struct wacom *wacom = hid_get_drvdata(hdev);
+- struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+- struct wacom_features *features = &wacom_wac->features;
+- unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
+-
+- switch (equivalent_usage) {
+- case HID_DG_BATTERYSTRENGTH:
+- case WACOM_HID_WD_BATTERY_LEVEL:
+- case WACOM_HID_WD_BATTERY_CHARGING:
+- features->quirks |= WACOM_QUIRK_BATTERY;
+- break;
+- }
++ return;
+ }
+
+ static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field,
+@@ -1995,18 +1984,21 @@ static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *f
+ wacom_wac->hid_data.bat_connected = 1;
+ wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
+ }
++ wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
+ break;
+ case WACOM_HID_WD_BATTERY_LEVEL:
+ value = value * 100 / (field->logical_maximum - field->logical_minimum);
+ wacom_wac->hid_data.battery_capacity = value;
+ wacom_wac->hid_data.bat_connected = 1;
+ wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
++ wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
+ break;
+ case WACOM_HID_WD_BATTERY_CHARGING:
+ wacom_wac->hid_data.bat_charging = value;
+ wacom_wac->hid_data.ps_connected = value;
+ wacom_wac->hid_data.bat_connected = 1;
+ wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
++ wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
+ break;
+ }
+ }
+@@ -2022,18 +2014,15 @@ static void wacom_wac_battery_report(struct hid_device *hdev,
+ {
+ struct wacom *wacom = hid_get_drvdata(hdev);
+ struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+- struct wacom_features *features = &wacom_wac->features;
+
+- if (features->quirks & WACOM_QUIRK_BATTERY) {
+- int status = wacom_wac->hid_data.bat_status;
+- int capacity = wacom_wac->hid_data.battery_capacity;
+- bool charging = wacom_wac->hid_data.bat_charging;
+- bool connected = wacom_wac->hid_data.bat_connected;
+- bool powered = wacom_wac->hid_data.ps_connected;
++ int status = wacom_wac->hid_data.bat_status;
++ int capacity = wacom_wac->hid_data.battery_capacity;
++ bool charging = wacom_wac->hid_data.bat_charging;
++ bool connected = wacom_wac->hid_data.bat_connected;
++ bool powered = wacom_wac->hid_data.ps_connected;
+
+- wacom_notify_battery(wacom_wac, status, capacity, charging,
+- connected, powered);
+- }
++ wacom_notify_battery(wacom_wac, status, capacity, charging,
++ connected, powered);
+ }
+
+ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
+--
+2.39.2
+
--- /dev/null
+From 6e6024d9af7fe93b6f1db37f0b38d96d7c5c8c3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 17:10:45 +0200
+Subject: ipvs: Update width of source for ip_vs_sync_conn_options
+
+From: Simon Horman <horms@kernel.org>
+
+[ Upstream commit e3478c68f6704638d08f437cbc552ca5970c151a ]
+
+In ip_vs_sync_conn_v0() copy is made to struct ip_vs_sync_conn_options.
+That structure looks like this:
+
+struct ip_vs_sync_conn_options {
+ struct ip_vs_seq in_seq;
+ struct ip_vs_seq out_seq;
+};
+
+The source of the copy is the in_seq field of struct ip_vs_conn. Whose
+type is struct ip_vs_seq. Thus we can see that the source - is not as
+wide as the amount of data copied, which is the width of struct
+ip_vs_sync_conn_option.
+
+The copy is safe because the next field in is another struct ip_vs_seq.
+Make use of struct_group() to annotate this.
+
+Flagged by gcc-13 as:
+
+ In file included from ./include/linux/string.h:254,
+ from ./include/linux/bitmap.h:11,
+ from ./include/linux/cpumask.h:12,
+ from ./arch/x86/include/asm/paravirt.h:17,
+ from ./arch/x86/include/asm/cpuid.h:62,
+ from ./arch/x86/include/asm/processor.h:19,
+ from ./arch/x86/include/asm/timex.h:5,
+ from ./include/linux/timex.h:67,
+ from ./include/linux/time32.h:13,
+ from ./include/linux/time.h:60,
+ from ./include/linux/stat.h:19,
+ from ./include/linux/module.h:13,
+ from net/netfilter/ipvs/ip_vs_sync.c:38:
+ In function 'fortify_memcpy_chk',
+ inlined from 'ip_vs_sync_conn_v0' at net/netfilter/ipvs/ip_vs_sync.c:606:3:
+ ./include/linux/fortify-string.h:529:25: error: call to '__read_overflow2_field' declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Werror=attribute-warning]
+ 529 | __read_overflow2_field(q_size_field, size);
+ |
+
+Compile tested only.
+
+Signed-off-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ip_vs.h | 6 ++++--
+ net/netfilter/ipvs/ip_vs_sync.c | 2 +-
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
+index 1fca6a88114ad..abc46f05762e6 100644
+--- a/include/net/ip_vs.h
++++ b/include/net/ip_vs.h
+@@ -549,8 +549,10 @@ struct ip_vs_conn {
+ */
+ struct ip_vs_app *app; /* bound ip_vs_app object */
+ void *app_data; /* Application private data */
+- struct ip_vs_seq in_seq; /* incoming seq. struct */
+- struct ip_vs_seq out_seq; /* outgoing seq. struct */
++ struct_group(sync_conn_opt,
++ struct ip_vs_seq in_seq; /* incoming seq. struct */
++ struct ip_vs_seq out_seq; /* outgoing seq. struct */
++ );
+
+ const struct ip_vs_pe *pe;
+ char *pe_data;
+diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
+index 4963fec815da3..d4fe7bb4f853a 100644
+--- a/net/netfilter/ipvs/ip_vs_sync.c
++++ b/net/netfilter/ipvs/ip_vs_sync.c
+@@ -603,7 +603,7 @@ static void ip_vs_sync_conn_v0(struct netns_ipvs *ipvs, struct ip_vs_conn *cp,
+ if (cp->flags & IP_VS_CONN_F_SEQ_MASK) {
+ struct ip_vs_sync_conn_options *opt =
+ (struct ip_vs_sync_conn_options *)&s[1];
+- memcpy(opt, &cp->in_seq, sizeof(*opt));
++ memcpy(opt, &cp->sync_conn_opt, sizeof(*opt));
+ }
+
+ m->nr_conns++;
+--
+2.39.2
+
--- /dev/null
+From 5ffd0577502e2806127b81f7635d46361a5ce98b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Mar 2023 21:43:14 -0500
+Subject: irqchip/gicv3: Workaround for NVIDIA erratum T241-FABRIC-4
+
+From: Shanker Donthineni <sdonthineni@nvidia.com>
+
+[ Upstream commit 35727af2b15d98a2dd2811d631d3a3886111312e ]
+
+The T241 platform suffers from the T241-FABRIC-4 erratum which causes
+unexpected behavior in the GIC when multiple transactions are received
+simultaneously from different sources. This hardware issue impacts
+NVIDIA server platforms that use more than two T241 chips
+interconnected. Each chip has support for 320 {E}SPIs.
+
+This issue occurs when multiple packets from different GICs are
+incorrectly interleaved at the target chip. The erratum text below
+specifies exactly what can cause multiple transfer packets susceptible
+to interleaving and GIC state corruption. GIC state corruption can
+lead to a range of problems, including kernel panics, and unexpected
+behavior.
+
+>From the erratum text:
+ "In some cases, inter-socket AXI4 Stream packets with multiple
+ transfers, may be interleaved by the fabric when presented to ARM
+ Generic Interrupt Controller. GIC expects all transfers of a packet
+ to be delivered without any interleaving.
+
+ The following GICv3 commands may result in multiple transfer packets
+ over inter-socket AXI4 Stream interface:
+ - Register reads from GICD_I* and GICD_N*
+ - Register writes to 64-bit GICD registers other than GICD_IROUTERn*
+ - ITS command MOVALL
+
+ Multiple commands in GICv4+ utilize multiple transfer packets,
+ including VMOVP, VMOVI, VMAPP, and 64-bit register accesses."
+
+ This issue impacts system configurations with more than 2 sockets,
+ that require multi-transfer packets to be sent over inter-socket
+ AXI4 Stream interface between GIC instances on different sockets.
+ GICv4 cannot be supported. GICv3 SW model can only be supported
+ with the workaround. Single and Dual socket configurations are not
+ impacted by this issue and support GICv3 and GICv4."
+
+Link: https://developer.nvidia.com/docs/t241-fabric-4/nvidia-t241-fabric-4-errata.pdf
+
+Writing to the chip alias region of the GICD_In{E} registers except
+GICD_ICENABLERn has an equivalent effect as writing to the global
+distributor. The SPI interrupt deactivate path is not impacted by
+the erratum.
+
+To fix this problem, implement a workaround that ensures read accesses
+to the GICD_In{E} registers are directed to the chip that owns the
+SPI, and disable GICv4.x features. To simplify code changes, the
+gic_configure_irq() function uses the same alias region for both read
+and write operations to GICD_ICFGR.
+
+Co-developed-by: Vikram Sethi <vsethi@nvidia.com>
+Signed-off-by: Vikram Sethi <vsethi@nvidia.com>
+Signed-off-by: Shanker Donthineni <sdonthineni@nvidia.com>
+Acked-by: Sudeep Holla <sudeep.holla@arm.com> (for SMCCC/SOC ID bits)
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230319024314.3540573-2-sdonthineni@nvidia.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/arm64/silicon-errata.rst | 2 +
+ drivers/firmware/smccc/smccc.c | 26 ++++++
+ drivers/firmware/smccc/soc_id.c | 28 ++----
+ drivers/irqchip/Kconfig | 1 +
+ drivers/irqchip/irq-gic-v3.c | 115 ++++++++++++++++++++++---
+ include/linux/arm-smccc.h | 18 ++++
+ 6 files changed, 156 insertions(+), 34 deletions(-)
+
+diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
+index 808ade4cc008a..55492fea44276 100644
+--- a/Documentation/arm64/silicon-errata.rst
++++ b/Documentation/arm64/silicon-errata.rst
+@@ -170,6 +170,8 @@ stable kernels.
+ +----------------+-----------------+-----------------+-----------------------------+
+ | NVIDIA | Carmel Core | N/A | NVIDIA_CARMEL_CNP_ERRATUM |
+ +----------------+-----------------+-----------------+-----------------------------+
++| NVIDIA | T241 GICv3/4.x | T241-FABRIC-4 | N/A |
+++----------------+-----------------+-----------------+-----------------------------+
+ +----------------+-----------------+-----------------+-----------------------------+
+ | Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
+ +----------------+-----------------+-----------------+-----------------------------+
+diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c
+index 60ccf3e90d7de..db818f9dcb8ee 100644
+--- a/drivers/firmware/smccc/smccc.c
++++ b/drivers/firmware/smccc/smccc.c
+@@ -17,9 +17,13 @@ static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE;
+
+ bool __ro_after_init smccc_trng_available = false;
+ u64 __ro_after_init smccc_has_sve_hint = false;
++s32 __ro_after_init smccc_soc_id_version = SMCCC_RET_NOT_SUPPORTED;
++s32 __ro_after_init smccc_soc_id_revision = SMCCC_RET_NOT_SUPPORTED;
+
+ void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit)
+ {
++ struct arm_smccc_res res;
++
+ smccc_version = version;
+ smccc_conduit = conduit;
+
+@@ -27,6 +31,18 @@ void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit)
+ if (IS_ENABLED(CONFIG_ARM64_SVE) &&
+ smccc_version >= ARM_SMCCC_VERSION_1_3)
+ smccc_has_sve_hint = true;
++
++ if ((smccc_version >= ARM_SMCCC_VERSION_1_2) &&
++ (smccc_conduit != SMCCC_CONDUIT_NONE)) {
++ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
++ ARM_SMCCC_ARCH_SOC_ID, &res);
++ if ((s32)res.a0 >= 0) {
++ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 0, &res);
++ smccc_soc_id_version = (s32)res.a0;
++ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 1, &res);
++ smccc_soc_id_revision = (s32)res.a0;
++ }
++ }
+ }
+
+ enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void)
+@@ -44,6 +60,16 @@ u32 arm_smccc_get_version(void)
+ }
+ EXPORT_SYMBOL_GPL(arm_smccc_get_version);
+
++s32 arm_smccc_get_soc_id_version(void)
++{
++ return smccc_soc_id_version;
++}
++
++s32 arm_smccc_get_soc_id_revision(void)
++{
++ return smccc_soc_id_revision;
++}
++
+ static int __init smccc_devices_init(void)
+ {
+ struct platform_device *pdev;
+diff --git a/drivers/firmware/smccc/soc_id.c b/drivers/firmware/smccc/soc_id.c
+index dd7c3d5e8b0bb..890eb454599a3 100644
+--- a/drivers/firmware/smccc/soc_id.c
++++ b/drivers/firmware/smccc/soc_id.c
+@@ -42,41 +42,23 @@ static int __init smccc_soc_init(void)
+ if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
+ return 0;
+
+- if (arm_smccc_1_1_get_conduit() == SMCCC_CONDUIT_NONE) {
+- pr_err("%s: invalid SMCCC conduit\n", __func__);
+- return -EOPNOTSUPP;
+- }
+-
+- arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+- ARM_SMCCC_ARCH_SOC_ID, &res);
+-
+- if ((int)res.a0 == SMCCC_RET_NOT_SUPPORTED) {
++ soc_id_version = arm_smccc_get_soc_id_version();
++ if (soc_id_version == SMCCC_RET_NOT_SUPPORTED) {
+ pr_info("ARCH_SOC_ID not implemented, skipping ....\n");
+ return 0;
+ }
+
+- if ((int)res.a0 < 0) {
+- pr_info("ARCH_FEATURES(ARCH_SOC_ID) returned error: %lx\n",
+- res.a0);
+- return -EINVAL;
+- }
+-
+- arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 0, &res);
+- if ((int)res.a0 < 0) {
++ if (soc_id_version < 0) {
+ pr_err("ARCH_SOC_ID(0) returned error: %lx\n", res.a0);
+ return -EINVAL;
+ }
+
+- soc_id_version = res.a0;
+-
+- arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 1, &res);
+- if ((int)res.a0 < 0) {
++ soc_id_rev = arm_smccc_get_soc_id_revision();
++ if (soc_id_rev < 0) {
+ pr_err("ARCH_SOC_ID(1) returned error: %lx\n", res.a0);
+ return -EINVAL;
+ }
+
+- soc_id_rev = res.a0;
+-
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return -ENOMEM;
+diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
+index 7ef9f5e696d31..a29a426e4eed7 100644
+--- a/drivers/irqchip/Kconfig
++++ b/drivers/irqchip/Kconfig
+@@ -35,6 +35,7 @@ config ARM_GIC_V3
+ select IRQ_DOMAIN_HIERARCHY
+ select PARTITION_PERCPU
+ select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
++ select HAVE_ARM_SMCCC_DISCOVERY
+
+ config ARM_GIC_V3_ITS
+ bool
+diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
+index 34d58567b78d1..2182f87d2d12e 100644
+--- a/drivers/irqchip/irq-gic-v3.c
++++ b/drivers/irqchip/irq-gic-v3.c
+@@ -23,6 +23,9 @@
+ #include <linux/irqchip/arm-gic-common.h>
+ #include <linux/irqchip/arm-gic-v3.h>
+ #include <linux/irqchip/irq-partition-percpu.h>
++#include <linux/bitfield.h>
++#include <linux/bits.h>
++#include <linux/arm-smccc.h>
+
+ #include <asm/cputype.h>
+ #include <asm/exception.h>
+@@ -46,6 +49,7 @@ struct redist_region {
+
+ struct gic_chip_data {
+ struct fwnode_handle *fwnode;
++ phys_addr_t dist_phys_base;
+ void __iomem *dist_base;
+ struct redist_region *redist_regions;
+ struct rdists rdists;
+@@ -58,6 +62,10 @@ struct gic_chip_data {
+ struct partition_desc **ppi_descs;
+ };
+
++#define T241_CHIPS_MAX 4
++static void __iomem *t241_dist_base_alias[T241_CHIPS_MAX] __read_mostly;
++static DEFINE_STATIC_KEY_FALSE(gic_nvidia_t241_erratum);
++
+ static struct gic_chip_data gic_data __read_mostly;
+ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
+
+@@ -187,6 +195,39 @@ static inline bool gic_irq_in_rdist(struct irq_data *d)
+ }
+ }
+
++static inline void __iomem *gic_dist_base_alias(struct irq_data *d)
++{
++ if (static_branch_unlikely(&gic_nvidia_t241_erratum)) {
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ u32 chip;
++
++ /*
++ * For the erratum T241-FABRIC-4, read accesses to GICD_In{E}
++ * registers are directed to the chip that owns the SPI. The
++ * the alias region can also be used for writes to the
++ * GICD_In{E} except GICD_ICENABLERn. Each chip has support
++ * for 320 {E}SPIs. Mappings for all 4 chips:
++ * Chip0 = 32-351
++ * Chip1 = 352-671
++ * Chip2 = 672-991
++ * Chip3 = 4096-4415
++ */
++ switch (__get_intid_range(hwirq)) {
++ case SPI_RANGE:
++ chip = (hwirq - 32) / 320;
++ break;
++ case ESPI_RANGE:
++ chip = 3;
++ break;
++ default:
++ unreachable();
++ }
++ return t241_dist_base_alias[chip];
++ }
++
++ return gic_data.dist_base;
++}
++
+ static inline void __iomem *gic_dist_base(struct irq_data *d)
+ {
+ switch (get_intid_range(d)) {
+@@ -345,7 +386,7 @@ static int gic_peek_irq(struct irq_data *d, u32 offset)
+ if (gic_irq_in_rdist(d))
+ base = gic_data_rdist_sgi_base();
+ else
+- base = gic_data.dist_base;
++ base = gic_dist_base_alias(d);
+
+ return !!(readl_relaxed(base + offset + (index / 32) * 4) & mask);
+ }
+@@ -596,7 +637,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
+ if (gic_irq_in_rdist(d))
+ base = gic_data_rdist_sgi_base();
+ else
+- base = gic_data.dist_base;
++ base = gic_dist_base_alias(d);
+
+ offset = convert_offset_index(d, GICD_ICFGR, &index);
+
+@@ -1718,6 +1759,43 @@ static bool gic_enable_quirk_hip06_07(void *data)
+ return false;
+ }
+
++#define T241_CHIPN_MASK GENMASK_ULL(45, 44)
++#define T241_CHIP_GICDA_OFFSET 0x1580000
++#define SMCCC_SOC_ID_T241 0x036b0241
++
++static bool gic_enable_quirk_nvidia_t241(void *data)
++{
++ s32 soc_id = arm_smccc_get_soc_id_version();
++ unsigned long chip_bmask = 0;
++ phys_addr_t phys;
++ u32 i;
++
++ /* Check JEP106 code for NVIDIA T241 chip (036b:0241) */
++ if ((soc_id < 0) || (soc_id != SMCCC_SOC_ID_T241))
++ return false;
++
++ /* Find the chips based on GICR regions PHYS addr */
++ for (i = 0; i < gic_data.nr_redist_regions; i++) {
++ chip_bmask |= BIT(FIELD_GET(T241_CHIPN_MASK,
++ (u64)gic_data.redist_regions[i].phys_base));
++ }
++
++ if (hweight32(chip_bmask) < 3)
++ return false;
++
++ /* Setup GICD alias regions */
++ for (i = 0; i < ARRAY_SIZE(t241_dist_base_alias); i++) {
++ if (chip_bmask & BIT(i)) {
++ phys = gic_data.dist_phys_base + T241_CHIP_GICDA_OFFSET;
++ phys |= FIELD_PREP(T241_CHIPN_MASK, i);
++ t241_dist_base_alias[i] = ioremap(phys, SZ_64K);
++ WARN_ON_ONCE(!t241_dist_base_alias[i]);
++ }
++ }
++ static_branch_enable(&gic_nvidia_t241_erratum);
++ return true;
++}
++
+ static const struct gic_quirk gic_quirks[] = {
+ {
+ .desc = "GICv3: Qualcomm MSM8996 broken firmware",
+@@ -1749,6 +1827,12 @@ static const struct gic_quirk gic_quirks[] = {
+ .mask = 0xe8f00fff,
+ .init = gic_enable_quirk_cavium_38539,
+ },
++ {
++ .desc = "GICv3: NVIDIA erratum T241-FABRIC-4",
++ .iidr = 0x0402043b,
++ .mask = 0xffffffff,
++ .init = gic_enable_quirk_nvidia_t241,
++ },
+ {
+ }
+ };
+@@ -1816,7 +1900,8 @@ static void gic_enable_nmi_support(void)
+ gic_chip.flags |= IRQCHIP_SUPPORTS_NMI;
+ }
+
+-static int __init gic_init_bases(void __iomem *dist_base,
++static int __init gic_init_bases(phys_addr_t dist_phys_base,
++ void __iomem *dist_base,
+ struct redist_region *rdist_regs,
+ u32 nr_redist_regions,
+ u64 redist_stride,
+@@ -1832,6 +1917,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
+ pr_info("GIC: Using split EOI/Deactivate mode\n");
+
+ gic_data.fwnode = handle;
++ gic_data.dist_phys_base = dist_phys_base;
+ gic_data.dist_base = dist_base;
+ gic_data.redist_regions = rdist_regs;
+ gic_data.nr_redist_regions = nr_redist_regions;
+@@ -1859,10 +1945,13 @@ static int __init gic_init_bases(void __iomem *dist_base,
+ gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops,
+ &gic_data);
+ gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist));
+- gic_data.rdists.has_rvpeid = true;
+- gic_data.rdists.has_vlpis = true;
+- gic_data.rdists.has_direct_lpi = true;
+- gic_data.rdists.has_vpend_valid_dirty = true;
++ if (!static_branch_unlikely(&gic_nvidia_t241_erratum)) {
++ /* Disable GICv4.x features for the erratum T241-FABRIC-4 */
++ gic_data.rdists.has_rvpeid = true;
++ gic_data.rdists.has_vlpis = true;
++ gic_data.rdists.has_direct_lpi = true;
++ gic_data.rdists.has_vpend_valid_dirty = true;
++ }
+
+ if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) {
+ err = -ENOMEM;
+@@ -2068,6 +2157,7 @@ static void __iomem *gic_of_iomap(struct device_node *node, int idx,
+
+ static int __init gic_of_init(struct device_node *node, struct device_node *parent)
+ {
++ phys_addr_t dist_phys_base;
+ void __iomem *dist_base;
+ struct redist_region *rdist_regs;
+ struct resource res;
+@@ -2081,6 +2171,8 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
+ return PTR_ERR(dist_base);
+ }
+
++ dist_phys_base = res.start;
++
+ err = gic_validate_dist_version(dist_base);
+ if (err) {
+ pr_err("%pOF: no distributor detected, giving up\n", node);
+@@ -2112,8 +2204,8 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
+
+ gic_enable_of_quirks(node, gic_quirks, &gic_data);
+
+- err = gic_init_bases(dist_base, rdist_regs, nr_redist_regions,
+- redist_stride, &node->fwnode);
++ err = gic_init_bases(dist_phys_base, dist_base, rdist_regs,
++ nr_redist_regions, redist_stride, &node->fwnode);
+ if (err)
+ goto out_unmap_rdist;
+
+@@ -2429,8 +2521,9 @@ gic_acpi_init(union acpi_subtable_headers *header, const unsigned long end)
+ goto out_redist_unmap;
+ }
+
+- err = gic_init_bases(acpi_data.dist_base, acpi_data.redist_regs,
+- acpi_data.nr_redist_regions, 0, gsi_domain_handle);
++ err = gic_init_bases(dist->base_address, acpi_data.dist_base,
++ acpi_data.redist_regs, acpi_data.nr_redist_regions,
++ 0, gsi_domain_handle);
+ if (err)
+ goto out_fwhandle_free;
+
+diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
+index 220c8c60e021a..f196c19f8e55c 100644
+--- a/include/linux/arm-smccc.h
++++ b/include/linux/arm-smccc.h
+@@ -226,6 +226,24 @@ void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);
+
+ extern u64 smccc_has_sve_hint;
+
++/**
++ * arm_smccc_get_soc_id_version()
++ *
++ * Returns the SOC ID version.
++ *
++ * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
++ */
++s32 arm_smccc_get_soc_id_version(void);
++
++/**
++ * arm_smccc_get_soc_id_revision()
++ *
++ * Returns the SOC ID revision.
++ *
++ * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
++ */
++s32 arm_smccc_get_soc_id_revision(void);
++
+ /**
+ * struct arm_smccc_res - Result from SMC/HVC call
+ * @a0-a3 result values from registers 0 to 3
+--
+2.39.2
+
--- /dev/null
+From 75af28f110a4224e38da6f062f00fa56dad15151 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Feb 2023 07:51:02 +0200
+Subject: lib: cpu_rmap: Avoid use after free on rmap->obj array entries
+
+From: Eli Cohen <elic@nvidia.com>
+
+[ Upstream commit 4e0473f1060aa49621d40a113afde24818101d37 ]
+
+When calling irq_set_affinity_notifier() with NULL at the notify
+argument, it will cause freeing of the glue pointer in the
+corresponding array entry but will leave the pointer in the array. A
+subsequent call to free_irq_cpu_rmap() will try to free this entry again
+leading to possible use after free.
+
+Fix that by setting NULL to the array entry and checking that we have
+non-zero at the array entry when iterating over the array in
+free_irq_cpu_rmap().
+
+The current code does not suffer from this since there are no cases
+where irq_set_affinity_notifier(irq, NULL) (note the NULL passed for the
+notify arg) is called, followed by a call to free_irq_cpu_rmap() so we
+don't hit and issue. Subsequent patches in this series excersize this
+flow, hence the required fix.
+
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Eli Cohen <elic@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/cpu_rmap.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/lib/cpu_rmap.c b/lib/cpu_rmap.c
+index f08d9c56f712e..e77f12bb3c774 100644
+--- a/lib/cpu_rmap.c
++++ b/lib/cpu_rmap.c
+@@ -232,7 +232,8 @@ void free_irq_cpu_rmap(struct cpu_rmap *rmap)
+
+ for (index = 0; index < rmap->used; index++) {
+ glue = rmap->obj[index];
+- irq_set_affinity_notifier(glue->notify.irq, NULL);
++ if (glue)
++ irq_set_affinity_notifier(glue->notify.irq, NULL);
+ }
+
+ cpu_rmap_put(rmap);
+@@ -268,6 +269,7 @@ static void irq_cpu_rmap_release(struct kref *ref)
+ container_of(ref, struct irq_glue, notify.kref);
+
+ cpu_rmap_put(glue->rmap);
++ glue->rmap->obj[glue->index] = NULL;
+ kfree(glue);
+ }
+
+@@ -297,6 +299,7 @@ int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq)
+ rc = irq_set_affinity_notifier(irq, &glue->notify);
+ if (rc) {
+ cpu_rmap_put(glue->rmap);
++ rmap->obj[glue->index] = NULL;
+ kfree(glue);
+ }
+ return rc;
+--
+2.39.2
+
--- /dev/null
+From 154241050b2a4970960ccff701d7d4d4bd432a9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Apr 2023 10:24:08 -0700
+Subject: lkdtm/stackleak: Fix noinstr violation
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit f571da059f86fd9d432aea32c9c7e5aaa53245d8 ]
+
+Fixes the following warning:
+
+ vmlinux.o: warning: objtool: check_stackleak_irqoff+0x2b6: call to _printk() leaves .noinstr.text section
+
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/ee5209f53aa0a62aea58be18f2b78b17606779a6.1681320026.git.jpoimboe@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/lkdtm/stackleak.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/misc/lkdtm/stackleak.c b/drivers/misc/lkdtm/stackleak.c
+index 025b133297a6b..f1d0221609138 100644
+--- a/drivers/misc/lkdtm/stackleak.c
++++ b/drivers/misc/lkdtm/stackleak.c
+@@ -43,12 +43,14 @@ static void noinstr check_stackleak_irqoff(void)
+ * STACK_END_MAGIC, and in either casee something is seriously wrong.
+ */
+ if (current_sp < task_stack_low || current_sp >= task_stack_high) {
++ instrumentation_begin();
+ pr_err("FAIL: current_stack_pointer (0x%lx) outside of task stack bounds [0x%lx..0x%lx]\n",
+ current_sp, task_stack_low, task_stack_high - 1);
+ test_failed = true;
+ goto out;
+ }
+ if (lowest_sp < task_stack_low || lowest_sp >= task_stack_high) {
++ instrumentation_begin();
+ pr_err("FAIL: current->lowest_stack (0x%lx) outside of task stack bounds [0x%lx..0x%lx]\n",
+ lowest_sp, task_stack_low, task_stack_high - 1);
+ test_failed = true;
+@@ -86,11 +88,14 @@ static void noinstr check_stackleak_irqoff(void)
+ if (*(unsigned long *)poison_low == STACKLEAK_POISON)
+ continue;
+
++ instrumentation_begin();
+ pr_err("FAIL: non-poison value %lu bytes below poison boundary: 0x%lx\n",
+ poison_high - poison_low, *(unsigned long *)poison_low);
+ test_failed = true;
++ goto out;
+ }
+
++ instrumentation_begin();
+ pr_info("stackleak stack usage:\n"
+ " high offset: %lu bytes\n"
+ " current: %lu bytes\n"
+@@ -113,6 +118,7 @@ static void noinstr check_stackleak_irqoff(void)
+ } else {
+ pr_info("OK: the rest of the thread stack is properly erased\n");
+ }
++ instrumentation_end();
+ }
+
+ static void lkdtm_STACKLEAK_ERASING(void)
+--
+2.39.2
+
--- /dev/null
+From be8b58ebc04b87f9c7d8bd5a22753667b5d43d2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Apr 2023 10:33:28 +0200
+Subject: mcb-pci: Reallocate memory region to avoid memory overlapping
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: RodrÃguez Barbarin, José Javier <JoseJavier.Rodriguez@duagon.com>
+
+[ Upstream commit 9be24faadd085c284890c3afcec7a0184642315a ]
+
+mcb-pci requests a fixed-size memory region to parse the chameleon
+table, however, if the chameleon table is smaller that the allocated
+region, it could overlap with the IP Cores' memory regions.
+
+After parsing the chameleon table, drop/reallocate the memory region
+with the actual chameleon table size.
+
+Co-developed-by: Jorge Sanjuan Garcia <jorge.sanjuangarcia@duagon.com>
+Signed-off-by: Jorge Sanjuan Garcia <jorge.sanjuangarcia@duagon.com>
+Signed-off-by: Javier Rodriguez <josejavier.rodriguez@duagon.com>
+Signed-off-by: Johannes Thumshirn <jth@kernel.org>
+Link: https://lore.kernel.org/r/20230411083329.4506-3-jth@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mcb/mcb-pci.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mcb/mcb-pci.c b/drivers/mcb/mcb-pci.c
+index dc88232d9af83..53d9202ff9a7c 100644
+--- a/drivers/mcb/mcb-pci.c
++++ b/drivers/mcb/mcb-pci.c
+@@ -31,7 +31,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ {
+ struct resource *res;
+ struct priv *priv;
+- int ret;
++ int ret, table_size;
+ unsigned long flags;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(struct priv), GFP_KERNEL);
+@@ -90,7 +90,30 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ if (ret < 0)
+ goto out_mcb_bus;
+
+- dev_dbg(&pdev->dev, "Found %d cells\n", ret);
++ table_size = ret;
++
++ if (table_size < CHAM_HEADER_SIZE) {
++ /* Release the previous resources */
++ devm_iounmap(&pdev->dev, priv->base);
++ devm_release_mem_region(&pdev->dev, priv->mapbase, CHAM_HEADER_SIZE);
++
++ /* Then, allocate it again with the actual chameleon table size */
++ res = devm_request_mem_region(&pdev->dev, priv->mapbase,
++ table_size,
++ KBUILD_MODNAME);
++ if (!res) {
++ dev_err(&pdev->dev, "Failed to request PCI memory\n");
++ ret = -EBUSY;
++ goto out_mcb_bus;
++ }
++
++ priv->base = devm_ioremap(&pdev->dev, priv->mapbase, table_size);
++ if (!priv->base) {
++ dev_err(&pdev->dev, "Cannot ioremap\n");
++ ret = -ENOMEM;
++ goto out_mcb_bus;
++ }
++ }
+
+ mcb_bus_add_devices(priv->bus);
+
+--
+2.39.2
+
--- /dev/null
+From 29e70793dd6f644a98ed92559c516ba37e109454 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Mar 2023 15:38:51 +0800
+Subject: md: fix soft lockup in status_resync
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 6efddf1e32e2a264694766ca485a4f5e04ee82a7 ]
+
+status_resync() will calculate 'curr_resync - recovery_active' to show
+user a progress bar like following:
+
+[============>........] resync = 61.4%
+
+'curr_resync' and 'recovery_active' is updated in md_do_sync(), and
+status_resync() can read them concurrently, hence it's possible that
+'curr_resync - recovery_active' can overflow to a huge number. In this
+case status_resync() will be stuck in the loop to print a large amount
+of '=', which will end up soft lockup.
+
+Fix the problem by setting 'resync' to MD_RESYNC_ACTIVE in this case,
+this way resync in progress will be reported to user.
+
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20230310073855.1337560-3-yukuai1@huaweicloud.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index d5c362b1602b6..bb73a541bb193 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -8028,16 +8028,16 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev)
+ } else if (resync > max_sectors) {
+ resync = max_sectors;
+ } else {
+- resync -= atomic_read(&mddev->recovery_active);
+- if (resync < MD_RESYNC_ACTIVE) {
+- /*
+- * Resync has started, but the subtraction has
+- * yielded one of the special values. Force it
+- * to active to ensure the status reports an
+- * active resync.
+- */
++ res = atomic_read(&mddev->recovery_active);
++ /*
++ * Resync has started, but the subtraction has overflowed or
++ * yielded one of the special values. Force it to active to
++ * ensure the status reports an active resync.
++ */
++ if (resync < res || resync - res < MD_RESYNC_ACTIVE)
+ resync = MD_RESYNC_ACTIVE;
+- }
++ else
++ resync -= res;
+ }
+
+ if (resync == MD_RESYNC_NONE) {
+--
+2.39.2
+
--- /dev/null
+From 00f530b7687c093ed8d695b2b8281720b72e3ecf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Mar 2023 13:39:05 +0100
+Subject: media: cx23885: Fix a null-ptr-deref bug in buffer_prepare() and
+ buffer_finish()
+
+From: harperchen <harperchen1110@gmail.com>
+
+[ Upstream commit 47e8b73bc35d7c54642f78e498697692f6358996 ]
+
+When the driver calls cx23885_risc_buffer() to prepare the buffer, the
+function call dma_alloc_coherent may fail, resulting in a empty buffer
+risc->cpu. Later when we free the buffer or access the buffer, null ptr
+deref is triggered.
+
+This bug is similar to the following one:
+https://git.linuxtv.org/media_stage.git/commit/?id=2b064d91440b33fba5b452f2d1b31f13ae911d71.
+
+We believe the bug can be also dynamically triggered from user side.
+Similarly, we fix this by checking the return value of cx23885_risc_buffer()
+and the value of risc->cpu before buffer free.
+
+Signed-off-by: harperchen <harperchen1110@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/cx23885/cx23885-core.c | 4 +++-
+ drivers/media/pci/cx23885/cx23885-video.c | 13 +++++++------
+ 2 files changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
+index 9232a966bcabb..2ce2914576cf2 100644
+--- a/drivers/media/pci/cx23885/cx23885-core.c
++++ b/drivers/media/pci/cx23885/cx23885-core.c
+@@ -1325,7 +1325,9 @@ void cx23885_free_buffer(struct cx23885_dev *dev, struct cx23885_buffer *buf)
+ {
+ struct cx23885_riscmem *risc = &buf->risc;
+
+- dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu, risc->dma);
++ if (risc->cpu)
++ dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu, risc->dma);
++ memset(risc, 0, sizeof(*risc));
+ }
+
+ static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
+diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
+index 3d03f5e95786a..671fc0588e431 100644
+--- a/drivers/media/pci/cx23885/cx23885-video.c
++++ b/drivers/media/pci/cx23885/cx23885-video.c
+@@ -342,6 +342,7 @@ static int queue_setup(struct vb2_queue *q,
+
+ static int buffer_prepare(struct vb2_buffer *vb)
+ {
++ int ret;
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+ struct cx23885_buffer *buf =
+@@ -358,12 +359,12 @@ static int buffer_prepare(struct vb2_buffer *vb)
+
+ switch (dev->field) {
+ case V4L2_FIELD_TOP:
+- cx23885_risc_buffer(dev->pci, &buf->risc,
++ ret = cx23885_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl, 0, UNSET,
+ buf->bpl, 0, dev->height);
+ break;
+ case V4L2_FIELD_BOTTOM:
+- cx23885_risc_buffer(dev->pci, &buf->risc,
++ ret = cx23885_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl, UNSET, 0,
+ buf->bpl, 0, dev->height);
+ break;
+@@ -391,21 +392,21 @@ static int buffer_prepare(struct vb2_buffer *vb)
+ line0_offset = 0;
+ line1_offset = buf->bpl;
+ }
+- cx23885_risc_buffer(dev->pci, &buf->risc,
++ ret = cx23885_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl, line0_offset,
+ line1_offset,
+ buf->bpl, buf->bpl,
+ dev->height >> 1);
+ break;
+ case V4L2_FIELD_SEQ_TB:
+- cx23885_risc_buffer(dev->pci, &buf->risc,
++ ret = cx23885_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl,
+ 0, buf->bpl * (dev->height >> 1),
+ buf->bpl, 0,
+ dev->height >> 1);
+ break;
+ case V4L2_FIELD_SEQ_BT:
+- cx23885_risc_buffer(dev->pci, &buf->risc,
++ ret = cx23885_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl,
+ buf->bpl * (dev->height >> 1), 0,
+ buf->bpl, 0,
+@@ -418,7 +419,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
+ buf, buf->vb.vb2_buf.index,
+ dev->width, dev->height, dev->fmt->depth, dev->fmt->fourcc,
+ (unsigned long)buf->risc.dma);
+- return 0;
++ return ret;
+ }
+
+ static void buffer_finish(struct vb2_buffer *vb)
+--
+2.39.2
+
--- /dev/null
+From 9367186965c27c9bcd97badfd8746a8e65a3ae83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Mar 2023 09:05:13 +0100
+Subject: media: mediatek: vcodec: Fix potential array out-of-bounds in decoder
+ queue_setup
+
+From: Wei Chen <harperchen1110@gmail.com>
+
+[ Upstream commit 8fbcf730cb89c3647f3365226fe7014118fa93c7 ]
+
+variable *nplanes is provided by user via system call argument. The
+possible value of q_data->fmt->num_planes is 1-3, while the value
+of *nplanes can be 1-8. The array access by index i can cause array
+out-of-bounds.
+
+Fix this bug by checking *nplanes against the array size.
+
+Signed-off-by: Wei Chen <harperchen1110@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
+index c99705681a03e..93fcea821001f 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
+@@ -735,6 +735,13 @@ int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
+ }
+
+ if (*nplanes) {
++ if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
++ if (*nplanes != q_data->fmt->num_planes)
++ return -EINVAL;
++ } else {
++ if (*nplanes != 1)
++ return -EINVAL;
++ }
+ for (i = 0; i < *nplanes; i++) {
+ if (sizes[i] < q_data->sizeimage[i])
+ return -EINVAL;
+--
+2.39.2
+
--- /dev/null
+From 917d97b30282f2085916f223454708b14a3d3d32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Mar 2023 16:30:11 +0100
+Subject: media: pci: tw68: Fix null-ptr-deref bug in buf prepare and finish
+
+From: harperchen <harperchen1110@gmail.com>
+
+[ Upstream commit 1634b7adcc5bef645b3666fdd564e5952a9e24e0 ]
+
+When the driver calls tw68_risc_buffer() to prepare the buffer, the
+function call dma_alloc_coherent may fail, resulting in a empty buffer
+buf->cpu. Later when we free the buffer or access the buffer, null ptr
+deref is triggered.
+
+This bug is similar to the following one:
+https://git.linuxtv.org/media_stage.git/commit/?id=2b064d91440b33fba5b452f2d1b31f13ae911d71.
+
+We believe the bug can be also dynamically triggered from user side.
+Similarly, we fix this by checking the return value of tw68_risc_buffer()
+and the value of buf->cpu before buffer free.
+
+Signed-off-by: harperchen <harperchen1110@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/tw68/tw68-video.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/pci/tw68/tw68-video.c b/drivers/media/pci/tw68/tw68-video.c
+index 0cbc5b038073b..773a18702d369 100644
+--- a/drivers/media/pci/tw68/tw68-video.c
++++ b/drivers/media/pci/tw68/tw68-video.c
+@@ -437,6 +437,7 @@ static void tw68_buf_queue(struct vb2_buffer *vb)
+ */
+ static int tw68_buf_prepare(struct vb2_buffer *vb)
+ {
++ int ret;
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct vb2_queue *vq = vb->vb2_queue;
+ struct tw68_dev *dev = vb2_get_drv_priv(vq);
+@@ -452,30 +453,30 @@ static int tw68_buf_prepare(struct vb2_buffer *vb)
+ bpl = (dev->width * dev->fmt->depth) >> 3;
+ switch (dev->field) {
+ case V4L2_FIELD_TOP:
+- tw68_risc_buffer(dev->pci, buf, dma->sgl,
++ ret = tw68_risc_buffer(dev->pci, buf, dma->sgl,
+ 0, UNSET, bpl, 0, dev->height);
+ break;
+ case V4L2_FIELD_BOTTOM:
+- tw68_risc_buffer(dev->pci, buf, dma->sgl,
++ ret = tw68_risc_buffer(dev->pci, buf, dma->sgl,
+ UNSET, 0, bpl, 0, dev->height);
+ break;
+ case V4L2_FIELD_SEQ_TB:
+- tw68_risc_buffer(dev->pci, buf, dma->sgl,
++ ret = tw68_risc_buffer(dev->pci, buf, dma->sgl,
+ 0, bpl * (dev->height >> 1),
+ bpl, 0, dev->height >> 1);
+ break;
+ case V4L2_FIELD_SEQ_BT:
+- tw68_risc_buffer(dev->pci, buf, dma->sgl,
++ ret = tw68_risc_buffer(dev->pci, buf, dma->sgl,
+ bpl * (dev->height >> 1), 0,
+ bpl, 0, dev->height >> 1);
+ break;
+ case V4L2_FIELD_INTERLACED:
+ default:
+- tw68_risc_buffer(dev->pci, buf, dma->sgl,
++ ret = tw68_risc_buffer(dev->pci, buf, dma->sgl,
+ 0, bpl, bpl, bpl, dev->height >> 1);
+ break;
+ }
+- return 0;
++ return ret;
+ }
+
+ static void tw68_buf_finish(struct vb2_buffer *vb)
+@@ -485,7 +486,8 @@ static void tw68_buf_finish(struct vb2_buffer *vb)
+ struct tw68_dev *dev = vb2_get_drv_priv(vq);
+ struct tw68_buf *buf = container_of(vbuf, struct tw68_buf, vb);
+
+- dma_free_coherent(&dev->pci->dev, buf->size, buf->cpu, buf->dma);
++ if (buf->cpu)
++ dma_free_coherent(&dev->pci->dev, buf->size, buf->cpu, buf->dma);
+ }
+
+ static int tw68_start_streaming(struct vb2_queue *q, unsigned int count)
+--
+2.39.2
+
--- /dev/null
+From 2a62a4037175ec7cfd0854747ec9c95c492faf22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 17:18:39 +0200
+Subject: media: Prefer designated initializers over memset for subdev pad ops
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+[ Upstream commit e3a69496a1cde364c74a600d7a370179b58aed29 ]
+
+Structures passed to subdev pad operations are all zero-initialized, but
+not always with the same kind of code constructs. While most drivers
+used designated initializers, which zero all the fields that are not
+specified, when declaring variables, some use memset(). Those two
+methods lead to the same end result, and, depending on compiler
+optimizations, may even be completely equivalent, but they're not
+consistent.
+
+Improve coding style consistency by using designated initializers
+instead of calling memset(). Where applicable, also move the variables
+to inner scopes of for loops to ensure correct initialization in all
+iterations.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Lad Prabhakar <prabhakar.csengg@gmail.com> # For am437x
+Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/renesas/vsp1/vsp1_drm.c | 18 +++++++++---------
+ .../media/platform/renesas/vsp1/vsp1_entity.c | 11 +++++------
+ .../platform/samsung/exynos4-is/fimc-capture.c | 7 ++++---
+ drivers/media/platform/ti/am437x/am437x-vpfe.c | 15 ++++++++-------
+ drivers/media/platform/ti/cal/cal-video.c | 8 ++++----
+ drivers/media/usb/dvb-usb/cxusb-analog.c | 14 +++++++-------
+ drivers/staging/media/imx/imx-media-capture.c | 12 ++++++------
+ drivers/staging/media/imx/imx-media-utils.c | 8 ++++----
+ drivers/staging/media/omap4iss/iss_video.c | 6 +++---
+ 9 files changed, 50 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/media/platform/renesas/vsp1/vsp1_drm.c b/drivers/media/platform/renesas/vsp1/vsp1_drm.c
+index c6f25200982c8..7fe375b6322cd 100644
+--- a/drivers/media/platform/renesas/vsp1/vsp1_drm.c
++++ b/drivers/media/platform/renesas/vsp1/vsp1_drm.c
+@@ -66,7 +66,9 @@ static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
+ struct vsp1_entity *prev, unsigned int prev_pad,
+ struct vsp1_entity *next, unsigned int next_pad)
+ {
+- struct v4l2_subdev_format format;
++ struct v4l2_subdev_format format = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
+ int ret;
+
+ if (!uif) {
+@@ -82,8 +84,6 @@ static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
+ prev->sink = uif;
+ prev->sink_pad = UIF_PAD_SINK;
+
+- memset(&format, 0, sizeof(format));
+- format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ format.pad = prev_pad;
+
+ ret = v4l2_subdev_call(&prev->subdev, pad, get_fmt, NULL, &format);
+@@ -118,8 +118,12 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
+ struct vsp1_entity *uif,
+ unsigned int brx_input)
+ {
+- struct v4l2_subdev_selection sel;
+- struct v4l2_subdev_format format;
++ struct v4l2_subdev_selection sel = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_subdev_format format = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
+ const struct v4l2_rect *crop;
+ int ret;
+
+@@ -129,8 +133,6 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
+ */
+ crop = &vsp1->drm->inputs[rpf->entity.index].crop;
+
+- memset(&format, 0, sizeof(format));
+- format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ format.pad = RWPF_PAD_SINK;
+ format.format.width = crop->width + crop->left;
+ format.format.height = crop->height + crop->top;
+@@ -147,8 +149,6 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
+ __func__, format.format.width, format.format.height,
+ format.format.code, rpf->entity.index);
+
+- memset(&sel, 0, sizeof(sel));
+- sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ sel.pad = RWPF_PAD_SINK;
+ sel.target = V4L2_SEL_TGT_CROP;
+ sel.r = *crop;
+diff --git a/drivers/media/platform/renesas/vsp1/vsp1_entity.c b/drivers/media/platform/renesas/vsp1/vsp1_entity.c
+index 4c3bd2b1ca287..c31f05a80bb56 100644
+--- a/drivers/media/platform/renesas/vsp1/vsp1_entity.c
++++ b/drivers/media/platform/renesas/vsp1/vsp1_entity.c
+@@ -184,15 +184,14 @@ vsp1_entity_get_pad_selection(struct vsp1_entity *entity,
+ int vsp1_entity_init_cfg(struct v4l2_subdev *subdev,
+ struct v4l2_subdev_state *sd_state)
+ {
+- struct v4l2_subdev_format format;
+ unsigned int pad;
+
+ for (pad = 0; pad < subdev->entity.num_pads - 1; ++pad) {
+- memset(&format, 0, sizeof(format));
+-
+- format.pad = pad;
+- format.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY
+- : V4L2_SUBDEV_FORMAT_ACTIVE;
++ struct v4l2_subdev_format format = {
++ .pad = pad,
++ .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY
++ : V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
+
+ v4l2_subdev_call(subdev, pad, set_fmt, sd_state, &format);
+ }
+diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c
+index e3b95a2b7e040..beaee54ee73bf 100644
+--- a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c
++++ b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c
+@@ -763,7 +763,10 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
+ struct fimc_dev *fimc = ctx->fimc_dev;
+ struct fimc_pipeline *p = to_fimc_pipeline(fimc->vid_cap.ve.pipe);
+ struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR];
+- struct v4l2_subdev_format sfmt;
++ struct v4l2_subdev_format sfmt = {
++ .which = set ? V4L2_SUBDEV_FORMAT_ACTIVE
++ : V4L2_SUBDEV_FORMAT_TRY,
++ };
+ struct v4l2_mbus_framefmt *mf = &sfmt.format;
+ struct media_entity *me;
+ struct fimc_fmt *ffmt;
+@@ -774,9 +777,7 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
+ if (WARN_ON(!sd || !tfmt))
+ return -EINVAL;
+
+- memset(&sfmt, 0, sizeof(sfmt));
+ sfmt.format = *tfmt;
+- sfmt.which = set ? V4L2_SUBDEV_FORMAT_ACTIVE : V4L2_SUBDEV_FORMAT_TRY;
+
+ me = fimc_pipeline_get_head(&sd->entity);
+
+diff --git a/drivers/media/platform/ti/am437x/am437x-vpfe.c b/drivers/media/platform/ti/am437x/am437x-vpfe.c
+index 2dfae9bc0bba8..dffac89cbd210 100644
+--- a/drivers/media/platform/ti/am437x/am437x-vpfe.c
++++ b/drivers/media/platform/ti/am437x/am437x-vpfe.c
+@@ -1499,7 +1499,9 @@ static int vpfe_enum_size(struct file *file, void *priv,
+ struct v4l2_frmsizeenum *fsize)
+ {
+ struct vpfe_device *vpfe = video_drvdata(file);
+- struct v4l2_subdev_frame_size_enum fse;
++ struct v4l2_subdev_frame_size_enum fse = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
+ struct v4l2_subdev *sd = vpfe->current_subdev->sd;
+ struct vpfe_fmt *fmt;
+ int ret;
+@@ -1514,11 +1516,9 @@ static int vpfe_enum_size(struct file *file, void *priv,
+
+ memset(fsize->reserved, 0x0, sizeof(fsize->reserved));
+
+- memset(&fse, 0x0, sizeof(fse));
+ fse.index = fsize->index;
+ fse.pad = 0;
+ fse.code = fmt->code;
+- fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ ret = v4l2_subdev_call(sd, pad, enum_frame_size, NULL, &fse);
+ if (ret)
+ return ret;
+@@ -2146,7 +2146,6 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,
+ {
+ struct vpfe_device *vpfe = container_of(notifier->v4l2_dev,
+ struct vpfe_device, v4l2_dev);
+- struct v4l2_subdev_mbus_code_enum mbus_code;
+ struct vpfe_subdev_info *sdinfo;
+ struct vpfe_fmt *fmt;
+ int ret = 0;
+@@ -2173,9 +2172,11 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,
+
+ vpfe->num_active_fmt = 0;
+ for (j = 0, i = 0; (ret != -EINVAL); ++j) {
+- memset(&mbus_code, 0, sizeof(mbus_code));
+- mbus_code.index = j;
+- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++ struct v4l2_subdev_mbus_code_enum mbus_code = {
++ .index = j,
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++
+ ret = v4l2_subdev_call(subdev, pad, enum_mbus_code,
+ NULL, &mbus_code);
+ if (ret)
+diff --git a/drivers/media/platform/ti/cal/cal-video.c b/drivers/media/platform/ti/cal/cal-video.c
+index 4eade409d5d36..bbfd2719725aa 100644
+--- a/drivers/media/platform/ti/cal/cal-video.c
++++ b/drivers/media/platform/ti/cal/cal-video.c
+@@ -811,7 +811,6 @@ static const struct v4l2_file_operations cal_fops = {
+
+ static int cal_ctx_v4l2_init_formats(struct cal_ctx *ctx)
+ {
+- struct v4l2_subdev_mbus_code_enum mbus_code;
+ struct v4l2_mbus_framefmt mbus_fmt;
+ const struct cal_format_info *fmtinfo;
+ unsigned int i, j, k;
+@@ -826,10 +825,11 @@ static int cal_ctx_v4l2_init_formats(struct cal_ctx *ctx)
+ ctx->num_active_fmt = 0;
+
+ for (j = 0, i = 0; ; ++j) {
++ struct v4l2_subdev_mbus_code_enum mbus_code = {
++ .index = j,
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
+
+- memset(&mbus_code, 0, sizeof(mbus_code));
+- mbus_code.index = j;
+- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ ret = v4l2_subdev_call(ctx->phy->source, pad, enum_mbus_code,
+ NULL, &mbus_code);
+ if (ret == -EINVAL)
+diff --git a/drivers/media/usb/dvb-usb/cxusb-analog.c b/drivers/media/usb/dvb-usb/cxusb-analog.c
+index e93183ddd7975..deba5224cb8df 100644
+--- a/drivers/media/usb/dvb-usb/cxusb-analog.c
++++ b/drivers/media/usb/dvb-usb/cxusb-analog.c
+@@ -1014,7 +1014,10 @@ static int cxusb_medion_try_s_fmt_vid_cap(struct file *file,
+ {
+ struct dvb_usb_device *dvbdev = video_drvdata(file);
+ struct cxusb_medion_dev *cxdev = dvbdev->priv;
+- struct v4l2_subdev_format subfmt;
++ struct v4l2_subdev_format subfmt = {
++ .which = isset ? V4L2_SUBDEV_FORMAT_ACTIVE :
++ V4L2_SUBDEV_FORMAT_TRY,
++ };
+ u32 field;
+ int ret;
+
+@@ -1024,9 +1027,6 @@ static int cxusb_medion_try_s_fmt_vid_cap(struct file *file,
+ field = vb2_start_streaming_called(&cxdev->videoqueue) ?
+ cxdev->field_order : cxusb_medion_field_order(cxdev);
+
+- memset(&subfmt, 0, sizeof(subfmt));
+- subfmt.which = isset ? V4L2_SUBDEV_FORMAT_ACTIVE :
+- V4L2_SUBDEV_FORMAT_TRY;
+ subfmt.format.width = f->fmt.pix.width & ~1;
+ subfmt.format.height = f->fmt.pix.height & ~1;
+ subfmt.format.code = MEDIA_BUS_FMT_FIXED;
+@@ -1464,7 +1464,9 @@ int cxusb_medion_analog_init(struct dvb_usb_device *dvbdev)
+ .buf = tuner_analog_msg_data,
+ .len =
+ sizeof(tuner_analog_msg_data) };
+- struct v4l2_subdev_format subfmt;
++ struct v4l2_subdev_format subfmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
+ int ret;
+
+ /* switch tuner to analog mode so IF demod will become accessible */
+@@ -1507,8 +1509,6 @@ int cxusb_medion_analog_init(struct dvb_usb_device *dvbdev)
+ v4l2_subdev_call(cxdev->tuner, video, s_std, cxdev->norm);
+ v4l2_subdev_call(cxdev->cx25840, video, s_std, cxdev->norm);
+
+- memset(&subfmt, 0, sizeof(subfmt));
+- subfmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ subfmt.format.width = cxdev->width;
+ subfmt.format.height = cxdev->height;
+ subfmt.format.code = MEDIA_BUS_FMT_FIXED;
+diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c
+index 93ba092360105..5cc67786b9169 100644
+--- a/drivers/staging/media/imx/imx-media-capture.c
++++ b/drivers/staging/media/imx/imx-media-capture.c
+@@ -501,14 +501,14 @@ static int capture_legacy_g_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *a)
+ {
+ struct capture_priv *priv = video_drvdata(file);
+- struct v4l2_subdev_frame_interval fi;
++ struct v4l2_subdev_frame_interval fi = {
++ .pad = priv->src_sd_pad,
++ };
+ int ret;
+
+ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+- memset(&fi, 0, sizeof(fi));
+- fi.pad = priv->src_sd_pad;
+ ret = v4l2_subdev_call(priv->src_sd, video, g_frame_interval, &fi);
+ if (ret < 0)
+ return ret;
+@@ -523,14 +523,14 @@ static int capture_legacy_s_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *a)
+ {
+ struct capture_priv *priv = video_drvdata(file);
+- struct v4l2_subdev_frame_interval fi;
++ struct v4l2_subdev_frame_interval fi = {
++ .pad = priv->src_sd_pad,
++ };
+ int ret;
+
+ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+- memset(&fi, 0, sizeof(fi));
+- fi.pad = priv->src_sd_pad;
+ fi.interval = a->parm.capture.timeperframe;
+ ret = v4l2_subdev_call(priv->src_sd, video, s_frame_interval, &fi);
+ if (ret < 0)
+diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c
+index 3e7462112649d..4985f21b4023f 100644
+--- a/drivers/staging/media/imx/imx-media-utils.c
++++ b/drivers/staging/media/imx/imx-media-utils.c
+@@ -432,15 +432,15 @@ int imx_media_init_cfg(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state)
+ {
+ struct v4l2_mbus_framefmt *mf_try;
+- struct v4l2_subdev_format format;
+ unsigned int pad;
+ int ret;
+
+ for (pad = 0; pad < sd->entity.num_pads; pad++) {
+- memset(&format, 0, sizeof(format));
++ struct v4l2_subdev_format format = {
++ .pad = pad,
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
+
+- format.pad = pad;
+- format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &format);
+ if (ret)
+ continue;
+diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
+index 60f3d84be8285..8cc8b3ebab11f 100644
+--- a/drivers/staging/media/omap4iss/iss_video.c
++++ b/drivers/staging/media/omap4iss/iss_video.c
+@@ -244,7 +244,9 @@ static int
+ __iss_video_get_format(struct iss_video *video,
+ struct v4l2_mbus_framefmt *format)
+ {
+- struct v4l2_subdev_format fmt;
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
+ struct v4l2_subdev *subdev;
+ u32 pad;
+ int ret;
+@@ -253,9 +255,7 @@ __iss_video_get_format(struct iss_video *video,
+ if (!subdev)
+ return -EINVAL;
+
+- memset(&fmt, 0, sizeof(fmt));
+ fmt.pad = pad;
+- fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+
+ mutex_lock(&video->mutex);
+ ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
+--
+2.39.2
+
--- /dev/null
+From 700c7572ecefc44bed2a75700d33a3b577233cb1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Mar 2023 14:48:47 +0100
+Subject: media: pvrusb2: VIDEO_PVRUSB2 depends on DVB_CORE to use dvb_*
+ symbols
+
+From: Tom Rix <trix@redhat.com>
+
+[ Upstream commit 1107283b3351bef138cd12dbda1f999891cab7db ]
+
+A rand config causes this link error
+vmlinux.o: In function `pvr2_dvb_create':
+(.text+0x8af1d2): undefined reference to `dvb_register_adapter'
+
+The rand config has
+CONFIG_VIDEO_PVRUSB2=y
+CONFIG_VIDEO_DEV=y
+CONFIG_DVB_CORE=m
+
+VIDEO_PVRUSB2 should also depend on DVB_CORE.
+
+Signed-off-by: Tom Rix <trix@redhat.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/pvrusb2/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig
+index f2b64e49c5a20..9501b10b31aa5 100644
+--- a/drivers/media/usb/pvrusb2/Kconfig
++++ b/drivers/media/usb/pvrusb2/Kconfig
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ config VIDEO_PVRUSB2
+ tristate "Hauppauge WinTV-PVR USB2 support"
+- depends on VIDEO_DEV && I2C
++ depends on VIDEO_DEV && I2C && DVB_CORE
+ select VIDEO_TUNER
+ select VIDEO_TVEEPROM
+ select VIDEO_CX2341X
+--
+2.39.2
+
--- /dev/null
+From a25be18a1e5acf0bf7180dd886ca714e4af7766f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Mar 2023 00:43:38 +0800
+Subject: memstick: r592: Fix UAF bug in r592_remove due to race condition
+
+From: Zheng Wang <zyytlz.wz@163.com>
+
+[ Upstream commit 63264422785021704c39b38f65a78ab9e4a186d7 ]
+
+In r592_probe, dev->detect_timer was bound with r592_detect_timer.
+In r592_irq function, the timer function will be invoked by mod_timer.
+
+If we remove the module which will call hantro_release to make cleanup,
+there may be a unfinished work. The possible sequence is as follows,
+which will cause a typical UAF bug.
+
+Fix it by canceling the work before cleanup in r592_remove.
+
+CPU0 CPU1
+
+ |r592_detect_timer
+r592_remove |
+ memstick_free_host|
+ put_device; |
+ kfree(host); |
+ |
+ | queue_work
+ | &host->media_checker //use
+
+Signed-off-by: Zheng Wang <zyytlz.wz@163.com>
+Link: https://lore.kernel.org/r/20230307164338.1246287-1-zyytlz.wz@163.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memstick/host/r592.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c
+index 1d35d147552d4..42bfc46842b82 100644
+--- a/drivers/memstick/host/r592.c
++++ b/drivers/memstick/host/r592.c
+@@ -829,7 +829,7 @@ static void r592_remove(struct pci_dev *pdev)
+ /* Stop the processing thread.
+ That ensures that we won't take any more requests */
+ kthread_stop(dev->io_thread);
+-
++ del_timer_sync(&dev->detect_timer);
+ r592_enable_device(dev, false);
+
+ while (!error && dev->req) {
+--
+2.39.2
+
--- /dev/null
+From 6c39c5213149488e8477b0868b99a60fb4c07e80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Mar 2023 10:43:53 +0800
+Subject: mfd: dln2: Fix memory leak in dln2_probe()
+
+From: Qiang Ning <qning0106@126.com>
+
+[ Upstream commit 96da8f148396329ba769246cb8ceaa35f1ddfc48 ]
+
+When dln2_setup_rx_urbs() in dln2_probe() fails, error out_free forgets
+to call usb_put_dev() to decrease the refcount of dln2->usb_dev.
+
+Fix this by adding usb_put_dev() in the error handling code of
+dln2_probe().
+
+Signed-off-by: Qiang Ning <qning0106@126.com>
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://lore.kernel.org/r/20230330024353.4503-1-qning0106@126.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/dln2.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
+index 6cd0b0c752d6e..c3149729cec2e 100644
+--- a/drivers/mfd/dln2.c
++++ b/drivers/mfd/dln2.c
+@@ -827,6 +827,7 @@ static int dln2_probe(struct usb_interface *interface,
+ dln2_stop_rx_urbs(dln2);
+
+ out_free:
++ usb_put_dev(dln2->usb_dev);
+ dln2_free(dln2);
+
+ return ret;
+--
+2.39.2
+
--- /dev/null
+From 87e917b973ab1f6853fbfdad39f5322dbc083e6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Mar 2023 16:26:18 +0300
+Subject: mfd: intel-lpss: Add Intel Meteor Lake PCH-S LPSS PCI IDs
+
+From: Jarkko Nikula <jarkko.nikula@linux.intel.com>
+
+[ Upstream commit 72d4a1683741ee578da0e265886e6a7f3d42266c ]
+
+Add Intel Meteor Lake PCH-S also called as Meteor Point-S LPSS PCI IDs.
+
+Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
+Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://lore.kernel.org/r/20230330132618.4108665-1-jarkko.nikula@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/intel-lpss-pci.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c
+index dde31c50a6320..699f44ffff0e4 100644
+--- a/drivers/mfd/intel-lpss-pci.c
++++ b/drivers/mfd/intel-lpss-pci.c
+@@ -447,6 +447,21 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
+ { PCI_VDEVICE(INTEL, 0x7e79), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7e7a), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7e7b), (kernel_ulong_t)&bxt_i2c_info },
++ /* MTP-S */
++ { PCI_VDEVICE(INTEL, 0x7f28), (kernel_ulong_t)&bxt_uart_info },
++ { PCI_VDEVICE(INTEL, 0x7f29), (kernel_ulong_t)&bxt_uart_info },
++ { PCI_VDEVICE(INTEL, 0x7f2a), (kernel_ulong_t)&tgl_info },
++ { PCI_VDEVICE(INTEL, 0x7f2b), (kernel_ulong_t)&tgl_info },
++ { PCI_VDEVICE(INTEL, 0x7f4c), (kernel_ulong_t)&bxt_i2c_info },
++ { PCI_VDEVICE(INTEL, 0x7f4d), (kernel_ulong_t)&bxt_i2c_info },
++ { PCI_VDEVICE(INTEL, 0x7f4e), (kernel_ulong_t)&bxt_i2c_info },
++ { PCI_VDEVICE(INTEL, 0x7f4f), (kernel_ulong_t)&bxt_i2c_info },
++ { PCI_VDEVICE(INTEL, 0x7f5c), (kernel_ulong_t)&bxt_uart_info },
++ { PCI_VDEVICE(INTEL, 0x7f5d), (kernel_ulong_t)&bxt_uart_info },
++ { PCI_VDEVICE(INTEL, 0x7f5e), (kernel_ulong_t)&tgl_info },
++ { PCI_VDEVICE(INTEL, 0x7f5f), (kernel_ulong_t)&tgl_info },
++ { PCI_VDEVICE(INTEL, 0x7f7a), (kernel_ulong_t)&bxt_i2c_info },
++ { PCI_VDEVICE(INTEL, 0x7f7b), (kernel_ulong_t)&bxt_i2c_info },
+ /* LKF */
+ { PCI_VDEVICE(INTEL, 0x98a8), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0x98a9), (kernel_ulong_t)&bxt_uart_info },
+--
+2.39.2
+
--- /dev/null
+From 9f9ea98814901f8d88838539254b30cc34087bfe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Mar 2023 10:54:02 +0100
+Subject: mfd: intel_soc_pmic_chtwc: Add Lenovo Yoga Book X90F to
+ intel_cht_wc_models
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit ded99b89d25fd73a1d7bd910378e0339fd9d4c4a ]
+
+The Android Lenovo Yoga Book X90F / X90L uses the same charger / fuelgauge
+setup as the already supported Windows Lenovo Yoga Book X91F/L, add
+a DMI match for this to intel_cht_wc_models with driver_data
+set to INTEL_CHT_WC_LENOVO_YOGABOOK1.
+
+When the quirk for the X91F/L was initially added it was written to
+also apply to the X90F/L but this does not work because the Android
+version of the Yoga Book uses completely different DMI strings.
+Also adjust the X91F/L quirk to reflect that it only applies to
+the X91F/L models.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://lore.kernel.org/r/20230301095402.28582-1-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/intel_soc_pmic_chtwc.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mfd/intel_soc_pmic_chtwc.c b/drivers/mfd/intel_soc_pmic_chtwc.c
+index 9216f0d34206c..a82b7cb661b7b 100644
+--- a/drivers/mfd/intel_soc_pmic_chtwc.c
++++ b/drivers/mfd/intel_soc_pmic_chtwc.c
+@@ -159,11 +159,19 @@ static const struct dmi_system_id cht_wc_model_dmi_ids[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
+ },
+ }, {
+- /* Lenovo Yoga Book X90F / X91F / X91L */
++ /* Lenovo Yoga Book X90F / X90L */
+ .driver_data = (void *)(long)INTEL_CHT_WC_LENOVO_YOGABOOK1,
+ .matches = {
+- /* Non exact match to match all versions */
+- DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"),
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"),
++ },
++ }, {
++ /* Lenovo Yoga Book X91F / X91L */
++ .driver_data = (void *)(long)INTEL_CHT_WC_LENOVO_YOGABOOK1,
++ .matches = {
++ /* Non exact match to match F + L versions */
++ DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"),
+ },
+ },
+ { }
+--
+2.39.2
+
--- /dev/null
+From 10e7183f33b0e2868f0acd9b6e4266d0de07af6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 22:58:05 +0800
+Subject: nbd: fix incomplete validation of ioctl arg
+
+From: Zhong Jinghua <zhongjinghua@huawei.com>
+
+[ Upstream commit 55793ea54d77719a071b1ccc05a05056e3b5e009 ]
+
+We tested and found an alarm caused by nbd_ioctl arg without verification.
+The UBSAN warning calltrace like below:
+
+UBSAN: Undefined behaviour in fs/buffer.c:1709:35
+signed integer overflow:
+-9223372036854775808 - 1 cannot be represented in type 'long long int'
+CPU: 3 PID: 2523 Comm: syz-executor.0 Not tainted 4.19.90 #1
+Hardware name: linux,dummy-virt (DT)
+Call trace:
+ dump_backtrace+0x0/0x3f0 arch/arm64/kernel/time.c:78
+ show_stack+0x28/0x38 arch/arm64/kernel/traps.c:158
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x170/0x1dc lib/dump_stack.c:118
+ ubsan_epilogue+0x18/0xb4 lib/ubsan.c:161
+ handle_overflow+0x188/0x1dc lib/ubsan.c:192
+ __ubsan_handle_sub_overflow+0x34/0x44 lib/ubsan.c:206
+ __block_write_full_page+0x94c/0xa20 fs/buffer.c:1709
+ block_write_full_page+0x1f0/0x280 fs/buffer.c:2934
+ blkdev_writepage+0x34/0x40 fs/block_dev.c:607
+ __writepage+0x68/0xe8 mm/page-writeback.c:2305
+ write_cache_pages+0x44c/0xc70 mm/page-writeback.c:2240
+ generic_writepages+0xdc/0x148 mm/page-writeback.c:2329
+ blkdev_writepages+0x2c/0x38 fs/block_dev.c:2114
+ do_writepages+0xd4/0x250 mm/page-writeback.c:2344
+
+The reason for triggering this warning is __block_write_full_page()
+-> i_size_read(inode) - 1 overflow.
+inode->i_size is assigned in __nbd_ioctl() -> nbd_set_size() -> bytesize.
+We think it is necessary to limit the size of arg to prevent errors.
+
+Moreover, __nbd_ioctl() -> nbd_add_socket(), arg will be cast to int.
+Assuming the value of arg is 0x80000000000000001) (on a 64-bit machine),
+it will become 1 after the coercion, which will return unexpected results.
+
+Fix it by adding checks to prevent passing in too large numbers.
+
+Signed-off-by: Zhong Jinghua <zhongjinghua@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Link: https://lore.kernel.org/r/20230206145805.2645671-1-zhongjinghua@huawei.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/nbd.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index e379ccc63c520..888a6abb50f53 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -325,6 +325,9 @@ static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize,
+ if (blk_validate_block_size(blksize))
+ return -EINVAL;
+
++ if (bytesize < 0)
++ return -EINVAL;
++
+ nbd->config->bytesize = bytesize;
+ nbd->config->blksize_bits = __ffs(blksize);
+
+@@ -1110,6 +1113,9 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
+ struct nbd_sock *nsock;
+ int err;
+
++ /* Arg will be cast to int, check it to avoid overflow */
++ if (arg > INT_MAX)
++ return -EINVAL;
+ sock = nbd_get_socket(nbd, arg, &err);
+ if (!sock)
+ return err;
+--
+2.39.2
+
--- /dev/null
+From 6617843cd6760b93c40529cfef24f9b5119c69d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Mar 2023 10:07:24 -0500
+Subject: net: Catch invalid index in XPS mapping
+
+From: Nick Child <nnac123@linux.ibm.com>
+
+[ Upstream commit 5dd0dfd55baec0742ba8f5625a0dd064aca7db16 ]
+
+When setting the XPS value of a TX queue, warn the user once if the
+index of the queue is greater than the number of allocated TX queues.
+
+Previously, this scenario went uncaught. In the best case, it resulted
+in unnecessary allocations. In the worst case, it resulted in
+out-of-bounds memory references through calls to `netdev_get_tx_queue(
+dev, index)`. Therefore, it is important to inform the user but not
+worth returning an error and risk downing the netdevice.
+
+Signed-off-by: Nick Child <nnac123@linux.ibm.com>
+Reviewed-by: Piotr Raczynski <piotr.raczynski@intel.com>
+Link: https://lore.kernel.org/r/20230321150725.127229-1-nnac123@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 1fb7eef38ebe9..93d430693ca0f 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2549,6 +2549,8 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
+ struct xps_map *map, *new_map;
+ unsigned int nr_ids;
+
++ WARN_ON_ONCE(index >= dev->num_tx_queues);
++
+ if (dev->num_tc) {
+ /* Do not allow XPS on subordinate device directly */
+ num_tc = dev->num_tc;
+--
+2.39.2
+
--- /dev/null
+From faeb5dca9083be5e8e8a5e611b19c0cd3d6c1917 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Mar 2023 16:41:08 -0700
+Subject: net: pasemi: Fix return type of pasemi_mac_start_tx()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit c8384d4a51e7cb0e6587f3143f29099f202c5de1 ]
+
+With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
+indirect call targets are validated against the expected function
+pointer prototype to make sure the call target is valid to help mitigate
+ROP attacks. If they are not identical, there is a failure at run time,
+which manifests as either a kernel panic or thread getting killed. A
+warning in clang aims to catch these at compile time, which reveals:
+
+ drivers/net/ethernet/pasemi/pasemi_mac.c:1665:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
+ .ndo_start_xmit = pasemi_mac_start_tx,
+ ^~~~~~~~~~~~~~~~~~~
+ 1 error generated.
+
+->ndo_start_xmit() in 'struct net_device_ops' expects a return type of
+'netdev_tx_t', not 'int'. Adjust the return type of
+pasemi_mac_start_tx() to match the prototype's to resolve the warning.
+While PowerPC does not currently implement support for kCFI, it could in
+the future, which means this warning becomes a fatal CFI failure at run
+time.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/1750
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Link: https://lore.kernel.org/r/20230319-pasemi-incompatible-pointer-types-strict-v1-1-1b9459d8aef0@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/pasemi/pasemi_mac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c
+index aaab590ef548d..ed7dd0a042355 100644
+--- a/drivers/net/ethernet/pasemi/pasemi_mac.c
++++ b/drivers/net/ethernet/pasemi/pasemi_mac.c
+@@ -1423,7 +1423,7 @@ static void pasemi_mac_queue_csdesc(const struct sk_buff *skb,
+ write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), 2);
+ }
+
+-static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+ struct pasemi_mac * const mac = netdev_priv(dev);
+ struct pasemi_mac_txring * const txring = tx_ring(mac);
+--
+2.39.2
+
--- /dev/null
+From 658954cb932e3c114168f0d0fe04e9152452b9d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Mar 2023 10:07:25 -0500
+Subject: netdev: Enforce index cap in netdev_get_tx_queue
+
+From: Nick Child <nnac123@linux.ibm.com>
+
+[ Upstream commit 1cc6571f562774f1d928dc8b3cff50829b86e970 ]
+
+When requesting a TX queue at a given index, warn on out-of-bounds
+referencing if the index is greater than the allocated number of
+queues.
+
+Specifically, since this function is used heavily in the networking
+stack use DEBUG_NET_WARN_ON_ONCE to avoid executing a new branch on
+every packet.
+
+Signed-off-by: Nick Child <nnac123@linux.ibm.com>
+Link: https://lore.kernel.org/r/20230321150725.127229-2-nnac123@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netdevice.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index b072449b0f1ac..eac51e22a52a8 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -2428,6 +2428,7 @@ static inline
+ struct netdev_queue *netdev_get_tx_queue(const struct net_device *dev,
+ unsigned int index)
+ {
++ DEBUG_NET_WARN_ON_ONCE(index >= dev->num_tx_queues);
+ return &dev->_tx[index];
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 3d6b827f9ad0f56ea2c9a1ab93c4fc683d036fd5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Apr 2023 15:03:39 -0700
+Subject: null_blk: Always check queue mode setting from configfs
+
+From: Chaitanya Kulkarni <kch@nvidia.com>
+
+[ Upstream commit 63f8793ee60513a09f110ea460a6ff2c33811cdb ]
+
+Make sure to check device queue mode in the null_validate_conf() and
+return error for NULL_Q_RQ as we don't allow legacy I/O path, without
+this patch we get OOPs when queue mode is set to 1 from configfs,
+following are repro steps :-
+
+modprobe null_blk nr_devices=0
+mkdir config/nullb/nullb0
+echo 1 > config/nullb/nullb0/memory_backed
+echo 4096 > config/nullb/nullb0/blocksize
+echo 20480 > config/nullb/nullb0/size
+echo 1 > config/nullb/nullb0/queue_mode
+echo 1 > config/nullb/nullb0/power
+
+Entering kdb (current=0xffff88810acdd080, pid 2372) on processor 42 Oops: (null)
+due to oops @ 0xffffffffc041c329
+CPU: 42 PID: 2372 Comm: sh Tainted: G O N 6.3.0-rc5lblk+ #5
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
+RIP: 0010:null_add_dev.part.0+0xd9/0x720 [null_blk]
+Code: 01 00 00 85 d2 0f 85 a1 03 00 00 48 83 bb 08 01 00 00 00 0f 85 f7 03 00 00 80 bb 62 01 00 00 00 48 8b 75 20 0f 85 6d 02 00 00 <48> 89 6e 60 48 8b 75 20 bf 06 00 00 00 e8 f5 37 2c c1 48 8b 75 20
+RSP: 0018:ffffc900052cbde0 EFLAGS: 00010246
+RAX: 0000000000000001 RBX: ffff88811084d800 RCX: 0000000000000001
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff888100042e00
+RBP: ffff8881053d8200 R08: ffffc900052cbd68 R09: ffff888105db2000
+R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000002
+R13: ffff888104765200 R14: ffff88810eec1748 R15: ffff88810eec1740
+FS: 00007fd445fd1740(0000) GS:ffff8897dfc80000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000000000060 CR3: 0000000166a00000 CR4: 0000000000350ee0
+DR0: ffffffff8437a488 DR1: ffffffff8437a489 DR2: ffffffff8437a48a
+DR3: ffffffff8437a48b DR6: 00000000ffff0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ nullb_device_power_store+0xd1/0x120 [null_blk]
+ configfs_write_iter+0xb4/0x120
+ vfs_write+0x2ba/0x3c0
+ ksys_write+0x5f/0xe0
+ do_syscall_64+0x3b/0x90
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+RIP: 0033:0x7fd4460c57a7
+Code: 0d 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 48 89 54 24 18 48 89 74 24
+RSP: 002b:00007ffd3792a4a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
+RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007fd4460c57a7
+RDX: 0000000000000002 RSI: 000055b43c02e4c0 RDI: 0000000000000001
+RBP: 000055b43c02e4c0 R08: 000000000000000a R09: 00007fd44615b4e0
+R10: 00007fd44615b3e0 R11: 0000000000000246 R12: 0000000000000002
+R13: 00007fd446198520 R14: 0000000000000002 R15: 00007fd446198700
+ </TASK>
+
+Signed-off-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Reviewed-by: Nitesh Shetty <nj.shetty@samsung.com>
+Link: https://lore.kernel.org/r/20230416220339.43845-1-kch@nvidia.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/null_blk/main.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
+index af419af9a0f4a..c45d09a9a9421 100644
+--- a/drivers/block/null_blk/main.c
++++ b/drivers/block/null_blk/main.c
+@@ -1945,6 +1945,11 @@ static int null_init_tag_set(struct nullb *nullb, struct blk_mq_tag_set *set)
+
+ static int null_validate_conf(struct nullb_device *dev)
+ {
++ if (dev->queue_mode == NULL_Q_RQ) {
++ pr_err("legacy IO path is no longer available\n");
++ return -EINVAL;
++ }
++
+ dev->blocksize = round_down(dev->blocksize, 512);
+ dev->blocksize = clamp_t(unsigned int, dev->blocksize, 512, 4096);
+
+--
+2.39.2
+
--- /dev/null
+From 25166627c0aec13adae9a315a903991a1978da2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Mar 2023 09:18:07 +0100
+Subject: open: return EINVAL for O_DIRECTORY | O_CREAT
+
+From: Christian Brauner <brauner@kernel.org>
+
+[ Upstream commit 43b450632676fb60e9faeddff285d9fac94a4f58 ]
+
+After a couple of years and multiple LTS releases we received a report
+that the behavior of O_DIRECTORY | O_CREAT changed starting with v5.7.
+
+On kernels prior to v5.7 combinations of O_DIRECTORY, O_CREAT, O_EXCL
+had the following semantics:
+
+(1) open("/tmp/d", O_DIRECTORY | O_CREAT)
+ * d doesn't exist: create regular file
+ * d exists and is a regular file: ENOTDIR
+ * d exists and is a directory: EISDIR
+
+(2) open("/tmp/d", O_DIRECTORY | O_CREAT | O_EXCL)
+ * d doesn't exist: create regular file
+ * d exists and is a regular file: EEXIST
+ * d exists and is a directory: EEXIST
+
+(3) open("/tmp/d", O_DIRECTORY | O_EXCL)
+ * d doesn't exist: ENOENT
+ * d exists and is a regular file: ENOTDIR
+ * d exists and is a directory: open directory
+
+On kernels since to v5.7 combinations of O_DIRECTORY, O_CREAT, O_EXCL
+have the following semantics:
+
+(1) open("/tmp/d", O_DIRECTORY | O_CREAT)
+ * d doesn't exist: ENOTDIR (create regular file)
+ * d exists and is a regular file: ENOTDIR
+ * d exists and is a directory: EISDIR
+
+(2) open("/tmp/d", O_DIRECTORY | O_CREAT | O_EXCL)
+ * d doesn't exist: ENOTDIR (create regular file)
+ * d exists and is a regular file: EEXIST
+ * d exists and is a directory: EEXIST
+
+(3) open("/tmp/d", O_DIRECTORY | O_EXCL)
+ * d doesn't exist: ENOENT
+ * d exists and is a regular file: ENOTDIR
+ * d exists and is a directory: open directory
+
+This is a fairly substantial semantic change that userspace didn't
+notice until Pedro took the time to deliberately figure out corner
+cases. Since no one noticed this breakage we can somewhat safely assume
+that O_DIRECTORY | O_CREAT combinations are likely unused.
+
+The v5.7 breakage is especially weird because while ENOTDIR is returned
+indicating failure a regular file is actually created. This doesn't make
+a lot of sense.
+
+Time was spent finding potential users of this combination. Searching on
+codesearch.debian.net showed that codebases often express semantical
+expectations about O_DIRECTORY | O_CREAT which are completely contrary
+to what our code has done and currently does.
+
+The expectation often is that this particular combination would create
+and open a directory. This suggests users who tried to use that
+combination would stumble upon the counterintuitive behavior no matter
+if pre-v5.7 or post v5.7 and quickly realize neither semantics give them
+what they want. For some examples see the code examples in [1] to [3]
+and the discussion in [4].
+
+There are various ways to address this issue. The lazy/simple option
+would be to restore the pre-v5.7 behavior and to just live with that bug
+forever. But since there's a real chance that the O_DIRECTORY | O_CREAT
+quirk isn't relied upon we should try to get away with murder(ing bad
+semantics) first. If we need to Frankenstein pre-v5.7 behavior later so
+be it.
+
+So let's simply return EINVAL categorically for O_DIRECTORY | O_CREAT
+combinations. In addition to cleaning up the old bug this also opens up
+the possiblity to make that flag combination do something more intuitive
+in the future.
+
+Starting with this commit the following semantics apply:
+
+(1) open("/tmp/d", O_DIRECTORY | O_CREAT)
+ * d doesn't exist: EINVAL
+ * d exists and is a regular file: EINVAL
+ * d exists and is a directory: EINVAL
+
+(2) open("/tmp/d", O_DIRECTORY | O_CREAT | O_EXCL)
+ * d doesn't exist: EINVAL
+ * d exists and is a regular file: EINVAL
+ * d exists and is a directory: EINVAL
+
+(3) open("/tmp/d", O_DIRECTORY | O_EXCL)
+ * d doesn't exist: ENOENT
+ * d exists and is a regular file: ENOTDIR
+ * d exists and is a directory: open directory
+
+One additional note, O_TMPFILE is implemented as:
+
+ #define __O_TMPFILE 020000000
+ #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
+ #define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT)
+
+For older kernels it was important to return an explicit error when
+O_TMPFILE wasn't supported. So O_TMPFILE requires that O_DIRECTORY is
+raised alongside __O_TMPFILE. It also enforced that O_CREAT wasn't
+specified. Since O_DIRECTORY | O_CREAT could be used to create a regular
+allowing that combination together with __O_TMPFILE would've meant that
+false positives were possible, i.e., that a regular file was created
+instead of a O_TMPFILE. This could've been used to trick userspace into
+thinking it operated on a O_TMPFILE when it wasn't.
+
+Now that we block O_DIRECTORY | O_CREAT completely the check for O_CREAT
+in the __O_TMPFILE branch via if ((flags & O_TMPFILE_MASK) != O_TMPFILE)
+can be dropped. Instead we can simply check verify that O_DIRECTORY is
+raised via if (!(flags & O_DIRECTORY)) and explain this in two comments.
+
+As Aleksa pointed out O_PATH is unaffected by this change since it
+always returned EINVAL if O_CREAT was specified - with or without
+O_DIRECTORY.
+
+Link: https://lore.kernel.org/lkml/20230320071442.172228-1-pedro.falcato@gmail.com
+Link: https://sources.debian.org/src/flatpak/1.14.4-1/subprojects/libglnx/glnx-dirfd.c/?hl=324#L324 [1]
+Link: https://sources.debian.org/src/flatpak-builder/1.2.3-1/subprojects/libglnx/glnx-shutil.c/?hl=251#L251 [2]
+Link: https://sources.debian.org/src/ostree/2022.7-2/libglnx/glnx-dirfd.c/?hl=324#L324 [3]
+Link: https://www.openwall.com/lists/oss-security/2014/11/26/14 [4]
+Reported-by: Pedro Falcato <pedro.falcato@gmail.com>
+Cc: Aleksa Sarai <cyphar@cyphar.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/open.c | 18 +++++++++++++-----
+ include/uapi/asm-generic/fcntl.h | 1 -
+ tools/include/uapi/asm-generic/fcntl.h | 1 -
+ 3 files changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/fs/open.c b/fs/open.c
+index 20717ec510c07..9541430ec5b30 100644
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -1158,13 +1158,21 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
+ }
+
+ /*
+- * In order to ensure programs get explicit errors when trying to use
+- * O_TMPFILE on old kernels, O_TMPFILE is implemented such that it
+- * looks like (O_DIRECTORY|O_RDWR & ~O_CREAT) to old kernels. But we
+- * have to require userspace to explicitly set it.
++ * Block bugs where O_DIRECTORY | O_CREAT created regular files.
++ * Note, that blocking O_DIRECTORY | O_CREAT here also protects
++ * O_TMPFILE below which requires O_DIRECTORY being raised.
+ */
++ if ((flags & (O_DIRECTORY | O_CREAT)) == (O_DIRECTORY | O_CREAT))
++ return -EINVAL;
++
++ /* Now handle the creative implementation of O_TMPFILE. */
+ if (flags & __O_TMPFILE) {
+- if ((flags & O_TMPFILE_MASK) != O_TMPFILE)
++ /*
++ * In order to ensure programs get explicit errors when trying
++ * to use O_TMPFILE on old kernels we enforce that O_DIRECTORY
++ * is raised alongside __O_TMPFILE.
++ */
++ if (!(flags & O_DIRECTORY))
+ return -EINVAL;
+ if (!(acc_mode & MAY_WRITE))
+ return -EINVAL;
+diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
+index 1ecdb911add8d..80f37a0d40d7d 100644
+--- a/include/uapi/asm-generic/fcntl.h
++++ b/include/uapi/asm-generic/fcntl.h
+@@ -91,7 +91,6 @@
+
+ /* a horrid kludge trying to make sure that this will fail on old kernels */
+ #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
+-#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT)
+
+ #ifndef O_NDELAY
+ #define O_NDELAY O_NONBLOCK
+diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h
+index b02c8e0f40575..1c7a0f6632c09 100644
+--- a/tools/include/uapi/asm-generic/fcntl.h
++++ b/tools/include/uapi/asm-generic/fcntl.h
+@@ -91,7 +91,6 @@
+
+ /* a horrid kludge trying to make sure that this will fail on old kernels */
+ #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
+-#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT)
+
+ #ifndef O_NDELAY
+ #define O_NDELAY O_NONBLOCK
+--
+2.39.2
+
--- /dev/null
+From 71d75b76fd3c32ba047ca18bd8ed91776930d176 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Feb 2023 18:11:05 -0300
+Subject: parisc: Replace regular spinlock with spin_trylock on panic path
+
+From: Guilherme G. Piccoli <gpiccoli@igalia.com>
+
+[ Upstream commit 829632dae8321787525ee37dc4828bbe6edafdae ]
+
+The panic notifiers' callbacks execute in an atomic context, with
+interrupts/preemption disabled, and all CPUs not running the panic
+function are off, so it's very dangerous to wait on a regular
+spinlock, there's a risk of deadlock.
+
+Refactor the panic notifier of parisc/power driver to make use
+of spin_trylock - for that, we've added a second version of the
+soft-power function. Also, some comments were reorganized and
+trailing white spaces, useless header inclusion and blank lines
+were removed.
+
+Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
+Cc: Jeroen Roovers <jer@xs4all.nl>
+Acked-by: Helge Deller <deller@gmx.de> # parisc
+Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/include/asm/pdc.h | 1 +
+ arch/parisc/kernel/firmware.c | 27 +++++++++++++++++++++++----
+ drivers/parisc/power.c | 16 ++++++++++------
+ 3 files changed, 34 insertions(+), 10 deletions(-)
+
+diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h
+index fcbcf9a96c111..77622558bf651 100644
+--- a/arch/parisc/include/asm/pdc.h
++++ b/arch/parisc/include/asm/pdc.h
+@@ -80,6 +80,7 @@ int pdc_do_firm_test_reset(unsigned long ftc_bitmap);
+ int pdc_do_reset(void);
+ int pdc_soft_power_info(unsigned long *power_reg);
+ int pdc_soft_power_button(int sw_control);
++int pdc_soft_power_button_panic(int sw_control);
+ void pdc_io_reset(void);
+ void pdc_io_reset_devices(void);
+ int pdc_iodc_getc(void);
+diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
+index bd325f2b5349e..3e051a973e9b2 100644
+--- a/arch/parisc/kernel/firmware.c
++++ b/arch/parisc/kernel/firmware.c
+@@ -1232,15 +1232,18 @@ int __init pdc_soft_power_info(unsigned long *power_reg)
+ }
+
+ /*
+- * pdc_soft_power_button - Control the soft power button behaviour
+- * @sw_control: 0 for hardware control, 1 for software control
++ * pdc_soft_power_button{_panic} - Control the soft power button behaviour
++ * @sw_control: 0 for hardware control, 1 for software control
+ *
+ *
+ * This PDC function places the soft power button under software or
+ * hardware control.
+- * Under software control the OS may control to when to allow to shut
+- * down the system. Under hardware control pressing the power button
++ * Under software control the OS may control to when to allow to shut
++ * down the system. Under hardware control pressing the power button
+ * powers off the system immediately.
++ *
++ * The _panic version relies on spin_trylock to prevent deadlock
++ * on panic path.
+ */
+ int pdc_soft_power_button(int sw_control)
+ {
+@@ -1254,6 +1257,22 @@ int pdc_soft_power_button(int sw_control)
+ return retval;
+ }
+
++int pdc_soft_power_button_panic(int sw_control)
++{
++ int retval;
++ unsigned long flags;
++
++ if (!spin_trylock_irqsave(&pdc_lock, flags)) {
++ pr_emerg("Couldn't enable soft power button\n");
++ return -EBUSY; /* ignored by the panic notifier */
++ }
++
++ retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control);
++ spin_unlock_irqrestore(&pdc_lock, flags);
++
++ return retval;
++}
++
+ /*
+ * pdc_io_reset - Hack to avoid overlapping range registers of Bridges devices.
+ * Primarily a problem on T600 (which parisc-linux doesn't support) but
+diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c
+index 456776bd8ee66..6f5e5f0230d39 100644
+--- a/drivers/parisc/power.c
++++ b/drivers/parisc/power.c
+@@ -37,7 +37,6 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+-#include <linux/notifier.h>
+ #include <linux/panic_notifier.h>
+ #include <linux/reboot.h>
+ #include <linux/sched/signal.h>
+@@ -175,16 +174,21 @@ static void powerfail_interrupt(int code, void *x)
+
+
+
+-/* parisc_panic_event() is called by the panic handler.
+- * As soon as a panic occurs, our tasklets above will not be
+- * executed any longer. This function then re-enables the
+- * soft-power switch and allows the user to switch off the system
++/*
++ * parisc_panic_event() is called by the panic handler.
++ *
++ * As soon as a panic occurs, our tasklets above will not
++ * be executed any longer. This function then re-enables
++ * the soft-power switch and allows the user to switch off
++ * the system. We rely in pdc_soft_power_button_panic()
++ * since this version spin_trylocks (instead of regular
++ * spinlock), preventing deadlocks on panic path.
+ */
+ static int parisc_panic_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+ {
+ /* re-enable the soft-power switch */
+- pdc_soft_power_button(0);
++ pdc_soft_power_button_panic(0);
+ return NOTIFY_DONE;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 761893577c4e6d637fe5bf913609bb1a8fc2516f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 23:43:08 +0100
+Subject: phy: st: miphy28lp: use _poll_timeout functions for waits
+
+From: Alain Volmat <avolmat@me.com>
+
+[ Upstream commit e3be4dd2c8d8aabfd2c3127d0e2e5754d3ae82d6 ]
+
+This commit introduces _poll_timeout functions usage instead of
+wait loops waiting for a status bit.
+
+Signed-off-by: Alain Volmat <avolmat@me.com>
+Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
+Link: https://lore.kernel.org/r/20230210224309.98452-1-avolmat@me.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/st/phy-miphy28lp.c | 42 ++++++++--------------------------
+ 1 file changed, 10 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/phy/st/phy-miphy28lp.c b/drivers/phy/st/phy-miphy28lp.c
+index 068160a34f5cc..e30305b77f0d1 100644
+--- a/drivers/phy/st/phy-miphy28lp.c
++++ b/drivers/phy/st/phy-miphy28lp.c
+@@ -9,6 +9,7 @@
+
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+@@ -484,19 +485,11 @@ static inline void miphy28lp_pcie_config_gen(struct miphy28lp_phy *miphy_phy)
+
+ static inline int miphy28lp_wait_compensation(struct miphy28lp_phy *miphy_phy)
+ {
+- unsigned long finish = jiffies + 5 * HZ;
+ u8 val;
+
+ /* Waiting for Compensation to complete */
+- do {
+- val = readb_relaxed(miphy_phy->base + MIPHY_COMP_FSM_6);
+-
+- if (time_after_eq(jiffies, finish))
+- return -EBUSY;
+- cpu_relax();
+- } while (!(val & COMP_DONE));
+-
+- return 0;
++ return readb_relaxed_poll_timeout(miphy_phy->base + MIPHY_COMP_FSM_6,
++ val, val & COMP_DONE, 1, 5 * USEC_PER_SEC);
+ }
+
+
+@@ -805,7 +798,6 @@ static inline void miphy28lp_configure_usb3(struct miphy28lp_phy *miphy_phy)
+
+ static inline int miphy_is_ready(struct miphy28lp_phy *miphy_phy)
+ {
+- unsigned long finish = jiffies + 5 * HZ;
+ u8 mask = HFC_PLL | HFC_RDY;
+ u8 val;
+
+@@ -816,21 +808,14 @@ static inline int miphy_is_ready(struct miphy28lp_phy *miphy_phy)
+ if (miphy_phy->type == PHY_TYPE_SATA)
+ mask |= PHY_RDY;
+
+- do {
+- val = readb_relaxed(miphy_phy->base + MIPHY_STATUS_1);
+- if ((val & mask) != mask)
+- cpu_relax();
+- else
+- return 0;
+- } while (!time_after_eq(jiffies, finish));
+-
+- return -EBUSY;
++ return readb_relaxed_poll_timeout(miphy_phy->base + MIPHY_STATUS_1,
++ val, (val & mask) == mask, 1,
++ 5 * USEC_PER_SEC);
+ }
+
+ static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy)
+ {
+ struct miphy28lp_dev *miphy_dev = miphy_phy->phydev;
+- unsigned long finish = jiffies + 5 * HZ;
+ u32 val;
+
+ if (!miphy_phy->osc_rdy)
+@@ -839,17 +824,10 @@ static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy)
+ if (!miphy_phy->syscfg_reg[SYSCFG_STATUS])
+ return -EINVAL;
+
+- do {
+- regmap_read(miphy_dev->regmap,
+- miphy_phy->syscfg_reg[SYSCFG_STATUS], &val);
+-
+- if ((val & MIPHY_OSC_RDY) != MIPHY_OSC_RDY)
+- cpu_relax();
+- else
+- return 0;
+- } while (!time_after_eq(jiffies, finish));
+-
+- return -EBUSY;
++ return regmap_read_poll_timeout(miphy_dev->regmap,
++ miphy_phy->syscfg_reg[SYSCFG_STATUS],
++ val, val & MIPHY_OSC_RDY, 1,
++ 5 * USEC_PER_SEC);
+ }
+
+ static int miphy28lp_get_resource_byname(struct device_node *child,
+--
+2.39.2
+
--- /dev/null
+From 3ca43ed2ab905cd215d20a81d092b9861e1ed4d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Feb 2023 21:35:53 +0100
+Subject: platform/x86: x86-android-tablets: Add Acer Iconia One 7 B1-750 data
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 2f0cf1e85ddb5ae17284050dc1adafb89e4f1d8f ]
+
+The Acer Iconia One 7 B1-750 is a x86 ACPI tablet which ships with Android
+x86 as factory OS. Its DSDT contains a bunch of I2C devices which are not
+actually there, causing various resource conflicts. Enumeration of these
+is skipped through the acpi_quirk_skip_i2c_client_enumeration().
+
+Add support for manually instantiating the I2C + other devices which are
+actually present on this tablet by adding the necessary device info to
+the x86-android-tablets module.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20230301092331.7038-2-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/x86-android-tablets.c | 101 +++++++++++++++++++--
+ 1 file changed, 91 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/platform/x86/x86-android-tablets.c b/drivers/platform/x86/x86-android-tablets.c
+index 123a4618db55f..9178076d9d7da 100644
+--- a/drivers/platform/x86/x86-android-tablets.c
++++ b/drivers/platform/x86/x86-android-tablets.c
+@@ -265,6 +265,88 @@ static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = {
+ },
+ };
+
++static struct gpiod_lookup_table int3496_reference_gpios = {
++ .dev_id = "intel-int3496",
++ .table = {
++ GPIO_LOOKUP("INT33FC:01", 15, "vbus", GPIO_ACTIVE_HIGH),
++ GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_HIGH),
++ GPIO_LOOKUP("INT33FC:02", 18, "id", GPIO_ACTIVE_HIGH),
++ { }
++ },
++};
++
++/* Acer Iconia One 7 B1-750 has an Android factory img with everything hardcoded */
++static const char * const acer_b1_750_mount_matrix[] = {
++ "-1", "0", "0",
++ "0", "1", "0",
++ "0", "0", "1"
++};
++
++static const struct property_entry acer_b1_750_bma250e_props[] = {
++ PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", acer_b1_750_mount_matrix),
++ { }
++};
++
++static const struct software_node acer_b1_750_bma250e_node = {
++ .properties = acer_b1_750_bma250e_props,
++};
++
++static const struct x86_i2c_client_info acer_b1_750_i2c_clients[] __initconst = {
++ {
++ /* Novatek NVT-ts touchscreen */
++ .board_info = {
++ .type = "NVT-ts",
++ .addr = 0x34,
++ .dev_name = "NVT-ts",
++ },
++ .adapter_path = "\\_SB_.I2C4",
++ .irq_data = {
++ .type = X86_ACPI_IRQ_TYPE_GPIOINT,
++ .chip = "INT33FC:02",
++ .index = 3,
++ .trigger = ACPI_EDGE_SENSITIVE,
++ .polarity = ACPI_ACTIVE_LOW,
++ },
++ }, {
++ /* BMA250E accelerometer */
++ .board_info = {
++ .type = "bma250e",
++ .addr = 0x18,
++ .swnode = &acer_b1_750_bma250e_node,
++ },
++ .adapter_path = "\\_SB_.I2C3",
++ .irq_data = {
++ .type = X86_ACPI_IRQ_TYPE_GPIOINT,
++ .chip = "INT33FC:02",
++ .index = 25,
++ .trigger = ACPI_LEVEL_SENSITIVE,
++ .polarity = ACPI_ACTIVE_HIGH,
++ },
++ },
++};
++
++static struct gpiod_lookup_table acer_b1_750_goodix_gpios = {
++ .dev_id = "i2c-NVT-ts",
++ .table = {
++ GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_LOW),
++ { }
++ },
++};
++
++static struct gpiod_lookup_table * const acer_b1_750_gpios[] = {
++ &acer_b1_750_goodix_gpios,
++ &int3496_reference_gpios,
++ NULL
++};
++
++static const struct x86_dev_info acer_b1_750_info __initconst = {
++ .i2c_client_info = acer_b1_750_i2c_clients,
++ .i2c_client_count = ARRAY_SIZE(acer_b1_750_i2c_clients),
++ .pdev_info = int3496_pdevs,
++ .pdev_count = ARRAY_SIZE(int3496_pdevs),
++ .gpiod_lookup_tables = acer_b1_750_gpios,
++};
++
+ /*
+ * Advantech MICA-071
+ * This is a standard Windows tablet, but it has an extra "quick launch" button
+@@ -1298,17 +1380,8 @@ static const struct x86_i2c_client_info nextbook_ares8_i2c_clients[] __initconst
+ },
+ };
+
+-static struct gpiod_lookup_table nextbook_ares8_int3496_gpios = {
+- .dev_id = "intel-int3496",
+- .table = {
+- GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_HIGH),
+- GPIO_LOOKUP("INT33FC:02", 18, "id", GPIO_ACTIVE_HIGH),
+- { }
+- },
+-};
+-
+ static struct gpiod_lookup_table * const nextbook_ares8_gpios[] = {
+- &nextbook_ares8_int3496_gpios,
++ &int3496_reference_gpios,
+ NULL
+ };
+
+@@ -1435,6 +1508,14 @@ static const struct x86_dev_info xiaomi_mipad2_info __initconst = {
+ };
+
+ static const struct dmi_system_id x86_android_tablet_ids[] __initconst = {
++ {
++ /* Acer Iconia One 7 B1-750 */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "VESPA2"),
++ },
++ .driver_data = (void *)&acer_b1_750_info,
++ },
+ {
+ /* Advantech MICA-071 */
+ .matches = {
+--
+2.39.2
+
--- /dev/null
+From 7478071e20761b4d1a13cd2c640be413f44fe8fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Dec 2022 13:25:53 +0800
+Subject: rcu: Protect rcu_print_task_exp_stall() ->exp_tasks access
+
+From: Zqiang <qiang1.zhang@intel.com>
+
+[ Upstream commit 3c1566bca3f8349f12b75d0a2d5e4a20ad6262ec ]
+
+For kernels built with CONFIG_PREEMPT_RCU=y, the following scenario can
+result in a NULL-pointer dereference:
+
+ CPU1 CPU2
+rcu_preempt_deferred_qs_irqrestore rcu_print_task_exp_stall
+ if (special.b.blocked) READ_ONCE(rnp->exp_tasks) != NULL
+ raw_spin_lock_rcu_node
+ np = rcu_next_node_entry(t, rnp)
+ if (&t->rcu_node_entry == rnp->exp_tasks)
+ WRITE_ONCE(rnp->exp_tasks, np)
+ ....
+ raw_spin_unlock_irqrestore_rcu_node
+ raw_spin_lock_irqsave_rcu_node
+ t = list_entry(rnp->exp_tasks->prev,
+ struct task_struct, rcu_node_entry)
+ (if rnp->exp_tasks is NULL, this
+ will dereference a NULL pointer)
+
+The problem is that CPU2 accesses the rcu_node structure's->exp_tasks
+field without holding the rcu_node structure's ->lock and CPU2 did
+not observe CPU1's change to rcu_node structure's ->exp_tasks in time.
+Therefore, if CPU1 sets rcu_node structure's->exp_tasks pointer to NULL,
+then CPU2 might dereference that NULL pointer.
+
+This commit therefore holds the rcu_node structure's ->lock while
+accessing that structure's->exp_tasks field.
+
+[ paulmck: Apply Frederic Weisbecker feedback. ]
+
+Acked-by: Joel Fernandes (Google) <joel@joelfernandes.org>
+Signed-off-by: Zqiang <qiang1.zhang@intel.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/tree_exp.h | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h
+index 60732264a7d0b..e25321dbb068e 100644
+--- a/kernel/rcu/tree_exp.h
++++ b/kernel/rcu/tree_exp.h
+@@ -800,9 +800,11 @@ static int rcu_print_task_exp_stall(struct rcu_node *rnp)
+ int ndetected = 0;
+ struct task_struct *t;
+
+- if (!READ_ONCE(rnp->exp_tasks))
+- return 0;
+ raw_spin_lock_irqsave_rcu_node(rnp, flags);
++ if (!rnp->exp_tasks) {
++ raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
++ return 0;
++ }
+ t = list_entry(rnp->exp_tasks->prev,
+ struct task_struct, rcu_node_entry);
+ list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry) {
+--
+2.39.2
+
--- /dev/null
+From 1f7b5a9373f0aec69cb270ce8dcdbc01ca783f4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Apr 2023 09:05:27 +0800
+Subject: recordmcount: Fix memory leaks in the uwrite function
+
+From: Hao Zeng <zenghao@kylinos.cn>
+
+[ Upstream commit fa359d068574d29e7d2f0fdd0ebe4c6a12b5cfb9 ]
+
+Common realloc mistake: 'file_append' nulled but not freed upon failure
+
+Link: https://lkml.kernel.org/r/20230426010527.703093-1-zenghao@kylinos.cn
+
+Signed-off-by: Hao Zeng <zenghao@kylinos.cn>
+Suggested-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/recordmcount.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
+index cce12e1971d85..ec692af8ce9eb 100644
+--- a/scripts/recordmcount.c
++++ b/scripts/recordmcount.c
+@@ -102,6 +102,7 @@ static ssize_t uwrite(void const *const buf, size_t const count)
+ {
+ size_t cnt = count;
+ off_t idx = 0;
++ void *p = NULL;
+
+ file_updated = 1;
+
+@@ -109,7 +110,10 @@ static ssize_t uwrite(void const *const buf, size_t const count)
+ off_t aoffset = (file_ptr + count) - file_end;
+
+ if (aoffset > file_append_size) {
+- file_append = realloc(file_append, aoffset);
++ p = realloc(file_append, aoffset);
++ if (!p)
++ free(file_append);
++ file_append = p;
+ file_append_size = aoffset;
+ }
+ if (!file_append) {
+--
+2.39.2
+
--- /dev/null
+From 16fbfae4e4b87648bce9269482bc089aa4d437e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 16:12:18 -0800
+Subject: refscale: Move shutdown from wait_event() to wait_event_idle()
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit 6bc6e6b27524304aadb9c04611ddb1c84dd7617a ]
+
+The ref_scale_shutdown() kthread/function uses wait_event() to wait for
+the refscale test to complete. However, although the read-side tests
+are normally extremely fast, there is no law against specifying a very
+large value for the refscale.loops module parameter or against having
+a slow read-side primitive. Either way, this might well 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.
+
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/refscale.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/rcu/refscale.c b/kernel/rcu/refscale.c
+index 435c884c02b5c..d49a9d66e0000 100644
+--- a/kernel/rcu/refscale.c
++++ b/kernel/rcu/refscale.c
+@@ -795,7 +795,7 @@ ref_scale_cleanup(void)
+ static int
+ ref_scale_shutdown(void *arg)
+ {
+- wait_event(shutdown_wq, shutdown_start);
++ wait_event_idle(shutdown_wq, shutdown_start);
+
+ smp_mb(); // Wake before output.
+ ref_scale_cleanup();
+--
+2.39.2
+
--- /dev/null
+From 2591131679f82b82a2d3505f266399ab15089dfd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Mar 2023 08:18:11 +0100
+Subject: regmap: cache: Return error in cache sync operations for
+ REGCACHE_NONE
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit fd883d79e4dcd2417c2b80756f22a2ff03b0f6e0 ]
+
+There is no sense in doing a cache sync on REGCACHE_NONE regmaps.
+Instead of panicking the kernel due to missing cache_ops, return an error
+to client driver.
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Link: https://lore.kernel.org/r/20230313071812.13577-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/regmap/regcache.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
+index 362e043e26d86..8031007b4887d 100644
+--- a/drivers/base/regmap/regcache.c
++++ b/drivers/base/regmap/regcache.c
+@@ -349,6 +349,9 @@ int regcache_sync(struct regmap *map)
+ const char *name;
+ bool bypass;
+
++ if (WARN_ON(map->cache_type == REGCACHE_NONE))
++ return -EINVAL;
++
+ BUG_ON(!map->cache_ops);
+
+ map->lock(map->lock_arg);
+@@ -418,6 +421,9 @@ int regcache_sync_region(struct regmap *map, unsigned int min,
+ const char *name;
+ bool bypass;
+
++ if (WARN_ON(map->cache_type == REGCACHE_NONE))
++ return -EINVAL;
++
+ BUG_ON(!map->cache_ops);
+
+ map->lock(map->lock_arg);
+--
+2.39.2
+
--- /dev/null
+From dfde6790f1bdbbcfb555ba29a7ae750aa929a7c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Feb 2023 19:03:56 +0200
+Subject: remoteproc: imx_dsp_rproc: Add custom memory copy implementation for
+ i.MX DSP Cores
+
+From: Iuliana Prodan <iuliana.prodan@nxp.com>
+
+[ Upstream commit 408ec1ff0caa340c57eecf4cbd14ef0132036a50 ]
+
+The IRAM is part of the HiFi DSP.
+According to hardware specification only 32-bits write are allowed
+otherwise we get a Kernel panic.
+
+Therefore add a custom memory copy and memset functions to deal with
+the above restriction.
+
+Signed-off-by: Iuliana Prodan <iuliana.prodan@nxp.com>
+Link: https://lore.kernel.org/r/20230221170356.27923-1-iuliana.prodan@oss.nxp.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/imx_dsp_rproc.c | 187 ++++++++++++++++++++++++++++-
+ 1 file changed, 186 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
+index 506ec9565716b..e8e23f6b85563 100644
+--- a/drivers/remoteproc/imx_dsp_rproc.c
++++ b/drivers/remoteproc/imx_dsp_rproc.c
+@@ -721,6 +721,191 @@ static void imx_dsp_rproc_kick(struct rproc *rproc, int vqid)
+ dev_err(dev, "%s: failed (%d, err:%d)\n", __func__, vqid, err);
+ }
+
++/*
++ * Custom memory copy implementation for i.MX DSP Cores
++ *
++ * The IRAM is part of the HiFi DSP.
++ * According to hw specs only 32-bits writes are allowed.
++ */
++static int imx_dsp_rproc_memcpy(void *dest, const void *src, size_t size)
++{
++ const u8 *src_byte = src;
++ const u32 *source = src;
++ u32 affected_mask;
++ u32 *dst = dest;
++ int i, q, r;
++ u32 tmp;
++
++ /* destination must be 32bit aligned */
++ if (!IS_ALIGNED((uintptr_t)dest, 4))
++ return -EINVAL;
++
++ q = size / 4;
++ r = size % 4;
++
++ /* copy data in units of 32 bits at a time */
++ for (i = 0; i < q; i++)
++ writel(source[i], &dst[i]);
++
++ if (r) {
++ affected_mask = GENMASK(8 * r, 0);
++
++ /*
++ * first read the 32bit data of dest, then change affected
++ * bytes, and write back to dest.
++ * For unaffected bytes, it should not be changed
++ */
++ tmp = readl(dest + q * 4);
++ tmp &= ~affected_mask;
++
++ /* avoid reading after end of source */
++ for (i = 0; i < r; i++)
++ tmp |= (src_byte[q * 4 + i] << (8 * i));
++
++ writel(tmp, dest + q * 4);
++ }
++
++ return 0;
++}
++
++/*
++ * Custom memset implementation for i.MX DSP Cores
++ *
++ * The IRAM is part of the HiFi DSP.
++ * According to hw specs only 32-bits writes are allowed.
++ */
++static int imx_dsp_rproc_memset(void *addr, u8 value, size_t size)
++{
++ u32 tmp_val = value;
++ u32 *tmp_dst = addr;
++ u32 affected_mask;
++ int q, r;
++ u32 tmp;
++
++ /* destination must be 32bit aligned */
++ if (!IS_ALIGNED((uintptr_t)addr, 4))
++ return -EINVAL;
++
++ tmp_val |= tmp_val << 8;
++ tmp_val |= tmp_val << 16;
++
++ q = size / 4;
++ r = size % 4;
++
++ while (q--)
++ writel(tmp_val, tmp_dst++);
++
++ if (r) {
++ affected_mask = GENMASK(8 * r, 0);
++
++ /*
++ * first read the 32bit data of addr, then change affected
++ * bytes, and write back to addr.
++ * For unaffected bytes, it should not be changed
++ */
++ tmp = readl(tmp_dst);
++ tmp &= ~affected_mask;
++
++ tmp |= (tmp_val & affected_mask);
++ writel(tmp, tmp_dst);
++ }
++
++ return 0;
++}
++
++/*
++ * imx_dsp_rproc_elf_load_segments() - load firmware segments to memory
++ * @rproc: remote processor which will be booted using these fw segments
++ * @fw: the ELF firmware image
++ *
++ * This function loads the firmware segments to memory, where the remote
++ * processor expects them.
++ *
++ * Return: 0 on success and an appropriate error code otherwise
++ */
++static int imx_dsp_rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
++{
++ struct device *dev = &rproc->dev;
++ const void *ehdr, *phdr;
++ int i, ret = 0;
++ u16 phnum;
++ const u8 *elf_data = fw->data;
++ u8 class = fw_elf_get_class(fw);
++ u32 elf_phdr_get_size = elf_size_of_phdr(class);
++
++ ehdr = elf_data;
++ phnum = elf_hdr_get_e_phnum(class, ehdr);
++ phdr = elf_data + elf_hdr_get_e_phoff(class, ehdr);
++
++ /* go through the available ELF segments */
++ for (i = 0; i < phnum; i++, phdr += elf_phdr_get_size) {
++ u64 da = elf_phdr_get_p_paddr(class, phdr);
++ u64 memsz = elf_phdr_get_p_memsz(class, phdr);
++ u64 filesz = elf_phdr_get_p_filesz(class, phdr);
++ u64 offset = elf_phdr_get_p_offset(class, phdr);
++ u32 type = elf_phdr_get_p_type(class, phdr);
++ void *ptr;
++
++ if (type != PT_LOAD || !memsz)
++ continue;
++
++ dev_dbg(dev, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
++ type, da, memsz, filesz);
++
++ if (filesz > memsz) {
++ dev_err(dev, "bad phdr filesz 0x%llx memsz 0x%llx\n",
++ filesz, memsz);
++ ret = -EINVAL;
++ break;
++ }
++
++ if (offset + filesz > fw->size) {
++ dev_err(dev, "truncated fw: need 0x%llx avail 0x%zx\n",
++ offset + filesz, fw->size);
++ ret = -EINVAL;
++ break;
++ }
++
++ if (!rproc_u64_fit_in_size_t(memsz)) {
++ dev_err(dev, "size (%llx) does not fit in size_t type\n",
++ memsz);
++ ret = -EOVERFLOW;
++ break;
++ }
++
++ /* grab the kernel address for this device address */
++ ptr = rproc_da_to_va(rproc, da, memsz, NULL);
++ if (!ptr) {
++ dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da,
++ memsz);
++ ret = -EINVAL;
++ break;
++ }
++
++ /* put the segment where the remote processor expects it */
++ if (filesz) {
++ ret = imx_dsp_rproc_memcpy(ptr, elf_data + offset, filesz);
++ if (ret) {
++ dev_err(dev, "memory copy failed for da 0x%llx memsz 0x%llx\n",
++ da, memsz);
++ break;
++ }
++ }
++
++ /* zero out remaining memory for this segment */
++ if (memsz > filesz) {
++ ret = imx_dsp_rproc_memset(ptr + filesz, 0, memsz - filesz);
++ if (ret) {
++ dev_err(dev, "memset failed for da 0x%llx memsz 0x%llx\n",
++ da, memsz);
++ break;
++ }
++ }
++ }
++
++ return ret;
++}
++
+ static int imx_dsp_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
+ {
+ if (rproc_elf_load_rsc_table(rproc, fw))
+@@ -735,7 +920,7 @@ static const struct rproc_ops imx_dsp_rproc_ops = {
+ .start = imx_dsp_rproc_start,
+ .stop = imx_dsp_rproc_stop,
+ .kick = imx_dsp_rproc_kick,
+- .load = rproc_elf_load_segments,
++ .load = imx_dsp_rproc_elf_load_segments,
+ .parse_fw = imx_dsp_rproc_parse_fw,
+ .sanity_check = rproc_elf_sanity_check,
+ .get_boot_addr = rproc_elf_get_boot_addr,
+--
+2.39.2
+
--- /dev/null
+From 7f33be4f4442cdb26f221350c7922bb7021feb76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Mar 2023 18:06:34 +0200
+Subject: remoteproc: stm32_rproc: Add mutex protection for workqueue
+
+From: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
+
+[ Upstream commit 35bdafda40cc343ad2ba2cce105eba03a70241cc ]
+
+The workqueue may execute late even after remoteproc is stopped or
+stopping, some resources (rpmsg device and endpoint) have been
+released in rproc_stop_subdevices(), then rproc_vq_interrupt()
+accessing these resources will cause kernel dump.
+
+Call trace:
+virtqueue_add_inbuf
+virtqueue_add_inbuf
+rpmsg_recv_single
+rpmsg_recv_done
+vring_interrupt
+stm32_rproc_mb_vq_work
+process_one_work
+worker_thread
+kthread
+
+Suggested-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
+Link: https://lore.kernel.org/r/20230331160634.3113031-1-arnaud.pouliquen@foss.st.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/stm32_rproc.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
+index 23c1690b8d73f..8746cbb1f168d 100644
+--- a/drivers/remoteproc/stm32_rproc.c
++++ b/drivers/remoteproc/stm32_rproc.c
+@@ -291,8 +291,16 @@ static void stm32_rproc_mb_vq_work(struct work_struct *work)
+ struct stm32_mbox *mb = container_of(work, struct stm32_mbox, vq_work);
+ struct rproc *rproc = dev_get_drvdata(mb->client.dev);
+
++ mutex_lock(&rproc->lock);
++
++ if (rproc->state != RPROC_RUNNING)
++ goto unlock_mutex;
++
+ if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE)
+ dev_dbg(&rproc->dev, "no message found in vq%d\n", mb->vq_id);
++
++unlock_mutex:
++ mutex_unlock(&rproc->lock);
+ }
+
+ static void stm32_rproc_mb_callback(struct mbox_client *cl, void *data)
+--
+2.39.2
+
--- /dev/null
+From 4a7f377f5ace5754751ccf915ad1d72f4625d960 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Apr 2023 16:43:49 +0800
+Subject: samples/bpf: Fix fout leak in hbm's run_bpf_prog
+
+From: Hao Zeng <zenghao@kylinos.cn>
+
+[ Upstream commit 23acb14af1914010dd0aae1bbb7fab28bf518b8e ]
+
+Fix fout being fopen'ed but then not subsequently fclose'd. In the affected
+branch, fout is otherwise going out of scope.
+
+Signed-off-by: Hao Zeng <zenghao@kylinos.cn>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20230411084349.1999628-1-zenghao@kylinos.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/bpf/hbm.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/samples/bpf/hbm.c b/samples/bpf/hbm.c
+index 516fbac28b716..7f89700a17b69 100644
+--- a/samples/bpf/hbm.c
++++ b/samples/bpf/hbm.c
+@@ -315,6 +315,7 @@ static int run_bpf_prog(char *prog, int cg_id)
+ fout = fopen(fname, "w");
+ fprintf(fout, "id:%d\n", cg_id);
+ fprintf(fout, "ERROR: Could not lookup queue_stats\n");
++ fclose(fout);
+ } else if (stats_flag && qstats.lastPacketTime >
+ qstats.firstPacketTime) {
+ long long delta_us = (qstats.lastPacketTime -
+--
+2.39.2
+
--- /dev/null
+From f69b9a383a2128a79e9a10c1be3daf95a1a97bb1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Apr 2023 10:24:07 -0700
+Subject: sched: Fix KCSAN noinstr violation
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit e0b081d17a9f4e5c0cbb0e5fbeb1abe3de0f7e4e ]
+
+With KCSAN enabled, end_of_stack() can get out-of-lined. Force it
+inline.
+
+Fixes the following warnings:
+
+ vmlinux.o: warning: objtool: check_stackleak_irqoff+0x2b: call to end_of_stack() leaves .noinstr.text section
+
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/cc1b4d73d3a428a00d206242a68fdf99a934ca7b.1681320026.git.jpoimboe@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sched/task_stack.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/sched/task_stack.h b/include/linux/sched/task_stack.h
+index 5e799a47431e8..f158b025c1750 100644
+--- a/include/linux/sched/task_stack.h
++++ b/include/linux/sched/task_stack.h
+@@ -23,7 +23,7 @@ static __always_inline void *task_stack_page(const struct task_struct *task)
+
+ #define setup_thread_stack(new,old) do { } while(0)
+
+-static inline unsigned long *end_of_stack(const struct task_struct *task)
++static __always_inline unsigned long *end_of_stack(const struct task_struct *task)
+ {
+ #ifdef CONFIG_STACK_GROWSUP
+ return (unsigned long *)((unsigned long)task->stack + THREAD_SIZE) - 1;
+--
+2.39.2
+
--- /dev/null
+From ebfbead14bfbbe6f3a92c6dcc2cd15e601c6b8ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Mar 2023 15:16:22 -0800
+Subject: scsi: lpfc: Correct used_rpi count when devloss tmo fires with no
+ recovery
+
+From: Justin Tee <justin.tee@broadcom.com>
+
+[ Upstream commit db651ec22524eb8f9c854fbb4d9acd5d7e5be9e4 ]
+
+A fabric controller can sometimes send an RDP request right before a link
+down event. Because of this outstanding RDP request, the driver does not
+remove the last reference count on its ndlp causing a potential leak of RPI
+resources when devloss tmo fires.
+
+In lpfc_cmpl_els_rsp(), modify the NPIV clause to always allow the
+lpfc_drop_node() routine to execute when not registered with SCSI
+transport.
+
+This relaxes the contraint that an NPIV ndlp must be in a specific state in
+order to call lpfc_drop node. Logic is revised such that the
+lpfc_drop_node() routine is always called to ensure the last ndlp decrement
+occurs.
+
+Signed-off-by: Justin Tee <justin.tee@broadcom.com>
+Link: https://lore.kernel.org/r/20230301231626.9621-7-justintee8345@gmail.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_els.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
+index 863b2125fed6c..ddd5949d8fc01 100644
+--- a/drivers/scsi/lpfc/lpfc_els.c
++++ b/drivers/scsi/lpfc/lpfc_els.c
+@@ -5402,18 +5402,20 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ * these conditions and release the RPI.
+ */
+ if (phba->sli_rev == LPFC_SLI_REV4 &&
+- (vport && vport->port_type == LPFC_NPIV_PORT) &&
+- !(ndlp->fc4_xpt_flags & SCSI_XPT_REGD) &&
+- ndlp->nlp_flag & NLP_RELEASE_RPI) {
+- if (ndlp->nlp_state != NLP_STE_PLOGI_ISSUE &&
+- ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE) {
+- lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi);
+- spin_lock_irq(&ndlp->lock);
+- ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR;
+- ndlp->nlp_flag &= ~NLP_RELEASE_RPI;
+- spin_unlock_irq(&ndlp->lock);
+- lpfc_drop_node(vport, ndlp);
++ vport && vport->port_type == LPFC_NPIV_PORT &&
++ !(ndlp->fc4_xpt_flags & SCSI_XPT_REGD)) {
++ if (ndlp->nlp_flag & NLP_RELEASE_RPI) {
++ if (ndlp->nlp_state != NLP_STE_PLOGI_ISSUE &&
++ ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE) {
++ lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi);
++ spin_lock_irq(&ndlp->lock);
++ ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR;
++ ndlp->nlp_flag &= ~NLP_RELEASE_RPI;
++ spin_unlock_irq(&ndlp->lock);
++ }
+ }
++
++ lpfc_drop_node(vport, ndlp);
+ }
+
+ /* Release the originating I/O reference. */
+--
+2.39.2
+
--- /dev/null
+From b3b6aa60f67b822b5aeff3610812c04caf895be7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Mar 2023 15:16:17 -0800
+Subject: scsi: lpfc: Prevent lpfc_debugfs_lockstat_write() buffer overflow
+
+From: Justin Tee <justin.tee@broadcom.com>
+
+[ Upstream commit c6087b82a9146826564a55c5ca0164cac40348f5 ]
+
+A static code analysis tool flagged the possibility of buffer overflow when
+using copy_from_user() for a debugfs entry.
+
+Currently, it is possible that copy_from_user() copies more bytes than what
+would fit in the mybuf char array. Add a min() restriction check between
+sizeof(mybuf) - 1 and nbytes passed from the userspace buffer to protect
+against buffer overflow.
+
+Link: https://lore.kernel.org/r/20230301231626.9621-2-justintee8345@gmail.com
+Signed-off-by: Justin Tee <justin.tee@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_debugfs.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
+index f5252e45a48a2..3e365e5e194a2 100644
+--- a/drivers/scsi/lpfc/lpfc_debugfs.c
++++ b/drivers/scsi/lpfc/lpfc_debugfs.c
+@@ -2157,10 +2157,13 @@ lpfc_debugfs_lockstat_write(struct file *file, const char __user *buf,
+ char mybuf[64];
+ char *pbuf;
+ int i;
++ size_t bsize;
+
+ memset(mybuf, 0, sizeof(mybuf));
+
+- if (copy_from_user(mybuf, buf, nbytes))
++ bsize = min(nbytes, (sizeof(mybuf) - 1));
++
++ if (copy_from_user(mybuf, buf, bsize))
+ return -EFAULT;
+ pbuf = &mybuf[0];
+
+@@ -2181,7 +2184,7 @@ lpfc_debugfs_lockstat_write(struct file *file, const char __user *buf,
+ qp->lock_conflict.wq_access = 0;
+ }
+ }
+- return nbytes;
++ return bsize;
+ }
+ #endif
+
+--
+2.39.2
+
--- /dev/null
+From 856bc4ce51842fe1e00ea9c566df47f792121cc9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Mar 2023 16:16:35 +0800
+Subject: scsi: message: mptlan: Fix use after free bug in mptlan_remove() due
+ to race condition
+
+From: Zheng Wang <zyytlz.wz@163.com>
+
+[ Upstream commit f486893288f3e9b171b836f43853a6426515d800 ]
+
+mptlan_probe() calls mpt_register_lan_device() which initializes the
+&priv->post_buckets_task workqueue. A call to
+mpt_lan_wake_post_buckets_task() will subsequently start the work.
+
+During driver unload in mptlan_remove() the following race may occur:
+
+CPU0 CPU1
+
+ |mpt_lan_post_receive_buckets_work()
+mptlan_remove() |
+ free_netdev() |
+ kfree(dev); |
+ |
+ | dev->mtu
+ | //use
+
+Fix this by finishing the work prior to cleaning up in mptlan_remove().
+
+[mkp: we really should remove mptlan instead of attempting to fix it]
+
+Signed-off-by: Zheng Wang <zyytlz.wz@163.com>
+Link: https://lore.kernel.org/r/20230318081635.796479-1-zyytlz.wz@163.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/message/fusion/mptlan.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
+index 142eb5d5d9df6..de2e7bcf47847 100644
+--- a/drivers/message/fusion/mptlan.c
++++ b/drivers/message/fusion/mptlan.c
+@@ -1433,7 +1433,9 @@ mptlan_remove(struct pci_dev *pdev)
+ {
+ MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
+ struct net_device *dev = ioc->netdev;
++ struct mpt_lan_priv *priv = netdev_priv(dev);
+
++ cancel_delayed_work_sync(&priv->post_buckets_task);
+ if(dev != NULL) {
+ unregister_netdev(dev);
+ free_netdev(dev);
+--
+2.39.2
+
--- /dev/null
+From 5882f9b66f881dcfad63c2d3b7667a4d47cc4375 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Mar 2023 20:56:17 -0500
+Subject: scsi: target: iscsit: Free cmds before session free
+
+From: Dmitry Bogdanov <d.bogdanov@yadro.com>
+
+[ Upstream commit d8990b5a4d065f38f35d69bcd627ec5a7f8330ca ]
+
+Commands from recovery entries are freed after session has been closed.
+That leads to use-after-free at command free or NPE with such call trace:
+
+Time2Retain timer expired for SID: 1, cleaning up iSCSI session.
+BUG: kernel NULL pointer dereference, address: 0000000000000140
+RIP: 0010:sbitmap_queue_clear+0x3a/0xa0
+Call Trace:
+ target_release_cmd_kref+0xd1/0x1f0 [target_core_mod]
+ transport_generic_free_cmd+0xd1/0x180 [target_core_mod]
+ iscsit_free_cmd+0x53/0xd0 [iscsi_target_mod]
+ iscsit_free_connection_recovery_entries+0x29d/0x320 [iscsi_target_mod]
+ iscsit_close_session+0x13a/0x140 [iscsi_target_mod]
+ iscsit_check_post_dataout+0x440/0x440 [iscsi_target_mod]
+ call_timer_fn+0x24/0x140
+
+Move cleanup of recovery enrties to before session freeing.
+
+Reported-by: Forza <forza@tnonline.net>
+Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Link: https://lore.kernel.org/r/20230319015620.96006-7-michael.christie@oracle.com
+Reviewed-by: Maurizio Lombardi <mlombard@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/target/iscsi/iscsi_target.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
+index 3f7a9f7f5f4e3..07e196b44b91d 100644
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -4531,6 +4531,9 @@ int iscsit_close_session(struct iscsit_session *sess, bool can_sleep)
+ iscsit_stop_time2retain_timer(sess);
+ spin_unlock_bh(&se_tpg->session_lock);
+
++ if (sess->sess_ops->ErrorRecoveryLevel == 2)
++ iscsit_free_connection_recovery_entries(sess);
++
+ /*
+ * transport_deregister_session_configfs() will clear the
+ * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context
+@@ -4554,9 +4557,6 @@ int iscsit_close_session(struct iscsit_session *sess, bool can_sleep)
+
+ transport_deregister_session(sess->se_sess);
+
+- if (sess->sess_ops->ErrorRecoveryLevel == 2)
+- iscsit_free_connection_recovery_entries(sess);
+-
+ iscsit_free_all_ooo_cmdsns(sess);
+
+ spin_lock_bh(&se_tpg->session_lock);
+--
+2.39.2
+
--- /dev/null
+From aac36eba24a7d022292bf9f0bb0053320e5828b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Mar 2023 13:58:32 +0300
+Subject: scsi: ufs: ufs-pci: Add support for Intel Lunar Lake
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit 0a07d3c7a1d205b47d9f3608ff4e9d1065d63b6d ]
+
+Add PCI ID to support Intel Lunar Lake, same as MTL.
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20230328105832.3495-1-adrian.hunter@intel.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/host/ufshcd-pci.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/ufs/host/ufshcd-pci.c b/drivers/ufs/host/ufshcd-pci.c
+index 1c91f43e15c8e..9c911787f84c6 100644
+--- a/drivers/ufs/host/ufshcd-pci.c
++++ b/drivers/ufs/host/ufshcd-pci.c
+@@ -607,6 +607,7 @@ static const struct pci_device_id ufshcd_pci_tbl[] = {
+ { PCI_VDEVICE(INTEL, 0x51FF), (kernel_ulong_t)&ufs_intel_adl_hba_vops },
+ { PCI_VDEVICE(INTEL, 0x54FF), (kernel_ulong_t)&ufs_intel_adl_hba_vops },
+ { PCI_VDEVICE(INTEL, 0x7E47), (kernel_ulong_t)&ufs_intel_mtl_hba_vops },
++ { PCI_VDEVICE(INTEL, 0xA847), (kernel_ulong_t)&ufs_intel_mtl_hba_vops },
+ { } /* terminate list */
+ };
+
+--
+2.39.2
+
--- /dev/null
+From a8e69c29d1e0bb430dc6e85658adeea8b7d4a526 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 26 Feb 2023 16:16:33 +0300
+Subject: selftests: cgroup: Add 'malloc' failures checks in test_memcontrol
+
+From: Ivan Orlov <ivan.orlov0322@gmail.com>
+
+[ Upstream commit c83f320e55a49abd90629f42a72897afd579e0de ]
+
+There are several 'malloc' calls in test_memcontrol, which can be
+unsuccessful. This patch will add 'malloc' failures checking to
+give more details about test's fail reasons and avoid possible
+undefined behavior during the future null dereference (like the
+one in alloc_anon_50M_check_swap function).
+
+Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
+Reviewed-by: Muchun Song <songmuchun@bytedance.com>
+Acked-by: Shakeel Butt <shakeelb@google.com>
+Acked-by: Roman Gushchin <roman.gushchin@linux.dev>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/cgroup/test_memcontrol.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c
+index 8833359556f38..fe4f9f4302822 100644
+--- a/tools/testing/selftests/cgroup/test_memcontrol.c
++++ b/tools/testing/selftests/cgroup/test_memcontrol.c
+@@ -98,6 +98,11 @@ static int alloc_anon_50M_check(const char *cgroup, void *arg)
+ int ret = -1;
+
+ buf = malloc(size);
++ if (buf == NULL) {
++ fprintf(stderr, "malloc() failed\n");
++ return -1;
++ }
++
+ for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
+ *ptr = 0;
+
+@@ -211,6 +216,11 @@ static int alloc_anon_noexit(const char *cgroup, void *arg)
+ char *buf, *ptr;
+
+ buf = malloc(size);
++ if (buf == NULL) {
++ fprintf(stderr, "malloc() failed\n");
++ return -1;
++ }
++
+ for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
+ *ptr = 0;
+
+@@ -759,6 +769,11 @@ static int alloc_anon_50M_check_swap(const char *cgroup, void *arg)
+ int ret = -1;
+
+ buf = malloc(size);
++ if (buf == NULL) {
++ fprintf(stderr, "malloc() failed\n");
++ return -1;
++ }
++
+ for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
+ *ptr = 0;
+
+--
+2.39.2
+
--- /dev/null
+From 7f3ae94f0325f35124bd8d2b00fbde5bb8ba2b9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Apr 2023 13:14:06 +0300
+Subject: serial: 8250: Reinit port->pm on port specific driver unbind
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit 04e82793f068d2f0ffe62fcea03d007a8cdc16a7 ]
+
+When we unbind a serial port hardware specific 8250 driver, the generic
+serial8250 driver takes over the port. After that we see an oops about 10
+seconds later. This can produce the following at least on some TI SoCs:
+
+Unhandled fault: imprecise external abort (0x1406)
+Internal error: : 1406 [#1] SMP ARM
+
+Turns out that we may still have the serial port hardware specific driver
+port->pm in use, and serial8250_pm() tries to call it after the port
+specific driver is gone:
+
+serial8250_pm [8250_base] from uart_change_pm+0x54/0x8c [serial_base]
+uart_change_pm [serial_base] from uart_hangup+0x154/0x198 [serial_base]
+uart_hangup [serial_base] from __tty_hangup.part.0+0x328/0x37c
+__tty_hangup.part.0 from disassociate_ctty+0x154/0x20c
+disassociate_ctty from do_exit+0x744/0xaac
+do_exit from do_group_exit+0x40/0x8c
+do_group_exit from __wake_up_parent+0x0/0x1c
+
+Let's fix the issue by calling serial8250_set_defaults() in
+serial8250_unregister_port(). This will set the port back to using
+the serial8250 default functions, and sets the port->pm to point to
+serial8250_pm.
+
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Link: https://lore.kernel.org/r/20230418101407.12403-1-tony@atomide.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
+index 94fbf0add2ce2..81a5dab1a8286 100644
+--- a/drivers/tty/serial/8250/8250_core.c
++++ b/drivers/tty/serial/8250/8250_core.c
+@@ -1157,6 +1157,7 @@ void serial8250_unregister_port(int line)
+ uart->port.type = PORT_UNKNOWN;
+ uart->port.dev = &serial8250_isa_devs->dev;
+ uart->capabilities = 0;
++ serial8250_init_port(uart);
+ serial8250_apply_quirks(uart);
+ uart_add_one_port(&serial8250_reg, &uart->port);
+ } else {
+--
+2.39.2
+
ext4-don-t-clear-sb_rdonly-when-remounting-r-w-until.patch
ext4-allow-to-find-by-goal-if-ext4_mb_hint_goal_only.patch
ext4-allow-ext4_get_group_info-to-fail.patch
+refscale-move-shutdown-from-wait_event-to-wait_event.patch
+selftests-cgroup-add-malloc-failures-checks-in-test_.patch
+rcu-protect-rcu_print_task_exp_stall-exp_tasks-acces.patch
+open-return-einval-for-o_directory-o_creat.patch
+fs-hfsplus-remove-warn_on-from-hfsplus_cat_-read-wri.patch
+drm-displayid-add-displayid_get_header-and-check-bou.patch
+drm-amd-display-populate-subvp-cmd-info-only-for-the.patch
+drm-amd-display-correct-dml-calculation-to-align-hw-.patch
+platform-x86-x86-android-tablets-add-acer-iconia-one.patch
+drm-amd-display-enable-hostvm-based-on-riommu-active.patch
+drm-amd-display-use-dc_log_dc-in-the-trasform-pixel-.patch
+regmap-cache-return-error-in-cache-sync-operations-f.patch
+remoteproc-imx_dsp_rproc-add-custom-memory-copy-impl.patch
+arm64-dts-qcom-msm8996-add-missing-dwc3-quirks.patch
+media-cx23885-fix-a-null-ptr-deref-bug-in-buffer_pre.patch
+media-pci-tw68-fix-null-ptr-deref-bug-in-buf-prepare.patch
+media-pvrusb2-video_pvrusb2-depends-on-dvb_core-to-u.patch
+acpi-processor-check-for-null-return-of-devm_kzalloc.patch
+drm-rockchip-dw_hdmi-cleanup-drm-encoder-during-unbi.patch
+memstick-r592-fix-uaf-bug-in-r592_remove-due-to-race.patch
+arm64-dts-imx8mq-librem5-remove-dis_u3_susphy_quirk-.patch
+firmware-arm_sdei-fix-sleep-from-invalid-context-bug.patch
+acpi-ec-fix-oops-when-removing-custom-query-handlers.patch
+drm-amd-display-fixed-dcn30-underflow-issue.patch
+remoteproc-stm32_rproc-add-mutex-protection-for-work.patch
+drm-tegra-avoid-potential-32-bit-integer-overflow.patch
+drm-msm-dp-clean-up-handling-of-dp-aux-interrupts.patch
+acpica-avoid-undefined-behavior-applying-zero-offset.patch
+acpica-acpica-check-null-return-of-acpi_allocate_zer.patch
+arm64-dts-qcom-sdm845-polaris-drop-inexistent-proper.patch
+irqchip-gicv3-workaround-for-nvidia-erratum-t241-fab.patch
+acpi-video-remove-desktops-without-backlight-dmi-qui.patch
+drm-amd-display-correct-dml-calculation-to-follow-hw.patch
+drm-amd-fix-an-out-of-bounds-error-in-bios-parser.patch
+drm-amdgpu-fix-sdma-v4-sw-fini-error.patch
+media-prefer-designated-initializers-over-memset-for.patch
+media-mediatek-vcodec-fix-potential-array-out-of-bou.patch
+wifi-ath-silence-memcpy-run-time-false-positive-warn.patch
+bpf-annotate-data-races-in-bpf_local_storage.patch
+wifi-brcmfmac-pcie-provide-a-buffer-of-random-bytes-.patch
+wifi-brcmfmac-cfg80211-pass-the-pmk-in-binary-instea.patch
+ext2-check-block-size-validity-during-mount.patch
+scsi-lpfc-prevent-lpfc_debugfs_lockstat_write-buffer.patch
+scsi-lpfc-correct-used_rpi-count-when-devloss-tmo-fi.patch
+bnxt-avoid-overflow-in-bnxt_get_nvram_directory.patch
+net-pasemi-fix-return-type-of-pasemi_mac_start_tx.patch
+net-catch-invalid-index-in-xps-mapping.patch
+netdev-enforce-index-cap-in-netdev_get_tx_queue.patch
+scsi-target-iscsit-free-cmds-before-session-free.patch
+lib-cpu_rmap-avoid-use-after-free-on-rmap-obj-array-.patch
+scsi-message-mptlan-fix-use-after-free-bug-in-mptlan.patch
+gfs2-fix-inode-height-consistency-check.patch
+scsi-ufs-ufs-pci-add-support-for-intel-lunar-lake.patch
+ext4-set-goal-start-correctly-in-ext4_mb_normalize_r.patch
+ext4-fix-best-extent-lstart-adjustment-logic-in-ext4.patch
+crypto-jitter-permanent-and-intermittent-health-erro.patch
+f2fs-fix-system-crash-due-to-lack-of-free-space-in-l.patch
+f2fs-fix-to-drop-all-dirty-pages-during-umount-if-cp.patch
+f2fs-fix-to-check-readonly-condition-correctly.patch
+samples-bpf-fix-fout-leak-in-hbm-s-run_bpf_prog.patch
+bpf-add-preempt_count_-sub-add-into-btf-id-deny-list.patch
+md-fix-soft-lockup-in-status_resync.patch
+wifi-iwlwifi-pcie-fix-possible-null-pointer-derefere.patch
+wifi-iwlwifi-add-a-new-pci-device-id-for-bz-device.patch
+wifi-iwlwifi-pcie-fix-integer-overflow-in-iwl_write_.patch
+wifi-iwlwifi-mvm-fix-ptk_pn-memory-leak.patch
+block-bfq-fix-division-by-zero-error-on-zero-wsum.patch
+wifi-ath11k-ignore-frags-from-uninitialized-peer-in-.patch
+wifi-iwlwifi-fix-iwl_mvm_max_amsdu_size-for-mlo.patch
+null_blk-always-check-queue-mode-setting-from-config.patch
+wifi-iwlwifi-dvm-fix-memcpy-detected-field-spanning-.patch
+wifi-ath11k-fix-skb-corruption-in-reo-destination-ri.patch
+nbd-fix-incomplete-validation-of-ioctl-arg.patch
+ipvs-update-width-of-source-for-ip_vs_sync_conn_opti.patch
+bluetooth-btusb-add-new-pid-vid-04ca-3801-for-mt7663.patch
+bluetooth-add-new-quirk-for-broken-local-ext-feature.patch
+bluetooth-btrtl-add-support-for-the-rtl8723cs.patch
+bluetooth-improve-support-for-actions-semi-ats2851-b.patch
+bluetooth-btrtl-check-for-null-in-btrtl_set_quirks.patch
+bluetooth-btintel-add-le-states-quirk-support.patch
+bluetooth-hci_bcm-fall-back-to-getting-bdaddr-from-e.patch
+bluetooth-add-new-quirk-for-broken-set-random-rpa-ti.patch
+bluetooth-l2cap-fix-bad-unlock-balance-in-l2cap_disc.patch
+bluetooth-btrtl-add-the-support-for-rtl8851b.patch
+staging-rtl8192e-replace-macro-rtl_pci_device-with-p.patch
+hid-apple-set-the-tilde-quirk-flag-on-the-geyser-4-a.patch
+staging-axis-fifo-initialize-timeouts-in-init-only.patch
+asoc-amd-yc-add-dmi-entries-to-support-hp-omen-16-n0.patch
+hid-logitech-hidpp-don-t-use-the-usb-serial-for-usb-.patch
+hid-logitech-hidpp-reconcile-usb-and-unifying-serial.patch
+spi-spi-imx-fix-mx51_ecspi_-macros-when-cs-3.patch
+usb-typec-ucsi-acpi-add-quirk-for-asus-zenbook-um325.patch
+alsa-hda-lnl-add-hd-audio-pci-id.patch
+asoc-amd-add-dell-g15-5525-to-quirks-list.patch
+asoc-amd-yc-add-thinkbook-14-g5-arp-to-quirks-list-f.patch
+hid-apple-set-the-tilde-quirk-flag-on-the-geyser-3.patch
+hid-ignore-battery-for-elan-touchscreen-on-rog-flow-.patch
+hid-wacom-generic-set-battery-quirk-only-when-we-see.patch
+usb-typec-tcpm-fix-multiple-times-discover-svids-err.patch
+serial-8250-reinit-port-pm-on-port-specific-driver-u.patch
+mcb-pci-reallocate-memory-region-to-avoid-memory-ove.patch
+sched-fix-kcsan-noinstr-violation.patch
+lkdtm-stackleak-fix-noinstr-violation.patch
+recordmcount-fix-memory-leaks-in-the-uwrite-function.patch
+soundwire-dmi-quirks-add-remapping-for-intel-rooks-c.patch
+phy-st-miphy28lp-use-_poll_timeout-functions-for-wai.patch
+soundwire-qcom-gracefully-handle-too-many-ports-in-d.patch
+soundwire-bus-fix-unbalanced-pm_runtime_put-causing-.patch
+mfd-intel_soc_pmic_chtwc-add-lenovo-yoga-book-x90f-t.patch
+mfd-dln2-fix-memory-leak-in-dln2_probe.patch
+mfd-intel-lpss-add-intel-meteor-lake-pch-s-lpss-pci-.patch
+parisc-replace-regular-spinlock-with-spin_trylock-on.patch
--- /dev/null
+From bf6fd82af155417e8f9b03100409aadfd2e41508 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 14:46:40 +0100
+Subject: soundwire: bus: Fix unbalanced pm_runtime_put() causing usage count
+ underflow
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit e9537962519e88969f5f69cd0571eb4f6984403c ]
+
+This reverts commit
+443a98e649b4 ("soundwire: bus: use pm_runtime_resume_and_get()")
+
+Change calls to pm_runtime_resume_and_get() back to pm_runtime_get_sync().
+This fixes a usage count underrun caused by doing a pm_runtime_put() even
+though pm_runtime_resume_and_get() returned an error.
+
+The three affected functions ignore -EACCES error from trying to get
+pm_runtime, and carry on, including a put at the end of the function.
+But pm_runtime_resume_and_get() does not increment the usage count if it
+returns an error. So in the -EACCES case you must not call
+pm_runtime_put().
+
+The documentation for pm_runtime_get_sync() says:
+ "Consider using pm_runtime_resume_and_get() ... as this is likely to
+ result in cleaner code."
+
+In this case I don't think it results in cleaner code because the
+pm_runtime_put() at the end of the function would have to be conditional on
+the return value from pm_runtime_resume_and_get() at the top of the
+function.
+
+pm_runtime_get_sync() doesn't have this problem because it always
+increments the count, so always needs a put. The code can just flow through
+and do the pm_runtime_put() unconditionally.
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20230406134640.8582-1-rf@opensource.cirrus.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/bus.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
+index 76515c33e639e..4fd221d0cc818 100644
+--- a/drivers/soundwire/bus.c
++++ b/drivers/soundwire/bus.c
+@@ -571,9 +571,11 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
+ {
+ int ret;
+
+- ret = pm_runtime_resume_and_get(&slave->dev);
+- if (ret < 0 && ret != -EACCES)
++ ret = pm_runtime_get_sync(&slave->dev);
++ if (ret < 0 && ret != -EACCES) {
++ pm_runtime_put_noidle(&slave->dev);
+ return ret;
++ }
+
+ ret = sdw_nread_no_pm(slave, addr, count, val);
+
+@@ -595,9 +597,11 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val)
+ {
+ int ret;
+
+- ret = pm_runtime_resume_and_get(&slave->dev);
+- if (ret < 0 && ret != -EACCES)
++ ret = pm_runtime_get_sync(&slave->dev);
++ if (ret < 0 && ret != -EACCES) {
++ pm_runtime_put_noidle(&slave->dev);
+ return ret;
++ }
+
+ ret = sdw_nwrite_no_pm(slave, addr, count, val);
+
+@@ -1565,9 +1569,10 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
+
+ sdw_modify_slave_status(slave, SDW_SLAVE_ALERT);
+
+- ret = pm_runtime_resume_and_get(&slave->dev);
++ ret = pm_runtime_get_sync(&slave->dev);
+ if (ret < 0 && ret != -EACCES) {
+ dev_err(&slave->dev, "Failed to resume device: %d\n", ret);
++ pm_runtime_put_noidle(&slave->dev);
+ return ret;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From b1be588746f8273c131c01d67bd36b739f5f5abc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Mar 2023 17:06:18 +0800
+Subject: soundwire: dmi-quirks: add remapping for Intel 'Rooks County' NUC M15
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Eugene Huang <eugene.huang99@gmail.com>
+
+[ Upstream commit 01b33e284ca28cc977bdcfb23be2c719f2139175 ]
+
+Same DSDT problem as the HP Omen 16-k0005TX, except rt1316 amp is on
+link2.
+
+Link: https://github.com/thesofproject/linux/issues/4088
+Signed-off-by: Eugene Huang <eugene.huang99@gmail.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://lore.kernel.org/r/20230314090618.498716-1-yung-chuan.liao@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/dmi-quirks.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/drivers/soundwire/dmi-quirks.c b/drivers/soundwire/dmi-quirks.c
+index 7969881f126dc..58ea013fa918a 100644
+--- a/drivers/soundwire/dmi-quirks.c
++++ b/drivers/soundwire/dmi-quirks.c
+@@ -73,6 +73,23 @@ static const struct adr_remap hp_omen_16[] = {
+ {}
+ };
+
++/*
++ * Intel NUC M15 LAPRC510 and LAPRC710
++ */
++static const struct adr_remap intel_rooks_county[] = {
++ /* rt711-sdca on link0 */
++ {
++ 0x000020025d071100ull,
++ 0x000030025d071101ull
++ },
++ /* rt1316-sdca on link2 */
++ {
++ 0x000120025d071100ull,
++ 0x000230025d131601ull
++ },
++ {}
++};
++
+ static const struct dmi_system_id adr_remap_quirk_table[] = {
+ /* TGL devices */
+ {
+@@ -98,6 +115,14 @@ static const struct dmi_system_id adr_remap_quirk_table[] = {
+ },
+ .driver_data = (void *)intel_tgl_bios,
+ },
++ {
++ /* quirk used for NUC15 'Rooks County' LAPRC510 and LAPRC710 skews */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "LAPRC"),
++ },
++ .driver_data = (void *)intel_rooks_county,
++ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+--
+2.39.2
+
--- /dev/null
+From da6cac970293e781a724982351f39aa726627564 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Feb 2023 15:44:12 +0100
+Subject: soundwire: qcom: gracefully handle too many ports in DT
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 2367e0ecb498764e95cfda691ff0828f7d25f9a4 ]
+
+There are two issues related to the number of ports coming from
+Devicetree when exceeding in total QCOM_SDW_MAX_PORTS. Both lead to
+incorrect memory accesses:
+1. With DTS having too big value of input or output ports, the driver,
+ when copying port parameters from local/stack arrays into 'pconfig'
+ array in 'struct qcom_swrm_ctrl', will iterate over their sizes.
+
+2. If DTS also has too many parameters for these ports (e.g.
+ qcom,ports-sinterval-low), the driver will overflow buffers on the
+ stack when reading these properties from DTS.
+
+Add a sanity check so incorrect DTS will not cause kernel memory
+corruption.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230222144412.237832-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/qcom.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
+index 866026185c669..21c50972047f5 100644
+--- a/drivers/soundwire/qcom.c
++++ b/drivers/soundwire/qcom.c
+@@ -1209,6 +1209,9 @@ static int qcom_swrm_get_port_config(struct qcom_swrm_ctrl *ctrl)
+ ctrl->num_dout_ports = val;
+
+ nports = ctrl->num_dout_ports + ctrl->num_din_ports;
++ if (nports > QCOM_SDW_MAX_PORTS)
++ return -EINVAL;
++
+ /* Valid port numbers are from 1-14, so mask out port 0 explicitly */
+ set_bit(0, &ctrl->dout_port_mask);
+ set_bit(0, &ctrl->din_port_mask);
+--
+2.39.2
+
--- /dev/null
+From 97bbb78468e11385a9dd4cbaa83d43a961cb0c3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Mar 2023 18:21:32 -0400
+Subject: spi: spi-imx: fix MX51_ECSPI_* macros when cs > 3
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kevin Groeneveld <kgroeneveld@lenbrook.com>
+
+[ Upstream commit 87c614175bbf28d3fd076dc2d166bac759e41427 ]
+
+When using gpio based chip select the cs value can go outside the range
+0 – 3. The various MX51_ECSPI_* macros did not take this into consideration
+resulting in possible corruption of the configuration.
+
+For example for any cs value over 3 the SCLKPHA bits would not be set and
+other values in the register possibly corrupted.
+
+One way to fix this is to just mask the cs bits to 2 bits. This still
+allows all 4 native chip selects to work as well as gpio chip selects
+(which can use any of the 4 chip select configurations).
+
+Signed-off-by: Kevin Groeneveld <kgroeneveld@lenbrook.com>
+Link: https://lore.kernel.org/r/20230318222132.3373-1-kgroeneveld@lenbrook.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-imx.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
+index fbd7b354dd36b..2c660a95c17e7 100644
+--- a/drivers/spi/spi-imx.c
++++ b/drivers/spi/spi-imx.c
+@@ -253,6 +253,18 @@ static bool spi_imx_can_dma(struct spi_controller *controller, struct spi_device
+ return true;
+ }
+
++/*
++ * Note the number of natively supported chip selects for MX51 is 4. Some
++ * devices may have less actual SS pins but the register map supports 4. When
++ * using gpio chip selects the cs values passed into the macros below can go
++ * outside the range 0 - 3. We therefore need to limit the cs value to avoid
++ * corrupting bits outside the allocated locations.
++ *
++ * The simplest way to do this is to just mask the cs bits to 2 bits. This
++ * still allows all 4 native chip selects to work as well as gpio chip selects
++ * (which can use any of the 4 chip select configurations).
++ */
++
+ #define MX51_ECSPI_CTRL 0x08
+ #define MX51_ECSPI_CTRL_ENABLE (1 << 0)
+ #define MX51_ECSPI_CTRL_XCH (1 << 2)
+@@ -261,16 +273,16 @@ static bool spi_imx_can_dma(struct spi_controller *controller, struct spi_device
+ #define MX51_ECSPI_CTRL_DRCTL(drctl) ((drctl) << 16)
+ #define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8
+ #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12
+-#define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18)
++#define MX51_ECSPI_CTRL_CS(cs) ((cs & 3) << 18)
+ #define MX51_ECSPI_CTRL_BL_OFFSET 20
+ #define MX51_ECSPI_CTRL_BL_MASK (0xfff << 20)
+
+ #define MX51_ECSPI_CONFIG 0x0c
+-#define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0))
+-#define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs) + 4))
+-#define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs) + 8))
+-#define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs) + 12))
+-#define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs) + 20))
++#define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs & 3) + 0))
++#define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs & 3) + 4))
++#define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs & 3) + 8))
++#define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs & 3) + 12))
++#define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs & 3) + 20))
+
+ #define MX51_ECSPI_INT 0x10
+ #define MX51_ECSPI_INT_TEEN (1 << 0)
+--
+2.39.2
+
--- /dev/null
+From 78a036977278537e67a36c900a2cb3c03e53a3f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Mar 2023 01:09:00 +0500
+Subject: staging: axis-fifo: initialize timeouts in init only
+
+From: Khadija Kamran <kamrankhadijadj@gmail.com>
+
+[ Upstream commit 752cbd8f191678e86aa754f795546b7f06b7f171 ]
+
+Initialize the module parameters, read_timeout and write_timeout once in
+init().
+
+Module parameters can only be set once and cannot be modified later, so we
+don't need to evaluate them again when passing the parameters to
+wait_event_interruptible_timeout().
+
+Convert datatype of {read,write}_timeout from 'int' to 'long int' because
+implicit conversion of 'long int' to 'int' in statement
+'{read,write}_timeout = MAX_SCHEDULE_TIMEOUT' results in an overflow.
+
+Change format specifier for {read,write}_timeout from %i to %li.
+
+Reviewed-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
+Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Khadija Kamran <kamrankhadijadj@gmail.com>
+Link: https://lore.kernel.org/r/ZBN3XAsItCiTk7CV@khadija-virtual-machine
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/axis-fifo/axis-fifo.c | 28 ++++++++++++++++-----------
+ 1 file changed, 17 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c
+index dfd2b357f484b..0a85ea667a1b5 100644
+--- a/drivers/staging/axis-fifo/axis-fifo.c
++++ b/drivers/staging/axis-fifo/axis-fifo.c
+@@ -103,17 +103,17 @@
+ * globals
+ * ----------------------------
+ */
+-static int read_timeout = 1000; /* ms to wait before read() times out */
+-static int write_timeout = 1000; /* ms to wait before write() times out */
++static long read_timeout = 1000; /* ms to wait before read() times out */
++static long write_timeout = 1000; /* ms to wait before write() times out */
+
+ /* ----------------------------
+ * module command-line arguments
+ * ----------------------------
+ */
+
+-module_param(read_timeout, int, 0444);
++module_param(read_timeout, long, 0444);
+ MODULE_PARM_DESC(read_timeout, "ms to wait before blocking read() timing out; set to -1 for no timeout");
+-module_param(write_timeout, int, 0444);
++module_param(write_timeout, long, 0444);
+ MODULE_PARM_DESC(write_timeout, "ms to wait before blocking write() timing out; set to -1 for no timeout");
+
+ /* ----------------------------
+@@ -384,9 +384,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
+ mutex_lock(&fifo->read_lock);
+ ret = wait_event_interruptible_timeout(fifo->read_queue,
+ ioread32(fifo->base_addr + XLLF_RDFO_OFFSET),
+- (read_timeout >= 0) ?
+- msecs_to_jiffies(read_timeout) :
+- MAX_SCHEDULE_TIMEOUT);
++ read_timeout);
+
+ if (ret <= 0) {
+ if (ret == 0) {
+@@ -528,9 +526,7 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
+ ret = wait_event_interruptible_timeout(fifo->write_queue,
+ ioread32(fifo->base_addr + XLLF_TDFV_OFFSET)
+ >= words_to_write,
+- (write_timeout >= 0) ?
+- msecs_to_jiffies(write_timeout) :
+- MAX_SCHEDULE_TIMEOUT);
++ write_timeout);
+
+ if (ret <= 0) {
+ if (ret == 0) {
+@@ -948,7 +944,17 @@ static struct platform_driver axis_fifo_driver = {
+
+ static int __init axis_fifo_init(void)
+ {
+- pr_info("axis-fifo driver loaded with parameters read_timeout = %i, write_timeout = %i\n",
++ if (read_timeout >= 0)
++ read_timeout = msecs_to_jiffies(read_timeout);
++ else
++ read_timeout = MAX_SCHEDULE_TIMEOUT;
++
++ if (write_timeout >= 0)
++ write_timeout = msecs_to_jiffies(write_timeout);
++ else
++ write_timeout = MAX_SCHEDULE_TIMEOUT;
++
++ pr_info("axis-fifo driver loaded with parameters read_timeout = %li, write_timeout = %li\n",
+ read_timeout, write_timeout);
+ return platform_driver_register(&axis_fifo_driver);
+ }
+--
+2.39.2
+
--- /dev/null
+From fc0577d5e1effa1afaaf0a2c87ce2079d19587a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Feb 2023 07:47:21 +0100
+Subject: staging: rtl8192e: Replace macro RTL_PCI_DEVICE with PCI_DEVICE
+
+From: Philipp Hortmann <philipp.g.hortmann@gmail.com>
+
+[ Upstream commit fda2093860df4812d69052a8cf4997e53853a340 ]
+
+Replace macro RTL_PCI_DEVICE with PCI_DEVICE to get rid of rtl819xp_ops
+which is empty.
+
+Signed-off-by: Philipp Hortmann <philipp.g.hortmann@gmail.com>
+Link: https://lore.kernel.org/r/8b45ee783fa91196b7c9d6fc840a189496afd2f4.1677133271.git.philipp.g.hortmann@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 6 +++---
+ drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 5 -----
+ 2 files changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
+index c1e50084172d8..7e11364d718bf 100644
+--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
++++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
+@@ -48,9 +48,9 @@ static const struct rtl819x_ops rtl819xp_ops = {
+ };
+
+ static struct pci_device_id rtl8192_pci_id_tbl[] = {
+- {RTL_PCI_DEVICE(0x10ec, 0x8192, rtl819xp_ops)},
+- {RTL_PCI_DEVICE(0x07aa, 0x0044, rtl819xp_ops)},
+- {RTL_PCI_DEVICE(0x07aa, 0x0047, rtl819xp_ops)},
++ {PCI_DEVICE(0x10ec, 0x8192)},
++ {PCI_DEVICE(0x07aa, 0x0044)},
++ {PCI_DEVICE(0x07aa, 0x0047)},
+ {}
+ };
+
+diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h
+index 7021f9c435d96..50f1ec78cc457 100644
+--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h
++++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h
+@@ -55,11 +55,6 @@
+ #define IS_HARDWARE_TYPE_8192SE(_priv) \
+ (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192SE)
+
+-#define RTL_PCI_DEVICE(vend, dev, cfg) \
+- .vendor = (vend), .device = (dev), \
+- .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, \
+- .driver_data = (kernel_ulong_t)&(cfg)
+-
+ #define TOTAL_CAM_ENTRY 32
+ #define CAM_CONTENT_COUNT 8
+
+--
+2.39.2
+
--- /dev/null
+From 3acd1e9209b6361df0328127d2e40f804869f7a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Mar 2023 16:11:49 +0800
+Subject: usb: typec: tcpm: fix multiple times discover svids error
+
+From: Frank Wang <frank.wang@rock-chips.com>
+
+[ Upstream commit dac3b192107b978198e89ec0f77375738352e0c8 ]
+
+PD3.0 Spec 6.4.4.3.2 say that only Responder supports 12 or more SVIDs,
+the Discover SVIDs Command Shall be executed multiple times until a
+Discover SVIDs VDO is returned ending either with a SVID value of
+0x0000 in the last part of the last VDO or with a VDO containing two
+SVIDs with values of 0x0000.
+
+In the current implementation, if the last VDO does not find that the
+Discover SVIDs Command would be executed multiple times even if the
+Responder SVIDs are less than 12, and we found some odd dockers just
+meet this case. So fix it.
+
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
+Link: https://lore.kernel.org/r/20230316081149.24519-1-frank.wang@rock-chips.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
+index 032d21a967799..524099634a1d4 100644
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -1514,7 +1514,21 @@ static bool svdm_consume_svids(struct tcpm_port *port, const u32 *p, int cnt)
+ pmdata->svids[pmdata->nsvids++] = svid;
+ tcpm_log(port, "SVID %d: 0x%x", pmdata->nsvids, svid);
+ }
+- return true;
++
++ /*
++ * PD3.0 Spec 6.4.4.3.2: The SVIDs are returned 2 per VDO (see Table
++ * 6-43), and can be returned maximum 6 VDOs per response (see Figure
++ * 6-19). If the Respondersupports 12 or more SVID then the Discover
++ * SVIDs Command Shall be executed multiple times until a Discover
++ * SVIDs VDO is returned ending either with a SVID value of 0x0000 in
++ * the last part of the last VDO or with a VDO containing two SVIDs
++ * with values of 0x0000.
++ *
++ * However, some odd dockers support SVIDs less than 12 but without
++ * 0x0000 in the last VDO, so we need to break the Discover SVIDs
++ * request and return false here.
++ */
++ return cnt == 7;
+ abort:
+ tcpm_log(port, "SVID_DISCOVERY_MAX(%d) too low!", SVID_DISCOVERY_MAX);
+ return false;
+--
+2.39.2
+
--- /dev/null
+From c15e8b49a14fdcd64a8048f01e8219d93080bdb8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Apr 2023 16:44:56 +0300
+Subject: usb: typec: ucsi: acpi: add quirk for ASUS Zenbook UM325
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Samuel ÄŒavoj <samuel@cavoj.net>
+
+[ Upstream commit 326e1c208f3f24d14b93f910b8ae32c94923d22c ]
+
+On some ACPI platforms (namely the ASUS Zenbook UM325) the _DSM method must
+not be called after a notification is received but instead the mailbox
+should be read immediately from RAM. This is because the ACPI interrupt
+handler destroys the CCI in ERAM after copying to system memory, and when
+_DSM is later called to perform a second copy, it retrieves a garbage
+value.
+
+Instead, the _DSM(read) method should only be called when necessary, i.e.
+for polling the state after reset and for retrieving the version. Other
+reads should not call _DSM and only peek into the RAM region.
+
+This adds a separate read operation for the Zenbook that syncs the
+ACPI mailbox only with polled commands.
+
+Link: https://lore.kernel.org/linux-usb/20210823180626.tb6m7h5tp6adhvt2@fastboi.localdomain/
+Signed-off-by: Samuel ÄŒavoj <samuel@cavoj.net>
+[ heikki : handling everything in ucsi_acpi.c with DMI quirk ]
+Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20230405134456.49607-1-heikki.krogerus@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi_acpi.c | 44 ++++++++++++++++++++++++++++--
+ 1 file changed, 42 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
+index 62206a6b8ea75..217355f1f9b94 100644
+--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
++++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
+@@ -9,6 +9,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/module.h>
+ #include <linux/acpi.h>
++#include <linux/dmi.h>
+
+ #include "ucsi.h"
+
+@@ -23,6 +24,7 @@ struct ucsi_acpi {
+ struct completion complete;
+ unsigned long flags;
+ guid_t guid;
++ u64 cmd;
+ };
+
+ static int ucsi_acpi_dsm(struct ucsi_acpi *ua, int func)
+@@ -62,6 +64,7 @@ static int ucsi_acpi_async_write(struct ucsi *ucsi, unsigned int offset,
+ struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
+
+ memcpy(ua->base + offset, val, val_len);
++ ua->cmd = *(u64 *)val;
+
+ return ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_WRITE);
+ }
+@@ -93,13 +96,46 @@ static const struct ucsi_operations ucsi_acpi_ops = {
+ .async_write = ucsi_acpi_async_write
+ };
+
++static int
++ucsi_zenbook_read(struct ucsi *ucsi, unsigned int offset, void *val, size_t val_len)
++{
++ struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
++ int ret;
++
++ if (offset == UCSI_VERSION || UCSI_COMMAND(ua->cmd) == UCSI_PPM_RESET) {
++ ret = ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_READ);
++ if (ret)
++ return ret;
++ }
++
++ memcpy(val, ua->base + offset, val_len);
++
++ return 0;
++}
++
++static const struct ucsi_operations ucsi_zenbook_ops = {
++ .read = ucsi_zenbook_read,
++ .sync_write = ucsi_acpi_sync_write,
++ .async_write = ucsi_acpi_async_write
++};
++
++static const struct dmi_system_id zenbook_dmi_id[] = {
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"),
++ },
++ },
++ { }
++};
++
+ static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data)
+ {
+ struct ucsi_acpi *ua = data;
+ u32 cci;
+ int ret;
+
+- ret = ucsi_acpi_read(ua->ucsi, UCSI_CCI, &cci, sizeof(cci));
++ ret = ua->ucsi->ops->read(ua->ucsi, UCSI_CCI, &cci, sizeof(cci));
+ if (ret)
+ return;
+
+@@ -114,6 +150,7 @@ static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data)
+ static int ucsi_acpi_probe(struct platform_device *pdev)
+ {
+ struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
++ const struct ucsi_operations *ops = &ucsi_acpi_ops;
+ struct ucsi_acpi *ua;
+ struct resource *res;
+ acpi_status status;
+@@ -143,7 +180,10 @@ static int ucsi_acpi_probe(struct platform_device *pdev)
+ init_completion(&ua->complete);
+ ua->dev = &pdev->dev;
+
+- ua->ucsi = ucsi_create(&pdev->dev, &ucsi_acpi_ops);
++ if (dmi_check_system(zenbook_dmi_id))
++ ops = &ucsi_zenbook_ops;
++
++ ua->ucsi = ucsi_create(&pdev->dev, ops);
+ if (IS_ERR(ua->ucsi))
+ return PTR_ERR(ua->ucsi);
+
+--
+2.39.2
+
--- /dev/null
+From 2c6f8023ac13ac5fd4763b5cc9ae62d901d97727 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 20:31:38 +0200
+Subject: wifi: ath: Silence memcpy run-time false positive warning
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit bfcc8ba45eb87bfaaff900bbad2b87b204899d41 ]
+
+The memcpy() in ath_key_config() was attempting to write across
+neighboring struct members in struct ath_keyval. Introduce a wrapping
+struct_group, kv_values, to be the addressable target of the memcpy
+without overflowing an individual member. Silences the false positive
+run-time warning:
+
+ memcpy: detected field-spanning write (size 32) of single field "hk.kv_val" at drivers/net/wireless/ath/key.c:506 (size 16)
+
+Link: https://bbs.archlinux.org/viewtopic.php?id=282254
+Cc: Kalle Valo <kvalo@kernel.org>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: Paolo Abeni <pabeni@redhat.com>
+Cc: linux-wireless@vger.kernel.org
+Cc: netdev@vger.kernel.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230210054310.never.554-kees@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath.h | 12 +++++++-----
+ drivers/net/wireless/ath/key.c | 2 +-
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
+index f083fb9038c36..f02a308a9ffc5 100644
+--- a/drivers/net/wireless/ath/ath.h
++++ b/drivers/net/wireless/ath/ath.h
+@@ -96,11 +96,13 @@ struct ath_keyval {
+ u8 kv_type;
+ u8 kv_pad;
+ u16 kv_len;
+- u8 kv_val[16]; /* TK */
+- u8 kv_mic[8]; /* Michael MIC key */
+- u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
+- * supports both MIC keys in the same key cache entry;
+- * in that case, kv_mic is the RX key) */
++ struct_group(kv_values,
++ u8 kv_val[16]; /* TK */
++ u8 kv_mic[8]; /* Michael MIC key */
++ u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
++ * supports both MIC keys in the same key cache entry;
++ * in that case, kv_mic is the RX key) */
++ );
+ };
+
+ enum ath_cipher {
+diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c
+index 61b59a804e308..b7b61d4f02bae 100644
+--- a/drivers/net/wireless/ath/key.c
++++ b/drivers/net/wireless/ath/key.c
+@@ -503,7 +503,7 @@ int ath_key_config(struct ath_common *common,
+
+ hk.kv_len = key->keylen;
+ if (key->keylen)
+- memcpy(hk.kv_val, key->key, key->keylen);
++ memcpy(&hk.kv_values, key->key, key->keylen);
+
+ if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+ switch (vif->type) {
+--
+2.39.2
+
--- /dev/null
+From 2eaaae107d0fb4c3354edc7c99c8fe520c366d7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 13:35:02 +0300
+Subject: wifi: ath11k: Fix SKB corruption in REO destination ring
+
+From: Nagarajan Maran <quic_nmaran@quicinc.com>
+
+[ Upstream commit f9fff67d2d7ca6fa8066132003a3deef654c55b1 ]
+
+While running traffics for a long time, randomly an RX descriptor
+filled with value "0" from REO destination ring is received.
+This descriptor which is invalid causes the wrong SKB (SKB stored in
+the IDR lookup with buffer id "0") to be fetched which in turn
+causes SKB memory corruption issue and the same leads to crash
+after some time.
+
+Changed the start id for idr allocation to "1" and the buffer id "0"
+is reserved for error validation. Introduced Sanity check to validate
+the descriptor, before processing the SKB.
+
+Crash Signature :
+
+Unable to handle kernel paging request at virtual address 3f004900
+PC points to "b15_dma_inv_range+0x30/0x50"
+LR points to "dma_cache_maint_page+0x8c/0x128".
+The Backtrace obtained is as follows:
+[<8031716c>] (b15_dma_inv_range) from [<80313a4c>] (dma_cache_maint_page+0x8c/0x128)
+[<80313a4c>] (dma_cache_maint_page) from [<80313b90>] (__dma_page_dev_to_cpu+0x28/0xcc)
+[<80313b90>] (__dma_page_dev_to_cpu) from [<7fb5dd68>] (ath11k_dp_process_rx+0x1e8/0x4a4 [ath11k])
+[<7fb5dd68>] (ath11k_dp_process_rx [ath11k]) from [<7fb53c20>] (ath11k_dp_service_srng+0xb0/0x2ac [ath11k])
+[<7fb53c20>] (ath11k_dp_service_srng [ath11k]) from [<7f67bba4>] (ath11k_pci_ext_grp_napi_poll+0x1c/0x78 [ath11k_pci])
+[<7f67bba4>] (ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<807d5cf4>] (__napi_poll+0x28/0xb8)
+[<807d5cf4>] (__napi_poll) from [<807d5f28>] (net_rx_action+0xf0/0x280)
+[<807d5f28>] (net_rx_action) from [<80302148>] (__do_softirq+0xd0/0x280)
+[<80302148>] (__do_softirq) from [<80320408>] (irq_exit+0x74/0xd4)
+[<80320408>] (irq_exit) from [<803638a4>] (__handle_domain_irq+0x90/0xb4)
+[<803638a4>] (__handle_domain_irq) from [<805bedec>] (gic_handle_irq+0x58/0x90)
+[<805bedec>] (gic_handle_irq) from [<80301a78>] (__irq_svc+0x58/0x8c)
+
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Nagarajan Maran <quic_nmaran@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230403191533.28114-1-quic_nmaran@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/dp_rx.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
+index 1786d83f8f2ed..38be646bc0214 100644
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -389,10 +389,10 @@ int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id,
+ goto fail_free_skb;
+
+ spin_lock_bh(&rx_ring->idr_lock);
+- buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 0,
+- rx_ring->bufs_max * 3, GFP_ATOMIC);
++ buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 1,
++ (rx_ring->bufs_max * 3) + 1, GFP_ATOMIC);
+ spin_unlock_bh(&rx_ring->idr_lock);
+- if (buf_id < 0)
++ if (buf_id <= 0)
+ goto fail_dma_unmap;
+
+ desc = ath11k_hal_srng_src_get_next_entry(ab, srng);
+@@ -2665,6 +2665,9 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
+ cookie);
+ mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
+
++ if (unlikely(buf_id == 0))
++ continue;
++
+ ar = ab->pdevs[mac_id].ar;
+ rx_ring = &ar->dp.rx_refill_buf_ring;
+ spin_lock_bh(&rx_ring->idr_lock);
+--
+2.39.2
+
--- /dev/null
+From 001bcee8d4af8c3aa39c4bcb358fd663c5f33754 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Apr 2023 00:11:54 +0530
+Subject: wifi: ath11k: Ignore frags from uninitialized peer in dp.
+
+From: Harshitha Prem <quic_hprem@quicinc.com>
+
+[ Upstream commit a06bfb3c9f69f303692cdae87bc0899d2ae8b2a6 ]
+
+When max virtual ap interfaces are configured in all the bands with
+ACS and hostapd restart is done every 60s, a crash is observed at
+random times.
+In this certain scenario, a fragmented packet is received for
+self peer, for which rx_tid and rx_frags are not initialized in
+datapath. While handling this fragment, crash is observed as the
+rx_frag list is uninitialised and when we walk in
+ath11k_dp_rx_h_sort_frags, skb null leads to exception.
+
+To address this, before processing received fragments we check
+dp_setup_done flag is set to ensure that peer has completed its
+dp peer setup for fragment queue, else ignore processing the
+fragments.
+
+Call trace:
+ ath11k_dp_process_rx_err+0x550/0x1084 [ath11k]
+ ath11k_dp_service_srng+0x70/0x370 [ath11k]
+ 0xffffffc009693a04
+ __napi_poll+0x30/0xa4
+ net_rx_action+0x118/0x270
+ __do_softirq+0x10c/0x244
+ irq_exit+0x64/0xb4
+ __handle_domain_irq+0x88/0xac
+ gic_handle_irq+0x74/0xbc
+ el1_irq+0xf0/0x1c0
+ arch_cpu_idle+0x10/0x18
+ do_idle+0x104/0x248
+ cpu_startup_entry+0x20/0x64
+ rest_init+0xd0/0xdc
+ arch_call_rest_init+0xc/0x14
+ start_kernel+0x480/0x4b8
+ Code: f9400281 f94066a2 91405021 b94a0023 (f9406401)
+
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Harshitha Prem <quic_hprem@quicinc.com>
+Signed-off-by: Nagarajan Maran <quic_nmaran@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230403184155.8670-2-quic_nmaran@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/dp.c | 4 +++-
+ drivers/net/wireless/ath/ath11k/dp_rx.c | 8 ++++++++
+ drivers/net/wireless/ath/ath11k/peer.h | 1 +
+ 3 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c
+index f5156a7fbdd7a..d070bcb3fe247 100644
+--- a/drivers/net/wireless/ath/ath11k/dp.c
++++ b/drivers/net/wireless/ath/ath11k/dp.c
+@@ -36,6 +36,7 @@ void ath11k_dp_peer_cleanup(struct ath11k *ar, int vdev_id, const u8 *addr)
+ }
+
+ ath11k_peer_rx_tid_cleanup(ar, peer);
++ peer->dp_setup_done = false;
+ crypto_free_shash(peer->tfm_mmic);
+ spin_unlock_bh(&ab->base_lock);
+ }
+@@ -72,7 +73,8 @@ int ath11k_dp_peer_setup(struct ath11k *ar, int vdev_id, const u8 *addr)
+ ret = ath11k_peer_rx_frag_setup(ar, addr, vdev_id);
+ if (ret) {
+ ath11k_warn(ab, "failed to setup rx defrag context\n");
+- return ret;
++ tid--;
++ goto peer_clean;
+ }
+
+ /* TODO: Setup other peer specific resource used in data path */
+diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
+index e964e1b722871..1786d83f8f2ed 100644
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -3138,6 +3138,7 @@ int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id
+ }
+
+ peer->tfm_mmic = tfm;
++ peer->dp_setup_done = true;
+ spin_unlock_bh(&ab->base_lock);
+
+ return 0;
+@@ -3583,6 +3584,13 @@ static int ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar,
+ ret = -ENOENT;
+ goto out_unlock;
+ }
++ if (!peer->dp_setup_done) {
++ ath11k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n",
++ peer->addr, peer_id);
++ ret = -ENOENT;
++ goto out_unlock;
++ }
++
+ rx_tid = &peer->rx_tid[tid];
+
+ if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) ||
+diff --git a/drivers/net/wireless/ath/ath11k/peer.h b/drivers/net/wireless/ath/ath11k/peer.h
+index 6dd17bafe3a0c..9bd385d0a38c9 100644
+--- a/drivers/net/wireless/ath/ath11k/peer.h
++++ b/drivers/net/wireless/ath/ath11k/peer.h
+@@ -35,6 +35,7 @@ struct ath11k_peer {
+ u16 sec_type;
+ u16 sec_type_grp;
+ bool is_authorized;
++ bool dp_setup_done;
+ };
+
+ void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id);
+--
+2.39.2
+
--- /dev/null
+From aa7d0b048706b54b2fbdf45d405f91fb7db50eb1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 18:24:19 +0900
+Subject: wifi: brcmfmac: cfg80211: Pass the PMK in binary instead of hex
+
+From: Hector Martin <marcan@marcan.st>
+
+[ Upstream commit 89b89e52153fda2733562776c7c9d9d3ebf8dd6d ]
+
+Apparently the hex passphrase mechanism does not work on newer
+chips/firmware (e.g. BCM4387). It seems there was a simple way of
+passing it in binary all along, so use that and avoid the hexification.
+
+OpenBSD has been doing it like this from the beginning, so this should
+work on all chips.
+
+Also clear the structure before setting the PMK. This was leaking
+uninitialized stack contents to the device.
+
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Hector Martin <marcan@marcan.st>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230214092423.15175-6-marcan@marcan.st
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+index 2cc913acfc2d7..ad5a8d61d9385 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -1351,13 +1351,14 @@ static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len)
+ {
+ struct brcmf_pub *drvr = ifp->drvr;
+ struct brcmf_wsec_pmk_le pmk;
+- int i, err;
++ int err;
++
++ memset(&pmk, 0, sizeof(pmk));
+
+- /* convert to firmware key format */
+- pmk.key_len = cpu_to_le16(pmk_len << 1);
+- pmk.flags = cpu_to_le16(BRCMF_WSEC_PASSPHRASE);
+- for (i = 0; i < pmk_len; i++)
+- snprintf(&pmk.key[2 * i], 3, "%02x", pmk_data[i]);
++ /* pass pmk directly */
++ pmk.key_len = cpu_to_le16(pmk_len);
++ pmk.flags = cpu_to_le16(0);
++ memcpy(pmk.key, pmk_data, pmk_len);
+
+ /* store psk in firmware */
+ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK,
+--
+2.39.2
+
--- /dev/null
+From 2d80ab6c1a691e60eef55217d1bbd202bdc2b09d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 17:00:34 +0900
+Subject: wifi: brcmfmac: pcie: Provide a buffer of random bytes to the device
+
+From: Hector Martin <marcan@marcan.st>
+
+[ Upstream commit 91918ce88d9fef408bb12c46a27c73d79b604c20 ]
+
+Newer Apple firmwares on chipsets without a hardware RNG require the
+host to provide a buffer of 256 random bytes to the device on
+initialization. This buffer is present immediately before NVRAM,
+suffixed by a footer containing a magic number and the buffer length.
+
+This won't affect chips/firmwares that do not use this feature, so do it
+unconditionally for all Apple platforms (those with an Apple OTP).
+
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Hector Martin <marcan@marcan.st>
+Reviewed-by: Julian Calaby <julian.calaby@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230214080034.3828-3-marcan@marcan.st
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../broadcom/brcm80211/brcmfmac/pcie.c | 32 +++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+index 067ea019b110a..3b1277a8bd617 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -13,6 +13,7 @@
+ #include <linux/bcma/bcma.h>
+ #include <linux/sched.h>
+ #include <linux/io.h>
++#include <linux/random.h>
+ #include <asm/unaligned.h>
+
+ #include <soc.h>
+@@ -1631,6 +1632,13 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
+ return 0;
+ }
+
++struct brcmf_random_seed_footer {
++ __le32 length;
++ __le32 magic;
++};
++
++#define BRCMF_RANDOM_SEED_MAGIC 0xfeedc0de
++#define BRCMF_RANDOM_SEED_LENGTH 0x100
+
+ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
+ const struct firmware *fw, void *nvram,
+@@ -1667,6 +1675,30 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
+ nvram_len;
+ memcpy_toio(devinfo->tcm + address, nvram, nvram_len);
+ brcmf_fw_nvram_free(nvram);
++
++ if (devinfo->otp.valid) {
++ size_t rand_len = BRCMF_RANDOM_SEED_LENGTH;
++ struct brcmf_random_seed_footer footer = {
++ .length = cpu_to_le32(rand_len),
++ .magic = cpu_to_le32(BRCMF_RANDOM_SEED_MAGIC),
++ };
++ void *randbuf;
++
++ /* Some Apple chips/firmwares expect a buffer of random
++ * data to be present before NVRAM
++ */
++ brcmf_dbg(PCIE, "Download random seed\n");
++
++ address -= sizeof(footer);
++ memcpy_toio(devinfo->tcm + address, &footer,
++ sizeof(footer));
++
++ address -= rand_len;
++ randbuf = kzalloc(rand_len, GFP_KERNEL);
++ get_random_bytes(randbuf, rand_len);
++ memcpy_toio(devinfo->tcm + address, randbuf, rand_len);
++ kfree(randbuf);
++ }
+ } else {
+ brcmf_dbg(PCIE, "No matching NVRAM file found %s\n",
+ devinfo->nvram_name);
+--
+2.39.2
+
--- /dev/null
+From fa603f4f7122346671020e8737f8644ec8cdbccc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Apr 2023 13:11:53 +0300
+Subject: wifi: iwlwifi: add a new PCI device ID for BZ device
+
+From: Mukesh Sisodiya <mukesh.sisodiya@intel.com>
+
+[ Upstream commit c30a2a64788b3d617a9c5d96adb76c68b0862e5f ]
+
+Add support for a new PCI device ID 0x272b once registering with PCIe.
+
+Signed-off-by: Mukesh Sisodiya <mukesh.sisodiya@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230414130637.56342664110d.I5aa6f2858fdcf69fdea4f1a873115a48bd43764e@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+index afe6cc15c845f..03e8234d03520 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+@@ -504,6 +504,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
+
+ /* Bz devices */
+ {IWL_PCI_DEVICE(0x2727, PCI_ANY_ID, iwl_bz_trans_cfg)},
++ {IWL_PCI_DEVICE(0x272b, PCI_ANY_ID, iwl_bz_trans_cfg)},
+ {IWL_PCI_DEVICE(0xA840, PCI_ANY_ID, iwl_bz_trans_cfg)},
+ {IWL_PCI_DEVICE(0x7740, PCI_ANY_ID, iwl_bz_trans_cfg)},
+ #endif /* CONFIG_IWLMVM */
+--
+2.39.2
+
--- /dev/null
+From 9dc448910404568d7da11565d9030b2b2e7a258f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Apr 2023 15:25:46 +0200
+Subject: wifi: iwlwifi: dvm: Fix memcpy: detected field-spanning write
+ backtrace
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit ef16799640865f937719f0771c93be5dca18adc6 ]
+
+A received TKIP key may be up to 32 bytes because it may contain
+MIC rx/tx keys too. These are not used by iwl and copying these
+over overflows the iwl_keyinfo.key field.
+
+Add a check to not copy more data to iwl_keyinfo.key then will fit.
+
+This fixes backtraces like this one:
+
+ memcpy: detected field-spanning write (size 32) of single field "sta_cmd.key.key" at drivers/net/wireless/intel/iwlwifi/dvm/sta.c:1103 (size 16)
+ WARNING: CPU: 1 PID: 946 at drivers/net/wireless/intel/iwlwifi/dvm/sta.c:1103 iwlagn_send_sta_key+0x375/0x390 [iwldvm]
+ <snip>
+ Hardware name: Dell Inc. Latitude E6430/0H3MT5, BIOS A21 05/08/2017
+ RIP: 0010:iwlagn_send_sta_key+0x375/0x390 [iwldvm]
+ <snip>
+ Call Trace:
+ <TASK>
+ iwl_set_dynamic_key+0x1f0/0x220 [iwldvm]
+ iwlagn_mac_set_key+0x1e4/0x280 [iwldvm]
+ drv_set_key+0xa4/0x1b0 [mac80211]
+ ieee80211_key_enable_hw_accel+0xa8/0x2d0 [mac80211]
+ ieee80211_key_replace+0x22d/0x8e0 [mac80211]
+ <snip>
+
+Link: https://www.alionet.org/index.php?topic=1469.0
+Link: https://lore.kernel.org/linux-wireless/20230218191056.never.374-kees@kernel.org/
+Link: https://lore.kernel.org/linux-wireless/68760035-7f75-1b23-e355-bfb758a87d83@redhat.com/
+Cc: Kees Cook <keescook@chromium.org>
+Suggested-by: Johannes Berg <johannes@sipsolutions.net>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/dvm/sta.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c
+index cef43cf80620a..8b01ab986cb13 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c
+@@ -1081,6 +1081,7 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv,
+ {
+ __le16 key_flags;
+ struct iwl_addsta_cmd sta_cmd;
++ size_t to_copy;
+ int i;
+
+ spin_lock_bh(&priv->sta_lock);
+@@ -1100,7 +1101,9 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv,
+ sta_cmd.key.tkip_rx_tsc_byte2 = tkip_iv32;
+ for (i = 0; i < 5; i++)
+ sta_cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]);
+- memcpy(sta_cmd.key.key, keyconf->key, keyconf->keylen);
++ /* keyconf may contain MIC rx/tx keys which iwl does not use */
++ to_copy = min_t(size_t, sizeof(sta_cmd.key.key), keyconf->keylen);
++ memcpy(sta_cmd.key.key, keyconf->key, to_copy);
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
+--
+2.39.2
+
--- /dev/null
+From 13c6be5cca1df69dba09e100307a137db9cb06a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 11:41:30 +0300
+Subject: wifi: iwlwifi: fix iwl_mvm_max_amsdu_size() for MLO
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit b2bc600cced23762d4e97db8989b18772145604f ]
+
+For MLO, we cannot use vif->bss_conf.chandef.chan->band, since
+that will lead to a NULL-ptr dereference as bss_conf isn't used.
+However, in case of real MLO, we also need to take both LMACs
+into account if they exist, since the station might be active
+on both LMACs at the same time.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230417113648.3588afc85d79.I11592893bbc191b9548518b8bd782de568a9f848@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 37 +++++++++++++++++++--
+ 1 file changed, 34 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+index ba944175546d4..542cfcad6e0e6 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+@@ -788,10 +788,11 @@ unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm,
+ struct ieee80211_sta *sta, unsigned int tid)
+ {
+ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+- enum nl80211_band band = mvmsta->vif->bss_conf.chandef.chan->band;
+ u8 ac = tid_to_mac80211_ac[tid];
++ enum nl80211_band band;
+ unsigned int txf;
+- int lmac = iwl_mvm_get_lmac_id(mvm->fw, band);
++ unsigned int val;
++ int lmac;
+
+ /* For HE redirect to trigger based fifos */
+ if (sta->deflink.he_cap.has_he && !WARN_ON(!iwl_mvm_has_new_tx_api(mvm)))
+@@ -805,7 +806,37 @@ unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm,
+ * We also want to have the start of the next packet inside the
+ * fifo to be able to send bursts.
+ */
+- return min_t(unsigned int, mvmsta->max_amsdu_len,
++ val = mvmsta->max_amsdu_len;
++
++ if (hweight16(sta->valid_links) <= 1) {
++ if (sta->valid_links) {
++ struct ieee80211_bss_conf *link_conf;
++ unsigned int link = ffs(sta->valid_links) - 1;
++
++ rcu_read_lock();
++ link_conf = rcu_dereference(mvmsta->vif->link_conf[link]);
++ if (WARN_ON(!link_conf))
++ band = NL80211_BAND_2GHZ;
++ else
++ band = link_conf->chandef.chan->band;
++ rcu_read_unlock();
++ } else {
++ band = mvmsta->vif->bss_conf.chandef.chan->band;
++ }
++
++ lmac = iwl_mvm_get_lmac_id(mvm->fw, band);
++ } else if (fw_has_capa(&mvm->fw->ucode_capa,
++ IWL_UCODE_TLV_CAPA_CDB_SUPPORT)) {
++ /* for real MLO restrict to both LMACs if they exist */
++ lmac = IWL_LMAC_5G_INDEX;
++ val = min_t(unsigned int, val,
++ mvm->fwrt.smem_cfg.lmac[lmac].txfifo_size[txf] - 256);
++ lmac = IWL_LMAC_24G_INDEX;
++ } else {
++ lmac = IWL_LMAC_24G_INDEX;
++ }
++
++ return min_t(unsigned int, val,
+ mvm->fwrt.smem_cfg.lmac[lmac].txfifo_size[txf] - 256);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From cf6ea0d3cda383190e63bc9a9a494129f6dddafc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Apr 2023 13:12:02 +0300
+Subject: wifi: iwlwifi: mvm: fix ptk_pn memory leak
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit d066a530af8e1833c7ea2cef7784004700c85f79 ]
+
+If adding a key to firmware fails we leak the allocated ptk_pn.
+This shouldn't happen in practice, but we should still fix it.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230414130637.99446ffd02bc.I82a2ad6ec1395f188e0a1677cc619e3fcb1feac9@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+index a841268e0709f..801098c5183b6 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -3445,7 +3445,7 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ struct iwl_mvm_sta *mvmsta = NULL;
+- struct iwl_mvm_key_pn *ptk_pn;
++ struct iwl_mvm_key_pn *ptk_pn = NULL;
+ int keyidx = key->keyidx;
+ int ret, i;
+ u8 key_offset;
+@@ -3590,6 +3590,10 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
+ if (ret) {
+ IWL_WARN(mvm, "set key failed\n");
+ key->hw_key_idx = STA_KEY_IDX_INVALID;
++ if (ptk_pn) {
++ RCU_INIT_POINTER(mvmsta->ptk_pn[keyidx], NULL);
++ kfree(ptk_pn);
++ }
+ /*
+ * can't add key for RX, but we don't need it
+ * in the device for TX so still return 0,
+--
+2.39.2
+
--- /dev/null
+From e226a3ee3f6a0e8c437091d334a6fe4ad5d5dbab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Apr 2023 13:11:59 +0300
+Subject: wifi: iwlwifi: pcie: Fix integer overflow in iwl_write_to_user_buf
+
+From: Hyunwoo Kim <imv4bel@gmail.com>
+
+[ Upstream commit 58d1b717879bfeabe09b35e41ad667c79933eb2e ]
+
+An integer overflow occurs in the iwl_write_to_user_buf() function,
+which is called by the iwl_dbgfs_monitor_data_read() function.
+
+static bool iwl_write_to_user_buf(char __user *user_buf, ssize_t count,
+ void *buf, ssize_t *size,
+ ssize_t *bytes_copied)
+{
+ int buf_size_left = count - *bytes_copied;
+
+ buf_size_left = buf_size_left - (buf_size_left % sizeof(u32));
+ if (*size > buf_size_left)
+ *size = buf_size_left;
+
+If the user passes a SIZE_MAX value to the "ssize_t count" parameter,
+the ssize_t count parameter is assigned to "int buf_size_left".
+Then compare "*size" with "buf_size_left" . Here, "buf_size_left" is a
+negative number, so "*size" is assigned "buf_size_left" and goes into
+the third argument of the copy_to_user function, causing a heap overflow.
+
+This is not a security vulnerability because iwl_dbgfs_monitor_data_read()
+is a debugfs operation with 0400 privileges.
+
+Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230414130637.2d80ace81532.Iecfba549e0e0be21bbb0324675392e42e75bd5ad@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+index 54f11f60f11c4..8e95225cdd605 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+@@ -2852,7 +2852,7 @@ static bool iwl_write_to_user_buf(char __user *user_buf, ssize_t count,
+ void *buf, ssize_t *size,
+ ssize_t *bytes_copied)
+ {
+- int buf_size_left = count - *bytes_copied;
++ ssize_t buf_size_left = count - *bytes_copied;
+
+ buf_size_left = buf_size_left - (buf_size_left % sizeof(u32));
+ if (*size > buf_size_left)
+--
+2.39.2
+
--- /dev/null
+From 149c4ef43bf5b070ef76fa208d9c687bc53d15ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Apr 2023 21:40:32 +0300
+Subject: wifi: iwlwifi: pcie: fix possible NULL pointer dereference
+
+From: Daniel Gabay <daniel.gabay@intel.com>
+
+[ Upstream commit b655b9a9f8467684cfa8906713d33b71ea8c8f54 ]
+
+It is possible that iwl_pci_probe() will fail and free the trans,
+then afterwards iwl_pci_remove() will be called and crash by trying
+to access trans which is already freed, fix it.
+
+iwlwifi 0000:01:00.0: Detected crf-id 0xa5a5a5a2, cnv-id 0xa5a5a5a2
+ wfpm id 0xa5a5a5a2
+iwlwifi 0000:01:00.0: Can't find a correct rfid for crf id 0x5a2
+...
+BUG: kernel NULL pointer dereference, address: 0000000000000028
+...
+RIP: 0010:iwl_pci_remove+0x12/0x30 [iwlwifi]
+pci_device_remove+0x3e/0xb0
+device_release_driver_internal+0x103/0x1f0
+driver_detach+0x4c/0x90
+bus_remove_driver+0x5c/0xd0
+driver_unregister+0x31/0x50
+pci_unregister_driver+0x40/0x90
+iwl_pci_unregister_driver+0x15/0x20 [iwlwifi]
+__exit_compat+0x9/0x98 [iwlwifi]
+__x64_sys_delete_module+0x147/0x260
+
+Signed-off-by: Daniel Gabay <daniel.gabay@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230413213309.082f6e21341b.I0db21d7fa9a828d571ca886713bd0b5d0b6e1e5c@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+index 85fadd1ef1ff3..afe6cc15c845f 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+@@ -1685,6 +1685,9 @@ static void iwl_pci_remove(struct pci_dev *pdev)
+ {
+ struct iwl_trans *trans = pci_get_drvdata(pdev);
+
++ if (!trans)
++ return;
++
+ iwl_drv_stop(trans->drv);
+
+ iwl_trans_pcie_free(trans);
+--
+2.39.2
+