--- /dev/null
+From e985f769632f470f2e7a6924ffc3bbfde9e19b7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Mar 2023 17:45:58 +0200
+Subject: accel/habanalabs: postpone mem_mgr IDR destruction to hpriv_release()
+
+From: Tomer Tayar <ttayar@habana.ai>
+
+[ Upstream commit 2e8e9a895c4589f124a37fc84d123b5114406e94 ]
+
+The memory manager IDR is currently destroyed when user releases the
+file descriptor.
+However, at this point the user context might be still held, and memory
+buffers might be still in use.
+Later on, calls to release those buffers will fail due to not finding
+their handles in the IDR, leading to a memory leak.
+To avoid this leak, split the IDR destruction from the memory manager
+fini, and postpone it to hpriv_release() when there is no user context
+and no buffers are used.
+
+Signed-off-by: Tomer Tayar <ttayar@habana.ai>
+Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
+Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/habanalabs/common/device.c | 9 +++++++++
+ drivers/accel/habanalabs/common/habanalabs.h | 1 +
+ drivers/accel/habanalabs/common/habanalabs_drv.c | 1 +
+ drivers/accel/habanalabs/common/memory_mgr.c | 13 ++++++++++++-
+ 4 files changed, 23 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/accel/habanalabs/common/device.c b/drivers/accel/habanalabs/common/device.c
+index 9933e5858a363..c91436609f080 100644
+--- a/drivers/accel/habanalabs/common/device.c
++++ b/drivers/accel/habanalabs/common/device.c
+@@ -423,6 +423,9 @@ static void hpriv_release(struct kref *ref)
+ mutex_destroy(&hpriv->ctx_lock);
+ mutex_destroy(&hpriv->restore_phase_mutex);
+
++ /* There should be no memory buffers at this point and handles IDR can be destroyed */
++ hl_mem_mgr_idr_destroy(&hpriv->mem_mgr);
++
+ /* Device should be reset if reset-upon-device-release is enabled, or if there is a pending
+ * reset that waits for device release.
+ */
+@@ -514,6 +517,10 @@ static int hl_device_release(struct inode *inode, struct file *filp)
+ }
+
+ hl_ctx_mgr_fini(hdev, &hpriv->ctx_mgr);
++
++ /* Memory buffers might be still in use at this point and thus the handles IDR destruction
++ * is postponed to hpriv_release().
++ */
+ hl_mem_mgr_fini(&hpriv->mem_mgr);
+
+ hdev->compute_ctx_in_release = 1;
+@@ -887,6 +894,7 @@ static int device_early_init(struct hl_device *hdev)
+
+ free_cb_mgr:
+ hl_mem_mgr_fini(&hdev->kernel_mem_mgr);
++ hl_mem_mgr_idr_destroy(&hdev->kernel_mem_mgr);
+ free_chip_info:
+ kfree(hdev->hl_chip_info);
+ free_prefetch_wq:
+@@ -930,6 +938,7 @@ static void device_early_fini(struct hl_device *hdev)
+ mutex_destroy(&hdev->clk_throttling.lock);
+
+ hl_mem_mgr_fini(&hdev->kernel_mem_mgr);
++ hl_mem_mgr_idr_destroy(&hdev->kernel_mem_mgr);
+
+ kfree(hdev->hl_chip_info);
+
+diff --git a/drivers/accel/habanalabs/common/habanalabs.h b/drivers/accel/habanalabs/common/habanalabs.h
+index fa05e76d3d21a..829b30ab1961a 100644
+--- a/drivers/accel/habanalabs/common/habanalabs.h
++++ b/drivers/accel/habanalabs/common/habanalabs.h
+@@ -3861,6 +3861,7 @@ const char *hl_sync_engine_to_string(enum hl_sync_engine_type engine_type);
+
+ void hl_mem_mgr_init(struct device *dev, struct hl_mem_mgr *mmg);
+ void hl_mem_mgr_fini(struct hl_mem_mgr *mmg);
++void hl_mem_mgr_idr_destroy(struct hl_mem_mgr *mmg);
+ int hl_mem_mgr_mmap(struct hl_mem_mgr *mmg, struct vm_area_struct *vma,
+ void *args);
+ struct hl_mmap_mem_buf *hl_mmap_mem_buf_get(struct hl_mem_mgr *mmg,
+diff --git a/drivers/accel/habanalabs/common/habanalabs_drv.c b/drivers/accel/habanalabs/common/habanalabs_drv.c
+index 03dae57dc8386..e3781cfe8a7fe 100644
+--- a/drivers/accel/habanalabs/common/habanalabs_drv.c
++++ b/drivers/accel/habanalabs/common/habanalabs_drv.c
+@@ -237,6 +237,7 @@ int hl_device_open(struct inode *inode, struct file *filp)
+ out_err:
+ mutex_unlock(&hdev->fpriv_list_lock);
+ hl_mem_mgr_fini(&hpriv->mem_mgr);
++ hl_mem_mgr_idr_destroy(&hpriv->mem_mgr);
+ hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr);
+ filp->private_data = NULL;
+ mutex_destroy(&hpriv->ctx_lock);
+diff --git a/drivers/accel/habanalabs/common/memory_mgr.c b/drivers/accel/habanalabs/common/memory_mgr.c
+index 0f2759e265477..f8e8261cc83d8 100644
+--- a/drivers/accel/habanalabs/common/memory_mgr.c
++++ b/drivers/accel/habanalabs/common/memory_mgr.c
+@@ -341,8 +341,19 @@ void hl_mem_mgr_fini(struct hl_mem_mgr *mmg)
+ "%s: Buff handle %u for CTX is still alive\n",
+ topic, id);
+ }
++}
+
+- /* TODO: can it happen that some buffer is still in use at this point? */
++/**
++ * hl_mem_mgr_idr_destroy() - destroy memory manager IDR.
++ * @mmg: parent unified memory manager
++ *
++ * Destroy the memory manager IDR.
++ * Shall be called when IDR is empty and no memory buffers are in use.
++ */
++void hl_mem_mgr_idr_destroy(struct hl_mem_mgr *mmg)
++{
++ if (!idr_is_empty(&mmg->handles))
++ dev_crit(mmg->dev, "memory manager IDR is destroyed while it is not empty!\n");
+
+ idr_destroy(&mmg->handles);
+ }
+--
+2.39.2
+
--- /dev/null
+From dd060419f3a5e6015c6d60f2b83fc8547d9cfbac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Apr 2023 14:15:45 +0200
+Subject: accel/ivpu: Remove D3hot delay for Meteorlake
+
+From: Karol Wachowski <karol.wachowski@linux.intel.com>
+
+[ Upstream commit cb949ce504e829193234e26cb3042bb448465d52 ]
+
+VPU on MTL has hardware optimizations and does not require 10ms
+D0 - D3hot transition delay imposed by PCI specification (PCIe
+r6.0, sec 5.9.) .
+
+The delay removal is traditionally done by adding PCI ID to
+quirk_remove_d3hot_delay() in drivers/pci/quirks.c . But since
+we do not need that optimization before driver probe and we
+can better specify in the ivpu driver on what (future) hardware
+use the optimization, we do not use quirk_remove_d3hot_delay()
+for that.
+
+Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
+Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
+Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230403121545.2995279-1-stanislaw.gruszka@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/ivpu/ivpu_drv.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c
+index 6a320a73e3ccf..8396db2b52030 100644
+--- a/drivers/accel/ivpu/ivpu_drv.c
++++ b/drivers/accel/ivpu/ivpu_drv.c
+@@ -437,6 +437,10 @@ static int ivpu_pci_init(struct ivpu_device *vdev)
+ /* Clear any pending errors */
+ pcie_capability_clear_word(pdev, PCI_EXP_DEVSTA, 0x3f);
+
++ /* VPU MTL does not require PCI spec 10m D3hot delay */
++ if (ivpu_is_mtl(vdev))
++ pdev->d3hot_delay = 0;
++
+ ret = pcim_enable_device(pdev);
+ if (ret) {
+ ivpu_err(vdev, "Failed to enable PCI device: %d\n", ret);
+--
+2.39.2
+
--- /dev/null
+From 7247eba99457f386bdab76189bd2676a995d4763 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 105d2e795afad..9658e348dc17d 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -1122,6 +1122,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 a93f4f8709674e13efa56037afd685cb3d2d01ea 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 da5064a845f3ed9b865efc63be59b6cfb65799bc 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 295744fe7c920..bcc25d457581d 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,
+@@ -754,35 +748,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 9713b253e4ec4d4b190da1d7b661032aa99a470f 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 2c7295bc7b4b48465a1409e719c8e77989e662f9 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 a055736fbe3aadeaf8887e4c2a774e85458b6b93 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 754725004359351c781fc0d1d146e567b8682e1d 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 6895bcc121651..de0dde01fd5c4 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 507f4da3b9411ef4b52639ffb0e7d1b6b3bde47a 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 66af9526c98ba..73da1a4d52462 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -3006,8 +3006,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 1c2c2a0c90f06620e3e9861ba181bc21bfc3e13e 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 1b7fdbae6a2b5..56f2d855df78d 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+@@ -712,7 +712,5 @@
+ 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 dff517424f1a2d0e9d4f7fd02079d2f1264469ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Apr 2023 21:54:41 +0200
+Subject: arm64: dts: qcom: sm6115-j606f: Add ramoops node
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 8b0ac59c2da69aaf8e65c6bd648a06b755975302 ]
+
+Add a ramoops node to enable retrieving crash logs.
+
+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-lenovo_features-v2-1-625d7cb4a944@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts b/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts
+index 4ce2d905d70e1..42d89bab5d04b 100644
+--- a/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts
++++ b/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts
+@@ -52,6 +52,17 @@
+ gpio-key,wakeup;
+ };
+ };
++
++ reserved-memory {
++ ramoops@ffc00000 {
++ compatible = "ramoops";
++ reg = <0x0 0xffc00000 0x0 0x100000>;
++ record-size = <0x1000>;
++ console-size = <0x40000>;
++ ftrace-size = <0x20000>;
++ ecc-size = <16>;
++ };
++ };
+ };
+
+ &dispcc {
+--
+2.39.2
+
--- /dev/null
+From 186c9a79c7d5f212e3cf86c850eff5b5cbf69279 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Apr 2023 14:46:16 +0530
+Subject: ASoC: amd: Add check for acp config flags
+
+From: Syed Saba Kareem <Syed.SabaKareem@amd.com>
+
+[ Upstream commit bddcfb0802eb69b0f51293eab5db33d344c0262f ]
+
+We have SOF and generic ACP support enabled for Rembrandt and
+pheonix platforms on some machines. Since we have same PCI id
+used for probing, add check for machine configuration flag to
+avoid conflict with newer pci drivers. Such machine flag has
+been initialized via dmi match on few Chrome machines. If no
+flag is specified probe and register older platform device.
+
+Signed-off-by: Syed Saba Kareem <Syed.SabaKareem@amd.com>
+Reviewed-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Link: https://lore.kernel.org/r/20230412091638.1158901-1-Syed.SabaKareem@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/Kconfig | 2 ++
+ sound/soc/amd/ps/acp63.h | 2 ++
+ sound/soc/amd/ps/pci-ps.c | 8 +++++++-
+ sound/soc/amd/yc/acp6x.h | 3 +++
+ sound/soc/amd/yc/pci-acp6x.c | 8 +++++++-
+ 5 files changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig
+index c88ebd84bdd50..08e42082f5e96 100644
+--- a/sound/soc/amd/Kconfig
++++ b/sound/soc/amd/Kconfig
+@@ -90,6 +90,7 @@ config SND_SOC_AMD_VANGOGH_MACH
+
+ config SND_SOC_AMD_ACP6x
+ tristate "AMD Audio Coprocessor-v6.x Yellow Carp support"
++ select SND_AMD_ACP_CONFIG
+ depends on X86 && PCI
+ help
+ This option enables Audio Coprocessor i.e ACP v6.x support on
+@@ -130,6 +131,7 @@ config SND_SOC_AMD_RPL_ACP6x
+
+ config SND_SOC_AMD_PS
+ tristate "AMD Audio Coprocessor-v6.3 Pink Sardine support"
++ select SND_AMD_ACP_CONFIG
+ depends on X86 && PCI && ACPI
+ help
+ This option enables Audio Coprocessor i.e ACP v6.3 support on
+diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h
+index 6bf29b520511d..dd36790b25aef 100644
+--- a/sound/soc/amd/ps/acp63.h
++++ b/sound/soc/amd/ps/acp63.h
+@@ -111,3 +111,5 @@ struct acp63_dev_data {
+ u16 pdev_count;
+ u16 pdm_dev_index;
+ };
++
++int snd_amd_acp_find_config(struct pci_dev *pci);
+diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
+index 688a1d4643d91..afddb9a77ba49 100644
+--- a/sound/soc/amd/ps/pci-ps.c
++++ b/sound/soc/amd/ps/pci-ps.c
+@@ -247,11 +247,17 @@ static int snd_acp63_probe(struct pci_dev *pci,
+ {
+ struct acp63_dev_data *adata;
+ u32 addr;
+- u32 irqflags;
++ u32 irqflags, flag;
+ int val;
+ int ret;
+
+ irqflags = IRQF_SHARED;
++
++ /* Return if acp config flag is defined */
++ flag = snd_amd_acp_find_config(pci);
++ if (flag)
++ return -ENODEV;
++
+ /* Pink Sardine device check */
+ switch (pci->revision) {
+ case 0x63:
+diff --git a/sound/soc/amd/yc/acp6x.h b/sound/soc/amd/yc/acp6x.h
+index 036207568c048..2de7d1edf00b7 100644
+--- a/sound/soc/amd/yc/acp6x.h
++++ b/sound/soc/amd/yc/acp6x.h
+@@ -105,3 +105,6 @@ static inline void acp6x_writel(u32 val, void __iomem *base_addr)
+ {
+ writel(val, base_addr - ACP6x_PHY_BASE_ADDRESS);
+ }
++
++int snd_amd_acp_find_config(struct pci_dev *pci);
++
+diff --git a/sound/soc/amd/yc/pci-acp6x.c b/sound/soc/amd/yc/pci-acp6x.c
+index 77c5fa1f7af14..7af6a349b1d41 100644
+--- a/sound/soc/amd/yc/pci-acp6x.c
++++ b/sound/soc/amd/yc/pci-acp6x.c
+@@ -149,10 +149,16 @@ static int snd_acp6x_probe(struct pci_dev *pci,
+ int index = 0;
+ int val = 0x00;
+ u32 addr;
+- unsigned int irqflags;
++ unsigned int irqflags, flag;
+ int ret;
+
+ irqflags = IRQF_SHARED;
++
++ /* Return if acp config flag is defined */
++ flag = snd_amd_acp_find_config(pci);
++ if (flag)
++ return -ENODEV;
++
+ /* Yellow Carp device check */
+ switch (pci->revision) {
+ case 0x60:
+--
+2.39.2
+
--- /dev/null
+From 170aa65b350045643c79259ce3b6b6a7f3b6733e 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 ebdc1721ffb09ea60f338d1d46971bea4ed19c33 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 f2c79db7a804c5d9d8d5f28e1a8bd8eff1c94bea 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 b8df6d43603f7fa9245bf61608f23fb147b1f60b 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 d9ed3108c17af..bac977da4eb5b 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -649,6 +649,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 9a4c3f46e7754ff092f92bdb27bc0300f1d964ab 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 400f8a7d0c3fe..997107bfc0b12 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 e87c928c9e17a..51f13518dba9b 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -886,8 +886,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 2348a75f53ce2663ab0d09fd18106c7e7d59aadd 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 1ab5663b009d8..0923582299f3a 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4106,6 +4106,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 997107bfc0b12..07df96c47ef4f 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 632be12672887..b65ee3a32e5d7 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -4093,7 +4093,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,
+@@ -4533,6 +4534,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 479eb5ecb0beec65da1ffff67d12c1ade2a424c1 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 af774688f1c0d..7a6dc05553f13 100644
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -2684,9 +2684,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 9ad9190650cce9e8e568ad7ed0825fb7d1cb5a7d 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 69c3fe649ca7d..44b672cca69ee 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");
+@@ -795,6 +888,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);
+
+@@ -953,6 +1059,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 ebf0101c959b0..349d72ee571b6 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 45c4ea0e964deb1b15be7278e506d47fb63bf4d7 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 7061621faeb0c..4fbb282cac4b5 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);
+
+@@ -1082,3 +1095,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 5ca4bfada81d6229b5c33d683d4164f823b0788e 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 44b672cca69ee..7061621faeb0c 100644
+--- a/drivers/bluetooth/btrtl.c
++++ b/drivers/bluetooth/btrtl.c
+@@ -889,6 +889,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 e14ef5308aeae8738362a5c6cedac75647addda5 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 5c536151ef836..683556dcdc436 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -558,6 +558,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 6793c4c79dc7b459cbd2254a9405eb9238a426b5 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 54ead500d0cfb719856051d8b10e7a16c769e6f7 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 683556dcdc436..1ab5663b009d8 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -4105,6 +4105,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 6dbaa99e470011bbb27d599efb3a66dcda2b98ea 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 55a7226233f96..24d075282996c 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 caf69a45bcfc2589696dc3c6bd1d69ce4009554d 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 6bd18eb5137f4..2dd8ee4a6f75b 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+@@ -2864,7 +2864,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 bb6cc50197f879943b094e714221b7d04fe7bb28 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 64600acbb4e76..f4b267082cbf9 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -17579,6 +17579,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 bool can_be_sleepable(struct bpf_prog *prog)
+--
+2.39.2
+
--- /dev/null
+From 82cc94724e3cdc44f201b0cd1e09543f531ea64c 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 35f4138a54dc1..58da17ae51241 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);
+@@ -174,7 +184,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;
+
+@@ -208,7 +218,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;
+
+@@ -420,7 +430,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 75d024a4dfb11aa44a9887e7f2bbf310aac689b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Apr 2023 22:01:31 -0500
+Subject: cifs: missing lock when updating session status
+
+From: Steve French <stfrench@microsoft.com>
+
+[ Upstream commit 943fb67b090212f1d3789eb7796b1c9045c62fd6 ]
+
+Coverity noted a place where we were not grabbing
+the ses_lock when setting (and checking) ses_status.
+
+Addresses-Coverity: 1536833 ("Data race condition (MISSING_LOCK)")
+Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Reviewed-by: Bharath SM <bharathsm@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/connect.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 59a10330e299b..8e9a672320ab7 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -1918,18 +1918,22 @@ void __cifs_put_smb_ses(struct cifs_ses *ses)
+ /* ses_count can never go negative */
+ WARN_ON(ses->ses_count < 0);
+
++ spin_lock(&ses->ses_lock);
+ if (ses->ses_status == SES_GOOD)
+ ses->ses_status = SES_EXITING;
+
+- cifs_free_ipc(ses);
+-
+ if (ses->ses_status == SES_EXITING && server->ops->logoff) {
++ spin_unlock(&ses->ses_lock);
++ cifs_free_ipc(ses);
+ xid = get_xid();
+ rc = server->ops->logoff(xid, ses);
+ if (rc)
+ cifs_server_dbg(VFS, "%s: Session Logoff failure rc=%d\n",
+ __func__, rc);
+ _free_xid(xid);
++ } else {
++ spin_unlock(&ses->ses_lock);
++ cifs_free_ipc(ses);
+ }
+
+ spin_lock(&cifs_tcp_ses_lock);
+--
+2.39.2
+
--- /dev/null
+From f337b8702a1398846016b2c88bd7e74fd871c555 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Apr 2023 21:32:49 +0200
+Subject: clk: rockchip: rk3588: make gate linked clocks critical
+
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+
+[ Upstream commit 64042c28c3bb6729df8e2fda89bc7ebbe3790907 ]
+
+RK3588 has a couple of hardware blocks called Native Interface Unit
+(NIU) that gate the clocks to devices behind them. Effectively this
+means that some clocks require two parent clocks being enabled.
+Downstream implemented this by using a separate clock driver
+("clk-link") for them, which enables the second clock using PM
+framework.
+
+In the upstream kernel we are currently missing support for the second
+parent. The information about it is in the GATE_LINK() macro as
+linkname, but that is not used. Thus the second parent clock is not
+properly enabled. So far this did not really matter, since these clocks
+are mostly required for the more advanced IP blocks, that are not yet
+supported upstream. As this is about to change we need a fix. There
+are three options available:
+
+1. Properly implement support for having two parent clocks in the
+ clock framework.
+2. Mark the affected clocks CLK_IGNORE_UNUSED, so that they are not
+ disabled. This wastes some power, but keeps the hack contained
+ within the clock driver. Going from this to the first solution
+ is easy once that has been implemented.
+3. Enabling the extra clock in the consumer driver. This leaks some
+ implementation details into DT.
+
+This patch implements the second option as an intermediate solution
+until the first one is available. I used an alias for CLK_IS_CRITICAL,
+so that it's easy to see which clocks are not really critical once
+the clock framework supports a better way to implement this.
+
+Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20230403193250.108693-2-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/rockchip/clk-rk3588.c | 42 +++++++++++++++++++------------
+ 1 file changed, 26 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c
+index b7ce3fbd6fa6a..6994165e03957 100644
+--- a/drivers/clk/rockchip/clk-rk3588.c
++++ b/drivers/clk/rockchip/clk-rk3588.c
+@@ -13,15 +13,25 @@
+ #include "clk.h"
+
+ /*
+- * GATE with additional linked clock. Downstream enables the linked clock
+- * (via runtime PM) whenever the gate is enabled. The downstream implementation
+- * does this via separate clock nodes for each of the linked gate clocks,
+- * which leaks parts of the clock tree into DT. It is unclear why this is
+- * actually needed and things work without it for simple use cases. Thus
+- * the linked clock is ignored for now.
++ * Recent Rockchip SoCs have a new hardware block called Native Interface
++ * Unit (NIU), which gates clocks to devices behind them. These effectively
++ * need two parent clocks.
++ *
++ * Downstream enables the linked clock via runtime PM whenever the gate is
++ * enabled. This implementation uses separate clock nodes for each of the
++ * linked gate clocks, which leaks parts of the clock tree into DT.
++ *
++ * The GATE_LINK macro instead takes the second parent via 'linkname', but
++ * ignores the information. Once the clock framework is ready to handle it, the
++ * information should be passed on here. But since these clocks are required to
++ * access multiple relevant IP blocks, such as PCIe or USB, we mark all linked
++ * clocks critical until a better solution is available. This will waste some
++ * power, but avoids leaking implementation details into DT or hanging the
++ * system.
+ */
+ #define GATE_LINK(_id, cname, pname, linkname, f, o, b, gf) \
+ GATE(_id, cname, pname, f, o, b, gf)
++#define RK3588_LINKED_CLK CLK_IS_CRITICAL
+
+
+ #define RK3588_GRF_SOC_STATUS0 0x600
+@@ -1446,7 +1456,7 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
+ COMPOSITE_NODIV(HCLK_NVM_ROOT, "hclk_nvm_root", mux_200m_100m_50m_24m_p, 0,
+ RK3588_CLKSEL_CON(77), 0, 2, MFLAGS,
+ RK3588_CLKGATE_CON(31), 0, GFLAGS),
+- COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, 0,
++ COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, RK3588_LINKED_CLK,
+ RK3588_CLKSEL_CON(77), 7, 1, MFLAGS, 2, 5, DFLAGS,
+ RK3588_CLKGATE_CON(31), 1, GFLAGS),
+ GATE(ACLK_EMMC, "aclk_emmc", "aclk_nvm_root", 0,
+@@ -1675,13 +1685,13 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
+ RK3588_CLKGATE_CON(42), 9, GFLAGS),
+
+ /* vdpu */
+- COMPOSITE(ACLK_VDPU_ROOT, "aclk_vdpu_root", gpll_cpll_aupll_p, 0,
++ COMPOSITE(ACLK_VDPU_ROOT, "aclk_vdpu_root", gpll_cpll_aupll_p, RK3588_LINKED_CLK,
+ RK3588_CLKSEL_CON(98), 5, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3588_CLKGATE_CON(44), 0, GFLAGS),
+ COMPOSITE_NODIV(ACLK_VDPU_LOW_ROOT, "aclk_vdpu_low_root", mux_400m_200m_100m_24m_p, 0,
+ RK3588_CLKSEL_CON(98), 7, 2, MFLAGS,
+ RK3588_CLKGATE_CON(44), 1, GFLAGS),
+- COMPOSITE_NODIV(HCLK_VDPU_ROOT, "hclk_vdpu_root", mux_200m_100m_50m_24m_p, 0,
++ COMPOSITE_NODIV(HCLK_VDPU_ROOT, "hclk_vdpu_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK,
+ RK3588_CLKSEL_CON(98), 9, 2, MFLAGS,
+ RK3588_CLKGATE_CON(44), 2, GFLAGS),
+ COMPOSITE(ACLK_JPEG_DECODER_ROOT, "aclk_jpeg_decoder_root", gpll_cpll_aupll_spll_p, 0,
+@@ -1732,9 +1742,9 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
+ COMPOSITE(ACLK_RKVENC0_ROOT, "aclk_rkvenc0_root", gpll_cpll_npll_p, 0,
+ RK3588_CLKSEL_CON(102), 7, 2, MFLAGS, 2, 5, DFLAGS,
+ RK3588_CLKGATE_CON(47), 1, GFLAGS),
+- GATE(HCLK_RKVENC0, "hclk_rkvenc0", "hclk_rkvenc0_root", 0,
++ GATE(HCLK_RKVENC0, "hclk_rkvenc0", "hclk_rkvenc0_root", RK3588_LINKED_CLK,
+ RK3588_CLKGATE_CON(47), 4, GFLAGS),
+- GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", 0,
++ GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", RK3588_LINKED_CLK,
+ RK3588_CLKGATE_CON(47), 5, GFLAGS),
+ COMPOSITE(CLK_RKVENC0_CORE, "clk_rkvenc0_core", gpll_cpll_aupll_npll_p, 0,
+ RK3588_CLKSEL_CON(102), 14, 2, MFLAGS, 9, 5, DFLAGS,
+@@ -1744,10 +1754,10 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
+ RK3588_CLKGATE_CON(48), 6, GFLAGS),
+
+ /* vi */
+- COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_cpll_npll_aupll_spll_p, 0,
++ COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_cpll_npll_aupll_spll_p, RK3588_LINKED_CLK,
+ RK3588_CLKSEL_CON(106), 5, 3, MFLAGS, 0, 5, DFLAGS,
+ RK3588_CLKGATE_CON(49), 0, GFLAGS),
+- COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", mux_200m_100m_50m_24m_p, 0,
++ COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK,
+ RK3588_CLKSEL_CON(106), 8, 2, MFLAGS,
+ RK3588_CLKGATE_CON(49), 1, GFLAGS),
+ COMPOSITE_NODIV(PCLK_VI_ROOT, "pclk_vi_root", mux_100m_50m_24m_p, 0,
+@@ -1919,10 +1929,10 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
+ COMPOSITE(ACLK_VOP_ROOT, "aclk_vop_root", gpll_cpll_dmyaupll_npll_spll_p, 0,
+ RK3588_CLKSEL_CON(110), 5, 3, MFLAGS, 0, 5, DFLAGS,
+ RK3588_CLKGATE_CON(52), 0, GFLAGS),
+- COMPOSITE_NODIV(ACLK_VOP_LOW_ROOT, "aclk_vop_low_root", mux_400m_200m_100m_24m_p, 0,
++ COMPOSITE_NODIV(ACLK_VOP_LOW_ROOT, "aclk_vop_low_root", mux_400m_200m_100m_24m_p, RK3588_LINKED_CLK,
+ RK3588_CLKSEL_CON(110), 8, 2, MFLAGS,
+ RK3588_CLKGATE_CON(52), 1, GFLAGS),
+- COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, 0,
++ COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK,
+ RK3588_CLKSEL_CON(110), 10, 2, MFLAGS,
+ RK3588_CLKGATE_CON(52), 2, GFLAGS),
+ COMPOSITE_NODIV(PCLK_VOP_ROOT, "pclk_vop_root", mux_100m_50m_24m_p, 0,
+@@ -2425,7 +2435,7 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
+
+ GATE_LINK(ACLK_ISP1_PRE, "aclk_isp1_pre", "aclk_isp1_root", "aclk_vi_root", 0, RK3588_CLKGATE_CON(26), 6, GFLAGS),
+ GATE_LINK(HCLK_ISP1_PRE, "hclk_isp1_pre", "hclk_isp1_root", "hclk_vi_root", 0, RK3588_CLKGATE_CON(26), 8, GFLAGS),
+- GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", "aclk_nvm_root", 0, RK3588_CLKGATE_CON(31), 2, GFLAGS),
++ GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", "aclk_nvm_root", RK3588_LINKED_CLK, RK3588_CLKGATE_CON(31), 2, GFLAGS),
+ GATE_LINK(ACLK_USB, "aclk_usb", "aclk_usb_root", "aclk_vo1usb_top_root", 0, RK3588_CLKGATE_CON(42), 2, GFLAGS),
+ GATE_LINK(HCLK_USB, "hclk_usb", "hclk_usb_root", "hclk_vo1usb_top_root", 0, RK3588_CLKGATE_CON(42), 3, GFLAGS),
+ GATE_LINK(ACLK_JPEG_DECODER_PRE, "aclk_jpeg_decoder_pre", "aclk_jpeg_decoder_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 7, GFLAGS),
+--
+2.39.2
+
--- /dev/null
+From 7e5cf5aaae3cab9b66cd0de0016db0c0c2739553 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Feb 2023 09:59:10 +0100
+Subject: clk: tegra20: fix gcc-7 constant overflow warning
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit b4a2adbf3586efa12fe78b9dec047423e01f3010 ]
+
+Older gcc versions get confused by comparing a u32 value to a negative
+constant in a switch()/case block:
+
+drivers/clk/tegra/clk-tegra20.c: In function 'tegra20_clk_measure_input_freq':
+drivers/clk/tegra/clk-tegra20.c:581:2: error: case label does not reduce to an integer constant
+ case OSC_CTRL_OSC_FREQ_12MHZ:
+ ^~~~
+drivers/clk/tegra/clk-tegra20.c:593:2: error: case label does not reduce to an integer constant
+ case OSC_CTRL_OSC_FREQ_26MHZ:
+
+Make the constants unsigned instead.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20230227085914.2560984-1-arnd@kernel.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/tegra/clk-tegra20.c | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
+index 422d782475532..dcacc5064d339 100644
+--- a/drivers/clk/tegra/clk-tegra20.c
++++ b/drivers/clk/tegra/clk-tegra20.c
+@@ -21,24 +21,24 @@
+ #define MISC_CLK_ENB 0x48
+
+ #define OSC_CTRL 0x50
+-#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
+-#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
+-#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
+-#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
+-#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
+-#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
+-
+-#define OSC_CTRL_PLL_REF_DIV_MASK (3<<28)
+-#define OSC_CTRL_PLL_REF_DIV_1 (0<<28)
+-#define OSC_CTRL_PLL_REF_DIV_2 (1<<28)
+-#define OSC_CTRL_PLL_REF_DIV_4 (2<<28)
++#define OSC_CTRL_OSC_FREQ_MASK (3u<<30)
++#define OSC_CTRL_OSC_FREQ_13MHZ (0u<<30)
++#define OSC_CTRL_OSC_FREQ_19_2MHZ (1u<<30)
++#define OSC_CTRL_OSC_FREQ_12MHZ (2u<<30)
++#define OSC_CTRL_OSC_FREQ_26MHZ (3u<<30)
++#define OSC_CTRL_MASK (0x3f2u | OSC_CTRL_OSC_FREQ_MASK)
++
++#define OSC_CTRL_PLL_REF_DIV_MASK (3u<<28)
++#define OSC_CTRL_PLL_REF_DIV_1 (0u<<28)
++#define OSC_CTRL_PLL_REF_DIV_2 (1u<<28)
++#define OSC_CTRL_PLL_REF_DIV_4 (2u<<28)
+
+ #define OSC_FREQ_DET 0x58
+-#define OSC_FREQ_DET_TRIG (1<<31)
++#define OSC_FREQ_DET_TRIG (1u<<31)
+
+ #define OSC_FREQ_DET_STATUS 0x5c
+-#define OSC_FREQ_DET_BUSY (1<<31)
+-#define OSC_FREQ_DET_CNT_MASK 0xFFFF
++#define OSC_FREQ_DET_BUSYu (1<<31)
++#define OSC_FREQ_DET_CNT_MASK 0xFFFFu
+
+ #define TEGRA20_CLK_PERIPH_BANKS 3
+
+--
+2.39.2
+
--- /dev/null
+From 351e4a30cea26525228fd151ecd4f8d99022cfbe 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 28fac6f9e8c2273f0f72b6ec0d442827eeddd591 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 2b57f5b2362a4..536a636245950 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
+@@ -4307,11 +4307,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;
+@@ -4319,107 +4319,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 461ab6d2030e2..daf3193701909 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
+@@ -4405,11 +4405,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;
+@@ -4417,107 +4417,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 51fe079d3f591aee9f21affe465520f99389391b 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 899105da04335..111eb978520ac 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
+@@ -4865,7 +4865,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 536a636245950..bd674dc30df33 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
+@@ -5191,7 +5191,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 daf3193701909..7eb2173b7691e 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
+@@ -5288,7 +5288,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 02d99b6bfe5ec..705748a942952 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
+@@ -3353,7 +3353,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 e58c1bc1da20593451775d2119fa5729a3f471bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Jan 2023 18:30:08 -0500
+Subject: drm/amd/display: enable DPG when disabling plane for phantom pipe
+
+From: Samson Tam <samson.tam@amd.com>
+
+[ Upstream commit f3f8f16b10f8258f1836e1110099097490a1d6c1 ]
+
+[Why]
+In disable_dangling_plane, for phantom pipes, we enable OTG so
+disable programming gets the double buffer update. But this
+causes an underflow to occur.
+
+[How]
+Enable DPG prior to enabling OTG.
+
+Reviewed-by: Alvin Lee <Alvin.Lee2@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Samson Tam <samson.tam@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 47 +++++++++++++++++++++++-
+ 1 file changed, 46 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index d406d7b74c6c3..d4a1670a54506 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -73,6 +73,8 @@
+
+ #include "dc_trace.h"
+
++#include "hw_sequencer_private.h"
++
+ #include "dce/dmub_outbox.h"
+
+ #define CTX \
+@@ -1056,6 +1058,44 @@ static void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *contex
+ }
+ }
+
++static void phantom_pipe_blank(
++ struct dc *dc,
++ struct timing_generator *tg,
++ int width,
++ int height)
++{
++ struct dce_hwseq *hws = dc->hwseq;
++ enum dc_color_space color_space;
++ struct tg_color black_color = {0};
++ struct output_pixel_processor *opp = NULL;
++ uint32_t num_opps, opp_id_src0, opp_id_src1;
++ uint32_t otg_active_width, otg_active_height;
++
++ /* program opp dpg blank color */
++ color_space = COLOR_SPACE_SRGB;
++ color_space_to_black_color(dc, color_space, &black_color);
++
++ otg_active_width = width;
++ otg_active_height = height;
++
++ /* get the OPTC source */
++ tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
++ ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp);
++ opp = dc->res_pool->opps[opp_id_src0];
++
++ opp->funcs->opp_set_disp_pattern_generator(
++ opp,
++ CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
++ CONTROLLER_DP_COLOR_SPACE_UDEFINED,
++ COLOR_DEPTH_UNDEFINED,
++ &black_color,
++ otg_active_width,
++ otg_active_height,
++ 0);
++
++ hws->funcs.wait_for_blank_complete(opp);
++}
++
+ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
+ {
+ int i, j;
+@@ -1114,8 +1154,13 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
+ * again for different use.
+ */
+ if (old_stream->mall_stream_config.type == SUBVP_PHANTOM) {
+- if (tg->funcs->enable_crtc)
++ if (tg->funcs->enable_crtc) {
++ int main_pipe_width, main_pipe_height;
++ main_pipe_width = old_stream->mall_stream_config.paired_stream->dst.width;
++ main_pipe_height = old_stream->mall_stream_config.paired_stream->dst.height;
++ phantom_pipe_blank(dc, tg, main_pipe_width, main_pipe_height);
+ tg->funcs->enable_crtc(tg);
++ }
+ }
+ dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
+ disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
+--
+2.39.2
+
--- /dev/null
+From bbcfad4bfa4c67089488b934c8be1157f16ae520 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 3bbc46a673355..28163f7acd5b2 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
+@@ -308,6 +308,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 0f1588a48c49dc4c7957c8340052ef772b100700 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 b4df540c0c61e..36fa413f8b42e 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 d13e46eeee3c0..6d3f2335b9f1e 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
+@@ -285,7 +285,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 823f29c292d05..184310fa52b1a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -895,7 +895,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 ce3f1997fc555156e7b23e3d210bdee3664cbbd0 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 c2092775ca88f..7f27e29fae116 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+@@ -750,7 +750,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 3fd631e4d64bb4990acfbafe33ba99fed7ecac4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Feb 2023 14:33:00 -0500
+Subject: drm/amd/display: reallocate DET for dual displays with high pixel
+ rate ratio
+
+From: Samson Tam <Samson.Tam@amd.com>
+
+[ Upstream commit 5f3401eeb064fab5ce50728cce46532cce7a85c5 ]
+
+[Why]
+For dual displays where pixel rate is much higher on one display,
+we may get underflow when DET is evenly allocated.
+
+[How]
+Allocate less DET segments for the lower pixel rate display and
+more DET segments for the higher pixel rate display
+
+Reviewed-by: Alvin Lee <Alvin.Lee2@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Samson Tam <Samson.Tam@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>
+---
+ .../display/dc/dcn32/dcn32_resource_helpers.c | 43 ++++++++++++++++++-
+ 1 file changed, 42 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+index 3a2d7bcc4b6d6..8310bcf651728 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+@@ -261,6 +261,8 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe)
+ return psr_capable;
+ }
+
++#define DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER 7
++
+ /**
+ * *******************************************************************************************
+ * dcn32_determine_det_override: Determine DET allocation for each pipe
+@@ -272,7 +274,6 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe)
+ * If there is a plane that's driven by more than 1 pipe (i.e. pipe split), then the
+ * number of DET for that given plane will be split among the pipes driving that plane.
+ *
+- *
+ * High level algorithm:
+ * 1. Split total DET among number of streams
+ * 2. For each stream, split DET among the planes
+@@ -280,6 +281,18 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe)
+ * among those pipes.
+ * 4. Assign the DET override to the DML pipes.
+ *
++ * Special cases:
++ *
++ * For two displays that have a large difference in pixel rate, we may experience
++ * underflow on the larger display when we divide the DET equally. For this, we
++ * will implement a modified algorithm to assign more DET to larger display.
++ *
++ * 1. Calculate difference in pixel rates ( multiplier ) between two displays
++ * 2. If the multiplier exceeds DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER, then
++ * implement the modified DET override algorithm.
++ * 3. Assign smaller DET size for lower pixel display and higher DET size for
++ * higher pixel display
++ *
+ * @param [in]: dc: Current DC state
+ * @param [in]: context: New DC state to be programmed
+ * @param [in]: pipes: Array of DML pipes
+@@ -299,18 +312,46 @@ void dcn32_determine_det_override(struct dc *dc,
+ struct dc_plane_state *current_plane = NULL;
+ uint8_t stream_count = 0;
+
++ int phy_pix_clk_mult, lower_mode_stream_index;
++ int phy_pix_clk[MAX_PIPES] = {0};
++ bool use_new_det_override_algorithm = false;
++
+ for (i = 0; i < context->stream_count; i++) {
+ /* Don't count SubVP streams for DET allocation */
+ if (context->streams[i]->mall_stream_config.type != SUBVP_PHANTOM) {
++ phy_pix_clk[i] = context->streams[i]->phy_pix_clk;
+ stream_count++;
+ }
+ }
+
++ /* Check for special case with two displays, one with much higher pixel rate */
++ if (stream_count == 2) {
++ ASSERT(!phy_pix_clk[0] || !phy_pix_clk[1]);
++ if (phy_pix_clk[0] < phy_pix_clk[1]) {
++ lower_mode_stream_index = 0;
++ phy_pix_clk_mult = phy_pix_clk[1] / phy_pix_clk[0];
++ } else {
++ lower_mode_stream_index = 1;
++ phy_pix_clk_mult = phy_pix_clk[0] / phy_pix_clk[1];
++ }
++
++ if (phy_pix_clk_mult >= DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER)
++ use_new_det_override_algorithm = true;
++ }
++
+ if (stream_count > 0) {
+ stream_segments = 18 / stream_count;
+ for (i = 0; i < context->stream_count; i++) {
+ if (context->streams[i]->mall_stream_config.type == SUBVP_PHANTOM)
+ continue;
++
++ if (use_new_det_override_algorithm) {
++ if (i == lower_mode_stream_index)
++ stream_segments = 4;
++ else
++ stream_segments = 14;
++ }
++
+ if (context->stream_status[i].plane_count > 0)
+ plane_segments = stream_segments / context->stream_status[i].plane_count;
+ else
+--
+2.39.2
+
--- /dev/null
+From 51ad74af99b1e4c2d3bb8dfd977a0ab7714b6d0c 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 1813bca030329210104ba1a22411d43051939181 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 e381de2429fa6..ae3783a7d7f45 100644
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+@@ -515,11 +515,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 dc2ec43deecba974362251644c29bb226b982fa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Apr 2023 16:32:29 -0400
+Subject: drm/amdgpu: Enable IH retry CAM on GFX9
+
+From: Mukul Joshi <mukul.joshi@amd.com>
+
+[ Upstream commit 318e431b306e966d2ee99e900a11bdc9a701ee83 ]
+
+This patch enables the IH retry CAM on GFX9 series cards. This
+retry filter is used to prevent sending lots of retry interrupts
+in a short span of time and overflowing the IH ring buffer. This
+will also help reduce CPU interrupt workload.
+
+Signed-off-by: Mukul Joshi <mukul.joshi@amd.com>
+Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 2 +
+ drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 51 +++++++++++------
+ drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 2 +-
+ drivers/gpu/drm/amd/amdgpu/vega20_ih.c | 55 +++++++++----------
+ drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 10 +++-
+ .../asic_reg/oss/osssys_4_2_0_offset.h | 6 ++
+ .../asic_reg/oss/osssys_4_2_0_sh_mask.h | 11 ++++
+ 7 files changed, 88 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
+index e9f2c11ea416c..be243adf3e657 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
+@@ -98,6 +98,8 @@ struct amdgpu_irq {
+ struct irq_domain *domain; /* GPU irq controller domain */
+ unsigned virq[AMDGPU_MAX_IRQ_SRC_ID];
+ uint32_t srbm_soft_reset;
++ u32 retry_cam_doorbell_index;
++ bool retry_cam_enabled;
+ };
+
+ void amdgpu_irq_disable_all(struct amdgpu_device *adev);
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+index 83d22dd8b8715..bc8b4e405b7a7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+@@ -553,32 +553,49 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
+ const char *mmhub_cid;
+ const char *hub_name;
+ u64 addr;
++ uint32_t cam_index = 0;
++ int ret;
+
+ addr = (u64)entry->src_data[0] << 12;
+ addr |= ((u64)entry->src_data[1] & 0xf) << 44;
+
+ if (retry_fault) {
+- /* Returning 1 here also prevents sending the IV to the KFD */
++ if (adev->irq.retry_cam_enabled) {
++ /* Delegate it to a different ring if the hardware hasn't
++ * already done it.
++ */
++ if (entry->ih == &adev->irq.ih) {
++ amdgpu_irq_delegate(adev, entry, 8);
++ return 1;
++ }
++
++ cam_index = entry->src_data[2] & 0x3ff;
+
+- /* Process it onyl if it's the first fault for this address */
+- if (entry->ih != &adev->irq.ih_soft &&
+- amdgpu_gmc_filter_faults(adev, entry->ih, addr, entry->pasid,
++ ret = amdgpu_vm_handle_fault(adev, entry->pasid, addr, write_fault);
++ WDOORBELL32(adev->irq.retry_cam_doorbell_index, cam_index);
++ if (ret)
++ return 1;
++ } else {
++ /* Process it onyl if it's the first fault for this address */
++ if (entry->ih != &adev->irq.ih_soft &&
++ amdgpu_gmc_filter_faults(adev, entry->ih, addr, entry->pasid,
+ entry->timestamp))
+- return 1;
++ return 1;
+
+- /* Delegate it to a different ring if the hardware hasn't
+- * already done it.
+- */
+- if (entry->ih == &adev->irq.ih) {
+- amdgpu_irq_delegate(adev, entry, 8);
+- return 1;
+- }
++ /* Delegate it to a different ring if the hardware hasn't
++ * already done it.
++ */
++ if (entry->ih == &adev->irq.ih) {
++ amdgpu_irq_delegate(adev, entry, 8);
++ return 1;
++ }
+
+- /* Try to handle the recoverable page faults by filling page
+- * tables
+- */
+- if (amdgpu_vm_handle_fault(adev, entry->pasid, addr, write_fault))
+- return 1;
++ /* Try to handle the recoverable page faults by filling page
++ * tables
++ */
++ if (amdgpu_vm_handle_fault(adev, entry->pasid, addr, write_fault))
++ return 1;
++ }
+ }
+
+ if (!printk_ratelimit())
+diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
+index 19455a7259391..685abf57ffddc 100644
+--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
++++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
+@@ -238,7 +238,7 @@ static void nbio_v7_4_ih_doorbell_range(struct amdgpu_device *adev,
+
+ if (use_doorbell) {
+ ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, OFFSET, doorbell_index);
+- ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 4);
++ ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 8);
+ } else
+ ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 0);
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
+index 1706081d054dd..6a8fb1fb48a3d 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
++++ b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
+@@ -38,6 +38,11 @@
+ #define mmIH_CHICKEN_ALDEBARAN 0x18d
+ #define mmIH_CHICKEN_ALDEBARAN_BASE_IDX 0
+
++#define mmIH_RETRY_INT_CAM_CNTL_ALDEBARAN 0x00ea
++#define mmIH_RETRY_INT_CAM_CNTL_ALDEBARAN_BASE_IDX 0
++#define IH_RETRY_INT_CAM_CNTL_ALDEBARAN__ENABLE__SHIFT 0x10
++#define IH_RETRY_INT_CAM_CNTL_ALDEBARAN__ENABLE_MASK 0x00010000L
++
+ static void vega20_ih_set_interrupt_funcs(struct amdgpu_device *adev);
+
+ /**
+@@ -251,36 +256,14 @@ static int vega20_ih_enable_ring(struct amdgpu_device *adev,
+ return 0;
+ }
+
+-/**
+- * vega20_ih_reroute_ih - reroute VMC/UTCL2 ih to an ih ring
+- *
+- * @adev: amdgpu_device pointer
+- *
+- * Reroute VMC and UMC interrupts on primary ih ring to
+- * ih ring 1 so they won't lose when bunches of page faults
+- * interrupts overwhelms the interrupt handler(VEGA20)
+- */
+-static void vega20_ih_reroute_ih(struct amdgpu_device *adev)
++static uint32_t vega20_setup_retry_doorbell(u32 doorbell_index)
+ {
+- uint32_t tmp;
++ u32 val = 0;
+
+- /* vega20 ih reroute will go through psp this
+- * function is used for newer asics starting arcturus
+- */
+- if (adev->ip_versions[OSSSYS_HWIP][0] >= IP_VERSION(4, 2, 1)) {
+- /* Reroute to IH ring 1 for VMC */
+- WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x12);
+- tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
+- tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, CLIENT_TYPE, 1);
+- tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
+- WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA, tmp);
+-
+- /* Reroute IH ring 1 for UTCL2 */
+- WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x1B);
+- tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
+- tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
+- WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA, tmp);
+- }
++ val = REG_SET_FIELD(val, IH_DOORBELL_RPTR, OFFSET, doorbell_index);
++ val = REG_SET_FIELD(val, IH_DOORBELL_RPTR, ENABLE, 1);
++
++ return val;
+ }
+
+ /**
+@@ -332,8 +315,6 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
+
+ for (i = 0; i < ARRAY_SIZE(ih); i++) {
+ if (ih[i]->ring_size) {
+- if (i == 1)
+- vega20_ih_reroute_ih(adev);
+ ret = vega20_ih_enable_ring(adev, ih[i]);
+ if (ret)
+ return ret;
+@@ -346,6 +327,20 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
+
+ pci_set_master(adev->pdev);
+
++ /* Allocate the doorbell for IH Retry CAM */
++ adev->irq.retry_cam_doorbell_index = (adev->doorbell_index.ih + 3) << 1;
++ WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RETRY_CAM,
++ vega20_setup_retry_doorbell(adev->irq.retry_cam_doorbell_index));
++
++ /* Enable IH Retry CAM */
++ if (adev->ip_versions[OSSSYS_HWIP][0] == IP_VERSION(4, 4, 0))
++ WREG32_FIELD15(OSSSYS, 0, IH_RETRY_INT_CAM_CNTL_ALDEBARAN,
++ ENABLE, 1);
++ else
++ WREG32_FIELD15(OSSSYS, 0, IH_RETRY_INT_CAM_CNTL, ENABLE, 1);
++
++ adev->irq.retry_cam_enabled = true;
++
+ /* enable interrupts */
+ ret = vega20_ih_toggle_interrupts(adev, true);
+ if (ret)
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+index dc6fd69670509..96a138a395150 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+@@ -2172,7 +2172,15 @@ static void svm_range_drain_retry_fault(struct svm_range_list *svms)
+ pr_debug("drain retry fault gpu %d svms %p\n", i, svms);
+
+ amdgpu_ih_wait_on_checkpoint_process_ts(pdd->dev->adev,
+- &pdd->dev->adev->irq.ih1);
++ pdd->dev->adev->irq.retry_cam_enabled ?
++ &pdd->dev->adev->irq.ih :
++ &pdd->dev->adev->irq.ih1);
++
++ if (pdd->dev->adev->irq.retry_cam_enabled)
++ amdgpu_ih_wait_on_checkpoint_process_ts(pdd->dev->adev,
++ &pdd->dev->adev->irq.ih_soft);
++
++
+ pr_debug("drain retry fault gpu %d svms 0x%p done\n", i, svms);
+ }
+ if (atomic_cmpxchg(&svms->drain_pagefaults, drain, 0) != drain)
+diff --git a/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_offset.h
+index bd129266ebfd1..a84a7cfaf71e5 100644
+--- a/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_offset.h
++++ b/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_offset.h
+@@ -135,6 +135,8 @@
+ #define mmIH_RB_WPTR_ADDR_LO_BASE_IDX 0
+ #define mmIH_DOORBELL_RPTR 0x0087
+ #define mmIH_DOORBELL_RPTR_BASE_IDX 0
++#define mmIH_DOORBELL_RETRY_CAM 0x0088
++#define mmIH_DOORBELL_RETRY_CAM_BASE_IDX 0
+ #define mmIH_RB_CNTL_RING1 0x008c
+ #define mmIH_RB_CNTL_RING1_BASE_IDX 0
+ #define mmIH_RB_BASE_RING1 0x008d
+@@ -159,6 +161,8 @@
+ #define mmIH_RB_WPTR_RING2_BASE_IDX 0
+ #define mmIH_DOORBELL_RPTR_RING2 0x009f
+ #define mmIH_DOORBELL_RPTR_RING2_BASE_IDX 0
++#define mmIH_RETRY_CAM_ACK 0x00a4
++#define mmIH_RETRY_CAM_ACK_BASE_IDX 0
+ #define mmIH_VERSION 0x00a5
+ #define mmIH_VERSION_BASE_IDX 0
+ #define mmIH_CNTL 0x00c0
+@@ -235,6 +239,8 @@
+ #define mmIH_MMHUB_ERROR_BASE_IDX 0
+ #define mmIH_MEM_POWER_CTRL 0x00e8
+ #define mmIH_MEM_POWER_CTRL_BASE_IDX 0
++#define mmIH_RETRY_INT_CAM_CNTL 0x00e9
++#define mmIH_RETRY_INT_CAM_CNTL_BASE_IDX 0
+ #define mmIH_REGISTER_LAST_PART2 0x00ff
+ #define mmIH_REGISTER_LAST_PART2_BASE_IDX 0
+ #define mmSEM_CLK_CTRL 0x0100
+diff --git a/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_sh_mask.h
+index 3ea83ea9ce3a4..75c04fc275a0c 100644
+--- a/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_sh_mask.h
++++ b/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_sh_mask.h
+@@ -349,6 +349,17 @@
+ #define IH_DOORBELL_RPTR_RING2__ENABLE__SHIFT 0x1c
+ #define IH_DOORBELL_RPTR_RING2__OFFSET_MASK 0x03FFFFFFL
+ #define IH_DOORBELL_RPTR_RING2__ENABLE_MASK 0x10000000L
++//IH_RETRY_INT_CAM_CNTL
++#define IH_RETRY_INT_CAM_CNTL__CAM_SIZE__SHIFT 0x0
++#define IH_RETRY_INT_CAM_CNTL__BACK_PRESSURE_SKID_VALUE__SHIFT 0x8
++#define IH_RETRY_INT_CAM_CNTL__ENABLE__SHIFT 0x10
++#define IH_RETRY_INT_CAM_CNTL__BACK_PRESSURE_ENABLE__SHIFT 0x11
++#define IH_RETRY_INT_CAM_CNTL__PER_VF_ENTRY_SIZE__SHIFT 0x14
++#define IH_RETRY_INT_CAM_CNTL__CAM_SIZE_MASK 0x0000001FL
++#define IH_RETRY_INT_CAM_CNTL__BACK_PRESSURE_SKID_VALUE_MASK 0x00003F00L
++#define IH_RETRY_INT_CAM_CNTL__ENABLE_MASK 0x00010000L
++#define IH_RETRY_INT_CAM_CNTL__BACK_PRESSURE_ENABLE_MASK 0x00020000L
++#define IH_RETRY_INT_CAM_CNTL__PER_VF_ENTRY_SIZE_MASK 0x00300000L
+ //IH_VERSION
+ #define IH_VERSION__MINVER__SHIFT 0x0
+ #define IH_VERSION__MAJVER__SHIFT 0x8
+--
+2.39.2
+
--- /dev/null
+From 1006341669bc32ba5791ad17f0a379592e57896a 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 8b8ddf0502661..a4d84e3fe9381 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+@@ -1870,7 +1870,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 de0be5c48224d40213b784a146f56ba884d73c3d 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 c6e94a243df35991e30146cdf3ee1f5e306bf25f 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 46a5349ee39642c5fe77e541a40f6c33b3d47c95 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 b9fe9daf80103a2f91752fcf2bcf050866d4ae2f 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 ef413deb612a9017b7171357be844d08682f4521 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 cb78d7dcfb952..c60cb900bb2f4 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 69c88facfe90e..f342f347a695f 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 0d9580f1de6e4ff51f312d1af5f5b3ce0ac1543b 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 90daeca1c8c58..9d495cd63ea27 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 e7e9fb8e0ab4978023df163551e49068b1af9138 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 2a1df157d1206..90daeca1c8c58 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 dd921a8663dbfaa1395ff6005298a54d3215b784 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 2996d38aa89c3..f984d9f05f808 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1810,6 +1810,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,
+@@ -1895,8 +1896,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 5ad6ac63e13f3..28a00942802c2 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 babb29a1c0347..9728bdeccb2cc 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -602,8 +602,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) +
+@@ -613,20 +617,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 b3cdb298e350aa92bc4a3fc3e49a18b9de1fbedf 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 d6f9d6e0f13b9..47eff365f536c 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -4427,6 +4427,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 5c1c3a84501fe..333ea095c8c50 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -2274,7 +2274,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 de8039f63d2a6804191a8e28a6bd37f6e300057b 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 c3e058e0a0188..96af24c394c39 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -325,8 +325,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))
+@@ -1306,7 +1313,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 1034912a61b30..68feb015cfa3a 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -2800,7 +2800,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 f04c8f5cd267b6020cce274f1c6c7f3608566dbb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 16:56:20 -0700
+Subject: f2fs: relax sanity check if checkpoint is corrupted
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+[ Upstream commit bd90c5cd339a9d7cdc609d2d6310b80dc697070d ]
+
+1. extent_cache
+ - let's drop the largest extent_cache
+2. invalidate_block
+ - don't show the warnings
+
+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/checkpoint.c | 10 ++++++++++
+ fs/f2fs/data.c | 4 ++++
+ fs/f2fs/extent_cache.c | 22 +++++++++++++++-------
+ 3 files changed, 29 insertions(+), 7 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index 96af24c394c39..d4c862ccd1f72 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -152,6 +152,11 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
+ se = get_seg_entry(sbi, segno);
+
+ exist = f2fs_test_bit(offset, se->cur_valid_map);
++
++ /* skip data, if we already have an error in checkpoint. */
++ if (unlikely(f2fs_cp_error(sbi)))
++ return exist;
++
+ if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
+ f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
+ blkaddr, exist);
+@@ -202,6 +207,11 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
+ case DATA_GENERIC_ENHANCE_UPDATE:
+ if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
+ blkaddr < MAIN_BLKADDR(sbi))) {
++
++ /* Skip to emit an error message. */
++ if (unlikely(f2fs_cp_error(sbi)))
++ return false;
++
+ f2fs_warn(sbi, "access invalid blkaddr:%u",
+ blkaddr);
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 68feb015cfa3a..92bcdbd8e4f21 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -2237,6 +2237,10 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
+ if (ret)
+ goto out;
+
++ if (unlikely(f2fs_cp_error(sbi))) {
++ ret = -EIO;
++ goto out_put_dnode;
++ }
+ f2fs_bug_on(sbi, dn.data_blkaddr != COMPRESS_ADDR);
+
+ skip_reading_dnode:
+diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
+index 9a8153895d203..bea6ab9d846ae 100644
+--- a/fs/f2fs/extent_cache.c
++++ b/fs/f2fs/extent_cache.c
+@@ -23,18 +23,26 @@ bool sanity_check_extent_cache(struct inode *inode)
+ {
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct f2fs_inode_info *fi = F2FS_I(inode);
++ struct extent_tree *et = fi->extent_tree[EX_READ];
+ struct extent_info *ei;
+
+- if (!fi->extent_tree[EX_READ])
++ if (!et)
++ return true;
++
++ ei = &et->largest;
++ if (!ei->len)
+ return true;
+
+- ei = &fi->extent_tree[EX_READ]->largest;
++ /* Let's drop, if checkpoint got corrupted. */
++ if (is_set_ckpt_flags(sbi, CP_ERROR_FLAG)) {
++ ei->len = 0;
++ et->largest_updated = true;
++ return true;
++ }
+
+- if (ei->len &&
+- (!f2fs_is_valid_blkaddr(sbi, ei->blk,
+- DATA_GENERIC_ENHANCE) ||
+- !f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1,
+- DATA_GENERIC_ENHANCE))) {
++ if (!f2fs_is_valid_blkaddr(sbi, ei->blk, DATA_GENERIC_ENHANCE) ||
++ !f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1,
++ DATA_GENERIC_ENHANCE)) {
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ f2fs_warn(sbi, "%s: inode (ino=%lx) extent info [%u, %u, %u] is incorrect, run fsck to fix",
+ __func__, inode->i_ino,
+--
+2.39.2
+
--- /dev/null
+From a8f3f0f4ecd611228ea5a4942148f11a41064b62 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 5b2f8147d1ae3..0f1001dca0e00 100644
+--- a/include/linux/cpuhotplug.h
++++ b/include/linux/cpuhotplug.h
+@@ -163,7 +163,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 72a4ddc0ea17860c2b6d71e4eba864ec590fd967 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 abb91f5fae921..b21660475ac1c 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 dcb240d5c6bbc953e871e7d1367a2f409a46d052 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Oct 2022 23:15:06 +0800
+Subject: fs/ntfs3: Add length check in indx_get_root
+
+From: Edward Lo <edward.lo@ambergroup.io>
+
+[ Upstream commit 08e8cf5f2d9ec383a2e339a2711b62a54ff3fba0 ]
+
+This adds a length check to guarantee the retrieved index root is legit.
+
+[ 162.459513] BUG: KASAN: use-after-free in hdr_find_e.isra.0+0x10c/0x320
+[ 162.460176] Read of size 2 at addr ffff8880037bca99 by task mount/243
+[ 162.460851]
+[ 162.461252] CPU: 0 PID: 243 Comm: mount Not tainted 6.0.0-rc7 #42
+[ 162.461744] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
+[ 162.462609] Call Trace:
+[ 162.462954] <TASK>
+[ 162.463276] dump_stack_lvl+0x49/0x63
+[ 162.463822] print_report.cold+0xf5/0x689
+[ 162.464608] ? unwind_get_return_address+0x3a/0x60
+[ 162.465766] ? hdr_find_e.isra.0+0x10c/0x320
+[ 162.466975] kasan_report+0xa7/0x130
+[ 162.467506] ? _raw_spin_lock_irq+0xc0/0xf0
+[ 162.467998] ? hdr_find_e.isra.0+0x10c/0x320
+[ 162.468536] __asan_load2+0x68/0x90
+[ 162.468923] hdr_find_e.isra.0+0x10c/0x320
+[ 162.469282] ? cmp_uints+0xe0/0xe0
+[ 162.469557] ? cmp_sdh+0x90/0x90
+[ 162.469864] ? ni_find_attr+0x214/0x300
+[ 162.470217] ? ni_load_mi+0x80/0x80
+[ 162.470479] ? entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[ 162.470931] ? ntfs_bread_run+0x190/0x190
+[ 162.471307] ? indx_get_root+0xe4/0x190
+[ 162.471556] ? indx_get_root+0x140/0x190
+[ 162.471833] ? indx_init+0x1e0/0x1e0
+[ 162.472069] ? fnd_clear+0x115/0x140
+[ 162.472363] ? _raw_spin_lock_irqsave+0x100/0x100
+[ 162.472731] indx_find+0x184/0x470
+[ 162.473461] ? sysvec_apic_timer_interrupt+0x57/0xc0
+[ 162.474429] ? indx_find_buffer+0x2d0/0x2d0
+[ 162.474704] ? do_syscall_64+0x3b/0x90
+[ 162.474962] dir_search_u+0x196/0x2f0
+[ 162.475381] ? ntfs_nls_to_utf16+0x450/0x450
+[ 162.475661] ? ntfs_security_init+0x3d6/0x440
+[ 162.475906] ? is_sd_valid+0x180/0x180
+[ 162.476191] ntfs_extend_init+0x13f/0x2c0
+[ 162.476496] ? ntfs_fix_post_read+0x130/0x130
+[ 162.476861] ? iput.part.0+0x286/0x320
+[ 162.477325] ntfs_fill_super+0x11e0/0x1b50
+[ 162.477709] ? put_ntfs+0x1d0/0x1d0
+[ 162.477970] ? vsprintf+0x20/0x20
+[ 162.478258] ? set_blocksize+0x95/0x150
+[ 162.478538] get_tree_bdev+0x232/0x370
+[ 162.478789] ? put_ntfs+0x1d0/0x1d0
+[ 162.479038] ntfs_fs_get_tree+0x15/0x20
+[ 162.479374] vfs_get_tree+0x4c/0x130
+[ 162.479729] path_mount+0x654/0xfe0
+[ 162.480124] ? putname+0x80/0xa0
+[ 162.480484] ? finish_automount+0x2e0/0x2e0
+[ 162.480894] ? putname+0x80/0xa0
+[ 162.481467] ? kmem_cache_free+0x1c4/0x440
+[ 162.482280] ? putname+0x80/0xa0
+[ 162.482714] do_mount+0xd6/0xf0
+[ 162.483264] ? path_mount+0xfe0/0xfe0
+[ 162.484782] ? __kasan_check_write+0x14/0x20
+[ 162.485593] __x64_sys_mount+0xca/0x110
+[ 162.486024] do_syscall_64+0x3b/0x90
+[ 162.486543] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[ 162.487141] RIP: 0033:0x7f9d374e948a
+[ 162.488324] Code: 48 8b 0d 11 fa 2a 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 49 89 ca b8 a5 00 00 008
+[ 162.489728] RSP: 002b:00007ffe30e73d18 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
+[ 162.490971] RAX: ffffffffffffffda RBX: 0000561cdb43a060 RCX: 00007f9d374e948a
+[ 162.491669] RDX: 0000561cdb43a260 RSI: 0000561cdb43a2e0 RDI: 0000561cdb442af0
+[ 162.492050] RBP: 0000000000000000 R08: 0000561cdb43a280 R09: 0000000000000020
+[ 162.492459] R10: 00000000c0ed0000 R11: 0000000000000206 R12: 0000561cdb442af0
+[ 162.493183] R13: 0000561cdb43a260 R14: 0000000000000000 R15: 00000000ffffffff
+[ 162.493644] </TASK>
+[ 162.493908]
+[ 162.494214] The buggy address belongs to the physical page:
+[ 162.494761] page:000000003e38a3d5 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x37bc
+[ 162.496064] flags: 0xfffffc0000000(node=0|zone=1|lastcpupid=0x1fffff)
+[ 162.497278] raw: 000fffffc0000000 ffffea00000df1c8 ffffea00000df008 0000000000000000
+[ 162.498928] raw: 0000000000000000 0000000000240000 00000000ffffffff 0000000000000000
+[ 162.500542] page dumped because: kasan: bad access detected
+[ 162.501057]
+[ 162.501242] Memory state around the buggy address:
+[ 162.502230] ffff8880037bc980: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+[ 162.502977] ffff8880037bca00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+[ 162.503522] >ffff8880037bca80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+[ 162.503963] ^
+[ 162.504370] ffff8880037bcb00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+[ 162.504766] ffff8880037bcb80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+
+Signed-off-by: Edward Lo <edward.lo@ambergroup.io>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/index.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c
+index 7a1e01a2ed9ae..f716487ec8a05 100644
+--- a/fs/ntfs3/index.c
++++ b/fs/ntfs3/index.c
+@@ -994,6 +994,7 @@ struct INDEX_ROOT *indx_get_root(struct ntfs_index *indx, struct ntfs_inode *ni,
+ struct ATTR_LIST_ENTRY *le = NULL;
+ struct ATTRIB *a;
+ const struct INDEX_NAMES *in = &s_index_names[indx->type];
++ struct INDEX_ROOT *root = NULL;
+
+ a = ni_find_attr(ni, NULL, &le, ATTR_ROOT, in->name, in->name_len, NULL,
+ mi);
+@@ -1003,7 +1004,15 @@ struct INDEX_ROOT *indx_get_root(struct ntfs_index *indx, struct ntfs_inode *ni,
+ if (attr)
+ *attr = a;
+
+- return resident_data_ex(a, sizeof(struct INDEX_ROOT));
++ root = resident_data_ex(a, sizeof(struct INDEX_ROOT));
++
++ /* length check */
++ if (root && offsetof(struct INDEX_ROOT, ihdr) + le32_to_cpu(root->ihdr.used) >
++ le32_to_cpu(a->res.data_size)) {
++ return NULL;
++ }
++
++ return root;
+ }
+
+ static int indx_write(struct ntfs_index *indx, struct ntfs_inode *ni,
+--
+2.39.2
+
--- /dev/null
+From 9bcb0a139b715d18de4e0535e07dc31482f9a575 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Oct 2022 23:33:37 +0800
+Subject: fs/ntfs3: Enhance the attribute size check
+
+From: Edward Lo <edward.lo@ambergroup.io>
+
+[ Upstream commit 4f082a7531223a438c757bb20e304f4c941c67a8 ]
+
+This combines the overflow and boundary check so that all attribute size
+will be properly examined while enumerating them.
+
+[ 169.181521] BUG: KASAN: slab-out-of-bounds in run_unpack+0x2e3/0x570
+[ 169.183161] Read of size 1 at addr ffff8880094b6240 by task mount/247
+[ 169.184046]
+[ 169.184925] CPU: 0 PID: 247 Comm: mount Not tainted 6.0.0-rc7+ #3
+[ 169.185908] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
+[ 169.187066] Call Trace:
+[ 169.187492] <TASK>
+[ 169.188049] dump_stack_lvl+0x49/0x63
+[ 169.188495] print_report.cold+0xf5/0x689
+[ 169.188964] ? run_unpack+0x2e3/0x570
+[ 169.189331] kasan_report+0xa7/0x130
+[ 169.189714] ? run_unpack+0x2e3/0x570
+[ 169.190079] __asan_load1+0x51/0x60
+[ 169.190634] run_unpack+0x2e3/0x570
+[ 169.191290] ? run_pack+0x840/0x840
+[ 169.191569] ? run_lookup_entry+0xb3/0x1f0
+[ 169.192443] ? mi_enum_attr+0x20a/0x230
+[ 169.192886] run_unpack_ex+0xad/0x3e0
+[ 169.193276] ? run_unpack+0x570/0x570
+[ 169.193557] ? ni_load_mi+0x80/0x80
+[ 169.193889] ? debug_smp_processor_id+0x17/0x20
+[ 169.194236] ? mi_init+0x4a/0x70
+[ 169.194496] attr_load_runs_vcn+0x166/0x1c0
+[ 169.194851] ? attr_data_write_resident+0x250/0x250
+[ 169.195188] mi_read+0x133/0x2c0
+[ 169.195481] ntfs_iget5+0x277/0x1780
+[ 169.196017] ? call_rcu+0x1c7/0x330
+[ 169.196392] ? ntfs_get_block_bmap+0x70/0x70
+[ 169.196708] ? evict+0x223/0x280
+[ 169.197014] ? __kmalloc+0x33/0x540
+[ 169.197305] ? wnd_init+0x15b/0x1b0
+[ 169.197599] ntfs_fill_super+0x1026/0x1ba0
+[ 169.197994] ? put_ntfs+0x1d0/0x1d0
+[ 169.198299] ? vsprintf+0x20/0x20
+[ 169.198583] ? mutex_unlock+0x81/0xd0
+[ 169.198930] ? set_blocksize+0x95/0x150
+[ 169.199269] get_tree_bdev+0x232/0x370
+[ 169.199750] ? put_ntfs+0x1d0/0x1d0
+[ 169.200094] ntfs_fs_get_tree+0x15/0x20
+[ 169.200431] vfs_get_tree+0x4c/0x130
+[ 169.200714] path_mount+0x654/0xfe0
+[ 169.201067] ? putname+0x80/0xa0
+[ 169.201358] ? finish_automount+0x2e0/0x2e0
+[ 169.201965] ? putname+0x80/0xa0
+[ 169.202445] ? kmem_cache_free+0x1c4/0x440
+[ 169.203075] ? putname+0x80/0xa0
+[ 169.203414] do_mount+0xd6/0xf0
+[ 169.203719] ? path_mount+0xfe0/0xfe0
+[ 169.203977] ? __kasan_check_write+0x14/0x20
+[ 169.204382] __x64_sys_mount+0xca/0x110
+[ 169.204711] do_syscall_64+0x3b/0x90
+[ 169.205059] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[ 169.205571] RIP: 0033:0x7f67a80e948a
+[ 169.206327] Code: 48 8b 0d 11 fa 2a 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 49 89 ca b8 a5 00 00 008
+[ 169.208296] RSP: 002b:00007ffddf020f58 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
+[ 169.209253] RAX: ffffffffffffffda RBX: 000055e2547a6060 RCX: 00007f67a80e948a
+[ 169.209777] RDX: 000055e2547a6260 RSI: 000055e2547a62e0 RDI: 000055e2547aeaf0
+[ 169.210342] RBP: 0000000000000000 R08: 000055e2547a6280 R09: 0000000000000020
+[ 169.210843] R10: 00000000c0ed0000 R11: 0000000000000202 R12: 000055e2547aeaf0
+[ 169.211307] R13: 000055e2547a6260 R14: 0000000000000000 R15: 00000000ffffffff
+[ 169.211913] </TASK>
+[ 169.212304]
+[ 169.212680] Allocated by task 0:
+[ 169.212963] (stack is not available)
+[ 169.213200]
+[ 169.213472] The buggy address belongs to the object at ffff8880094b5e00
+[ 169.213472] which belongs to the cache UDP of size 1152
+[ 169.214095] The buggy address is located 1088 bytes inside of
+[ 169.214095] 1152-byte region [ffff8880094b5e00, ffff8880094b6280)
+[ 169.214639]
+[ 169.215004] The buggy address belongs to the physical page:
+[ 169.215766] page:000000002e324c8c refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x94b4
+[ 169.218412] head:000000002e324c8c order:2 compound_mapcount:0 compound_pincount:0
+[ 169.219078] flags: 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff)
+[ 169.220272] raw: 000fffffc0010200 0000000000000000 dead000000000122 ffff888002409b40
+[ 169.221006] raw: 0000000000000000 00000000800c000c 00000001ffffffff 0000000000000000
+[ 169.222320] page dumped because: kasan: bad access detected
+[ 169.222922]
+[ 169.223119] Memory state around the buggy address:
+[ 169.224056] ffff8880094b6100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+[ 169.224908] ffff8880094b6180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+[ 169.225677] >ffff8880094b6200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+[ 169.226445] ^
+[ 169.227055] ffff8880094b6280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+[ 169.227638] ffff8880094b6300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+
+Signed-off-by: Edward Lo <edward.lo@ambergroup.io>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/record.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c
+index defce6a5c8e1b..abfe004774c03 100644
+--- a/fs/ntfs3/record.c
++++ b/fs/ntfs3/record.c
+@@ -220,11 +220,6 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
+ return NULL;
+ }
+
+- if (off + asize < off) {
+- /* overflow check */
+- return NULL;
+- }
+-
+ attr = Add2Ptr(attr, asize);
+ off += asize;
+ }
+@@ -247,8 +242,8 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
+ if ((t32 & 0xf) || (t32 > 0x100))
+ return NULL;
+
+- /* Check boundary. */
+- if (off + asize > used)
++ /* Check overflow and boundary. */
++ if (off + asize < off || off + asize > used)
+ return NULL;
+
+ /* Check size of attribute. */
+--
+2.39.2
+
--- /dev/null
+From 2ba3d8882e2213b5605a19e1f7984a0bf507b337 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 16:59:43 +0800
+Subject: fs/ntfs3: Fix a possible null-pointer dereference in ni_clear()
+
+From: Jia-Ju Bai <baijiaju1990@gmail.com>
+
+[ Upstream commit ec275bf9693d19cc0fdce8436f4c425ced86f6e7 ]
+
+In a previous commit c1006bd13146, ni->mi.mrec in ni_write_inode()
+could be NULL, and thus a NULL check is added for this variable.
+
+However, in the same call stack, ni->mi.mrec can be also dereferenced
+in ni_clear():
+
+ntfs_evict_inode(inode)
+ ni_write_inode(inode, ...)
+ ni = ntfs_i(inode);
+ is_rec_inuse(ni->mi.mrec) -> Add a NULL check by previous commit
+ ni_clear(ntfs_i(inode))
+ is_rec_inuse(ni->mi.mrec) -> No check
+
+Thus, a possible null-pointer dereference may exist in ni_clear().
+To fix it, a NULL check is added in this function.
+
+Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
+Reported-by: TOTE Robot <oslab@tsinghua.edu.cn>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/frecord.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
+index 1103d4d9a4974..9e7dfee303e8a 100644
+--- a/fs/ntfs3/frecord.c
++++ b/fs/ntfs3/frecord.c
+@@ -102,7 +102,7 @@ void ni_clear(struct ntfs_inode *ni)
+ {
+ struct rb_node *node;
+
+- if (!ni->vfs_inode.i_nlink && is_rec_inuse(ni->mi.mrec))
++ if (!ni->vfs_inode.i_nlink && ni->mi.mrec && is_rec_inuse(ni->mi.mrec))
+ ni_delete_all(ni);
+
+ al_destroy(ni);
+--
+2.39.2
+
--- /dev/null
+From a51bc4a2287e7d65590657d7e49ce96d6ec12c0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Oct 2022 12:32:51 +0530
+Subject: fs/ntfs3: Fix NULL dereference in ni_write_inode
+
+From: Abdun Nihaal <abdun.nihaal@gmail.com>
+
+[ Upstream commit 8dae4f6341e335a09575be60b4fdf697c732a470 ]
+
+Syzbot reports a NULL dereference in ni_write_inode.
+When creating a new inode, if allocation fails in mi_init function
+(called in mi_format_new function), mi->mrec is set to NULL.
+In the error path of this inode creation, mi->mrec is later
+dereferenced in ni_write_inode.
+
+Add a NULL check to prevent NULL dereference.
+
+Link: https://syzkaller.appspot.com/bug?extid=f45957555ed4a808cc7a
+Reported-and-tested-by: syzbot+f45957555ed4a808cc7a@syzkaller.appspotmail.com
+Signed-off-by: Abdun Nihaal <abdun.nihaal@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/frecord.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
+index 7d0473da12c33..1103d4d9a4974 100644
+--- a/fs/ntfs3/frecord.c
++++ b/fs/ntfs3/frecord.c
+@@ -3258,6 +3258,9 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint)
+ return 0;
+ }
+
++ if (!ni->mi.mrec)
++ goto out;
++
+ if (is_rec_inuse(ni->mi.mrec) &&
+ !(sbi->flags & NTFS_FLAGS_LOG_REPLAYING) && inode->i_nlink) {
+ bool modified = false;
+--
+2.39.2
+
--- /dev/null
+From eb0d358aebd62b293f8df3409045cd94f78dbb6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 17:19:12 +0800
+Subject: fs/ntfs3: Fix NULL pointer dereference in 'ni_write_inode'
+
+From: Ye Bin <yebin10@huawei.com>
+
+[ Upstream commit db2a3cc6a3481076da6344cc62a80a4e2525f36f ]
+
+Syzbot found the following issue:
+Unable to handle kernel NULL pointer dereference at virtual address 0000000000000016
+Mem abort info:
+ ESR = 0x0000000096000006
+ EC = 0x25: DABT (current EL), IL = 32 bits
+ SET = 0, FnV = 0
+ EA = 0, S1PTW = 0
+ FSC = 0x06: level 2 translation fault
+Data abort info:
+ ISV = 0, ISS = 0x00000006
+ CM = 0, WnR = 0
+user pgtable: 4k pages, 48-bit VAs, pgdp=000000010af56000
+[0000000000000016] pgd=08000001090da003, p4d=08000001090da003, pud=08000001090ce003, pmd=0000000000000000
+Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
+Modules linked in:
+CPU: 1 PID: 3036 Comm: syz-executor206 Not tainted 6.0.0-rc6-syzkaller-17739-g16c9f284e746 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/26/2022
+pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : is_rec_inuse fs/ntfs3/ntfs.h:313 [inline]
+pc : ni_write_inode+0xac/0x798 fs/ntfs3/frecord.c:3232
+lr : ni_write_inode+0xa0/0x798 fs/ntfs3/frecord.c:3226
+sp : ffff8000126c3800
+x29: ffff8000126c3860 x28: 0000000000000000 x27: ffff0000c8b02000
+x26: ffff0000c7502320 x25: ffff0000c7502288 x24: 0000000000000000
+x23: ffff80000cbec91c x22: ffff0000c8b03000 x21: ffff0000c8b02000
+x20: 0000000000000001 x19: ffff0000c75024d8 x18: 00000000000000c0
+x17: ffff80000dd1b198 x16: ffff80000db59158 x15: ffff0000c4b6b500
+x14: 00000000000000b8 x13: 0000000000000000 x12: ffff0000c4b6b500
+x11: ff80800008be1b60 x10: 0000000000000000 x9 : ffff0000c4b6b500
+x8 : 0000000000000000 x7 : ffff800008be1b50 x6 : 0000000000000000
+x5 : 0000000000000000 x4 : 0000000000000001 x3 : 0000000000000000
+x2 : 0000000000000008 x1 : 0000000000000001 x0 : 0000000000000000
+Call trace:
+ is_rec_inuse fs/ntfs3/ntfs.h:313 [inline]
+ ni_write_inode+0xac/0x798 fs/ntfs3/frecord.c:3232
+ ntfs_evict_inode+0x54/0x84 fs/ntfs3/inode.c:1744
+ evict+0xec/0x334 fs/inode.c:665
+ iput_final fs/inode.c:1748 [inline]
+ iput+0x2c4/0x324 fs/inode.c:1774
+ ntfs_new_inode+0x7c/0xe0 fs/ntfs3/fsntfs.c:1660
+ ntfs_create_inode+0x20c/0xe78 fs/ntfs3/inode.c:1278
+ ntfs_create+0x54/0x74 fs/ntfs3/namei.c:100
+ lookup_open fs/namei.c:3413 [inline]
+ open_last_lookups fs/namei.c:3481 [inline]
+ path_openat+0x804/0x11c4 fs/namei.c:3688
+ do_filp_open+0xdc/0x1b8 fs/namei.c:3718
+ do_sys_openat2+0xb8/0x22c fs/open.c:1311
+ do_sys_open fs/open.c:1327 [inline]
+ __do_sys_openat fs/open.c:1343 [inline]
+ __se_sys_openat fs/open.c:1338 [inline]
+ __arm64_sys_openat+0xb0/0xe0 fs/open.c:1338
+ __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline]
+ invoke_syscall arch/arm64/kernel/syscall.c:52 [inline]
+ el0_svc_common+0x138/0x220 arch/arm64/kernel/syscall.c:142
+ do_el0_svc+0x48/0x164 arch/arm64/kernel/syscall.c:206
+ el0_svc+0x58/0x150 arch/arm64/kernel/entry-common.c:636
+ el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:654
+ el0t_64_sync+0x18c/0x190
+Code: 97dafee4 340001b4 f9401328 2a1f03e0 (79402d14)
+---[ end trace 0000000000000000 ]---
+
+Above issue may happens as follows:
+ntfs_new_inode
+ mi_init
+ mi->mrec = kmalloc(sbi->record_size, GFP_NOFS); -->failed to allocate memory
+ if (!mi->mrec)
+ return -ENOMEM;
+iput
+ iput_final
+ evict
+ ntfs_evict_inode
+ ni_write_inode
+ is_rec_inuse(ni->mi.mrec)-> As 'ni->mi.mrec' is NULL trigger NULL-ptr-deref
+
+To solve above issue if new inode failed make inode bad before call 'iput()' in
+'ntfs_new_inode()'.
+
+Reported-by: syzbot+f45957555ed4a808cc7a@syzkaller.appspotmail.com
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/fsntfs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c
+index 24c9aeb5a49e0..2c0ce364808a9 100644
+--- a/fs/ntfs3/fsntfs.c
++++ b/fs/ntfs3/fsntfs.c
+@@ -1683,6 +1683,7 @@ struct ntfs_inode *ntfs_new_inode(struct ntfs_sb_info *sbi, CLST rno, bool dir)
+
+ out:
+ if (err) {
++ make_bad_inode(inode);
+ iput(inode);
+ ni = ERR_PTR(err);
+ }
+--
+2.39.2
+
--- /dev/null
+From a3bce7af0e6ca9f4f7105a4fceb1ddcc84dfcbfa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Nov 2022 23:39:44 +0800
+Subject: fs/ntfs3: Validate MFT flags before replaying logs
+
+From: Edward Lo <edward.lo@ambergroup.io>
+
+[ Upstream commit 98bea253aa28ad8be2ce565a9ca21beb4a9419e5 ]
+
+Log load and replay is part of the metadata handle flow during mount
+operation. The $MFT record will be loaded and used while replaying logs.
+However, a malformed $MFT record, say, has RECORD_FLAG_DIR flag set and
+contains an ATTR_ROOT attribute will misguide kernel to treat it as a
+directory, and try to free the allocated resources when the
+corresponding inode is freed, which will cause an invalid kfree because
+the memory hasn't actually been allocated.
+
+[ 101.368647] BUG: KASAN: invalid-free in kvfree+0x2c/0x40
+[ 101.369457]
+[ 101.369986] CPU: 0 PID: 198 Comm: mount Not tainted 6.0.0-rc7+ #5
+[ 101.370529] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
+[ 101.371362] Call Trace:
+[ 101.371795] <TASK>
+[ 101.372157] dump_stack_lvl+0x49/0x63
+[ 101.372658] print_report.cold+0xf5/0x689
+[ 101.373022] ? ni_write_inode+0x754/0xd90
+[ 101.373378] ? kvfree+0x2c/0x40
+[ 101.373698] kasan_report_invalid_free+0x77/0xf0
+[ 101.374058] ? kvfree+0x2c/0x40
+[ 101.374352] ? kvfree+0x2c/0x40
+[ 101.374668] __kasan_slab_free+0x189/0x1b0
+[ 101.374992] ? kvfree+0x2c/0x40
+[ 101.375271] kfree+0x168/0x3b0
+[ 101.375717] kvfree+0x2c/0x40
+[ 101.376002] indx_clear+0x26/0x60
+[ 101.376316] ni_clear+0xc5/0x290
+[ 101.376661] ntfs_evict_inode+0x45/0x70
+[ 101.377001] evict+0x199/0x280
+[ 101.377432] iput.part.0+0x286/0x320
+[ 101.377819] iput+0x32/0x50
+[ 101.378166] ntfs_loadlog_and_replay+0x143/0x320
+[ 101.378656] ? ntfs_bio_fill_1+0x510/0x510
+[ 101.378968] ? iput.part.0+0x286/0x320
+[ 101.379367] ntfs_fill_super+0xecb/0x1ba0
+[ 101.379729] ? put_ntfs+0x1d0/0x1d0
+[ 101.380046] ? vsprintf+0x20/0x20
+[ 101.380542] ? mutex_unlock+0x81/0xd0
+[ 101.380914] ? set_blocksize+0x95/0x150
+[ 101.381597] get_tree_bdev+0x232/0x370
+[ 101.382254] ? put_ntfs+0x1d0/0x1d0
+[ 101.382699] ntfs_fs_get_tree+0x15/0x20
+[ 101.383094] vfs_get_tree+0x4c/0x130
+[ 101.383675] path_mount+0x654/0xfe0
+[ 101.384203] ? putname+0x80/0xa0
+[ 101.384540] ? finish_automount+0x2e0/0x2e0
+[ 101.384943] ? putname+0x80/0xa0
+[ 101.385362] ? kmem_cache_free+0x1c4/0x440
+[ 101.385968] ? putname+0x80/0xa0
+[ 101.386666] do_mount+0xd6/0xf0
+[ 101.387228] ? path_mount+0xfe0/0xfe0
+[ 101.387585] ? __kasan_check_write+0x14/0x20
+[ 101.387979] __x64_sys_mount+0xca/0x110
+[ 101.388436] do_syscall_64+0x3b/0x90
+[ 101.388757] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[ 101.389289] RIP: 0033:0x7fa0f70e948a
+[ 101.390048] Code: 48 8b 0d 11 fa 2a 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 49 89 ca b8 a5 00 00 008
+[ 101.391297] RSP: 002b:00007ffc24fdecc8 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
+[ 101.391988] RAX: ffffffffffffffda RBX: 000055932c183060 RCX: 00007fa0f70e948a
+[ 101.392494] RDX: 000055932c183260 RSI: 000055932c1832e0 RDI: 000055932c18bce0
+[ 101.393053] RBP: 0000000000000000 R08: 000055932c183280 R09: 0000000000000020
+[ 101.393577] R10: 00000000c0ed0000 R11: 0000000000000202 R12: 000055932c18bce0
+[ 101.394044] R13: 000055932c183260 R14: 0000000000000000 R15: 00000000ffffffff
+[ 101.394747] </TASK>
+[ 101.395402]
+[ 101.396047] Allocated by task 198:
+[ 101.396724] kasan_save_stack+0x26/0x50
+[ 101.397400] __kasan_slab_alloc+0x6d/0x90
+[ 101.397974] kmem_cache_alloc_lru+0x192/0x5a0
+[ 101.398524] ntfs_alloc_inode+0x23/0x70
+[ 101.399137] alloc_inode+0x3b/0xf0
+[ 101.399534] iget5_locked+0x54/0xa0
+[ 101.400026] ntfs_iget5+0xaf/0x1780
+[ 101.400414] ntfs_loadlog_and_replay+0xe5/0x320
+[ 101.400883] ntfs_fill_super+0xecb/0x1ba0
+[ 101.401313] get_tree_bdev+0x232/0x370
+[ 101.401774] ntfs_fs_get_tree+0x15/0x20
+[ 101.402224] vfs_get_tree+0x4c/0x130
+[ 101.402673] path_mount+0x654/0xfe0
+[ 101.403160] do_mount+0xd6/0xf0
+[ 101.403537] __x64_sys_mount+0xca/0x110
+[ 101.404058] do_syscall_64+0x3b/0x90
+[ 101.404333] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[ 101.404816]
+[ 101.405067] The buggy address belongs to the object at ffff888008cc9ea0
+[ 101.405067] which belongs to the cache ntfs_inode_cache of size 992
+[ 101.406171] The buggy address is located 232 bytes inside of
+[ 101.406171] 992-byte region [ffff888008cc9ea0, ffff888008cca280)
+[ 101.406995]
+[ 101.408559] The buggy address belongs to the physical page:
+[ 101.409320] page:00000000dccf19dd refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x8cc8
+[ 101.410654] head:00000000dccf19dd order:2 compound_mapcount:0 compound_pincount:0
+[ 101.411533] flags: 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff)
+[ 101.412665] raw: 000fffffc0010200 0000000000000000 dead000000000122 ffff888003695140
+[ 101.413209] raw: 0000000000000000 00000000800e000e 00000001ffffffff 0000000000000000
+[ 101.413799] page dumped because: kasan: bad access detected
+[ 101.414213]
+[ 101.414427] Memory state around the buggy address:
+[ 101.414991] ffff888008cc9e80: fc fc fc fc 00 00 00 00 00 00 00 00 00 00 00 00
+[ 101.415785] ffff888008cc9f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 101.416933] >ffff888008cc9f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 101.417857] ^
+[ 101.418566] ffff888008cca000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 101.419704] ffff888008cca080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+Signed-off-by: Edward Lo <edward.lo@ambergroup.io>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/inode.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
+index ce6bb3bd86b6e..059f288784580 100644
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -100,6 +100,12 @@ static struct inode *ntfs_read_mft(struct inode *inode,
+ /* Record should contain $I30 root. */
+ is_dir = rec->flags & RECORD_FLAG_DIR;
+
++ /* MFT_REC_MFT is not a dir */
++ if (is_dir && ino == MFT_REC_MFT) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ inode->i_generation = le16_to_cpu(rec->seq);
+
+ /* Enumerate all struct Attributes MFT. */
+--
+2.39.2
+
--- /dev/null
+From fd77073ae108a567f4bebbc19c3a3b807faf31cf 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 4d99cc77a29b7..b65950e76be5a 100644
+--- a/fs/gfs2/glops.c
++++ b/fs/gfs2/glops.c
+@@ -396,6 +396,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;
+@@ -442,7 +443,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 6d5ee868423fd15f742b6056ae95479d18e9e889 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 5c145775482bc..e2c73a78b5972 100644
+--- a/drivers/hid/hid-apple.c
++++ b/drivers/hid/hid-apple.c
+@@ -875,7 +875,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 17316207065579ddb7a4ab92a0a9fa3423e7d483 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 1ccab8aa326cd..5c145775482bc 100644
+--- a/drivers/hid/hid-apple.c
++++ b/drivers/hid/hid-apple.c
+@@ -882,7 +882,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 },
+@@ -901,7 +902,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 },
+@@ -942,31 +944,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 17324e08622a0a96f6b7c11a2d9bb37dc4400787 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 c2e9b6d1fd7d3..8f3e0a5d5f834 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 5c65a584b3fa0..5a88866505eab 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 7b969e812f24135724bd475021af36c0feb4a6b5 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 5fc88a0632978..66380876937f6 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -947,6 +947,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 */
+ /* -------------------------------------------------------------------------- */
+@@ -4210,6 +4259,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 5b675fdd3ea8c6ddd3e348703306d061b3b15cff 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 66380876937f6..da89e84c9cbeb 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -853,8 +853,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);
+@@ -989,8 +988,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 a9c8ea9c1228c91b1361c25a0d67028ce4057f77 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 f7613d1ba9ca4212c8db5c8fea86b8c730a43378 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Feb 2023 12:59:19 +0200
+Subject: hwmon: (nzxt-smart2) add another USB ID
+
+From: Aleksandr Mezin <mezin.alexander@gmail.com>
+
+[ Upstream commit 4a148e9b1ee04e608263fa9536a96214d5561220 ]
+
+This seems to be a new revision of the device. RGB controls have changed,
+but this driver doesn't touch them anyway.
+
+Fan speed control reported to be working with existing userspace (hidraw)
+software, so I assume it's compatible. Fan channel count is the same.
+
+Recently added (0x1e71, 0x2019) seems to be the same device.
+
+Discovered in liquidctl project:
+
+https://github.com/liquidctl/liquidctl/issues/541
+
+Signed-off-by: Aleksandr Mezin <mezin.alexander@gmail.com>
+Link: https://lore.kernel.org/r/20230219105924.333007-1-mezin.alexander@gmail.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/nzxt-smart2.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hwmon/nzxt-smart2.c b/drivers/hwmon/nzxt-smart2.c
+index 2b93ba89610ae..a8e72d8fd0605 100644
+--- a/drivers/hwmon/nzxt-smart2.c
++++ b/drivers/hwmon/nzxt-smart2.c
+@@ -791,7 +791,8 @@ static const struct hid_device_id nzxt_smart2_hid_id_table[] = {
+ { HID_USB_DEVICE(0x1e71, 0x2009) }, /* NZXT RGB & Fan Controller */
+ { HID_USB_DEVICE(0x1e71, 0x200e) }, /* NZXT RGB & Fan Controller */
+ { HID_USB_DEVICE(0x1e71, 0x2010) }, /* NZXT RGB & Fan Controller */
+- { HID_USB_DEVICE(0x1e71, 0x2019) }, /* NZXT RGB & Fan Controller */
++ { HID_USB_DEVICE(0x1e71, 0x2011) }, /* NZXT RGB & Fan Controller (6 RGB) */
++ { HID_USB_DEVICE(0x1e71, 0x2019) }, /* NZXT RGB & Fan Controller (6 RGB) */
+ {},
+ };
+
+--
+2.39.2
+
--- /dev/null
+From b36f36cf156110ed32141d90fe69c46dcfe127f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Feb 2023 12:14:56 +0100
+Subject: iio: imu: st_lsm6dsx: discard samples during filters settling time
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit db3c490503bee4d0611f9fc17fcd8cfe6fcdbcad ]
+
+During digital filters settling time the driver is expected to drop
+samples since they can be corrupted. Introduce the capability to drop
+a given number of samples according to the configured ODR.
+Add sample_to_discard for LSM6DSM-like sensors since new generation
+devices (e.g. LSM6DSO) support DRDY mask where corrupted samples are
+masked in hw with values greather than 0x7ffd so the driver can easily
+discard them.
+I have not added sample_to_discard support for LSM6DS3 or LSM6DS3H since
+I do not have any sample for testing at the moment.
+
+Reported-by: Philippe De Muyter <phdm@macqel.be>
+Tested-by: Philippe De Muyter <phdm@macqel.be>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/r/21dcd94935c147ef9b1da4984b3da6264ee9609e.1677496295.git.lorenzo@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 11 ++++
+ .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 57 ++++++++++++++++---
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 18 ++++++
+ 3 files changed, 78 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+index 499fcf8875b40..8e119d78730ba 100644
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+@@ -137,6 +137,13 @@ struct st_lsm6dsx_odr_table_entry {
+ int odr_len;
+ };
+
++struct st_lsm6dsx_samples_to_discard {
++ struct {
++ u32 milli_hz;
++ u16 samples;
++ } val[ST_LSM6DSX_ODR_LIST_SIZE];
++};
++
+ struct st_lsm6dsx_fs {
+ u32 gain;
+ u8 val;
+@@ -291,6 +298,7 @@ struct st_lsm6dsx_ext_dev_settings {
+ * @irq_config: interrupts related registers.
+ * @drdy_mask: register info for data-ready mask (addr + mask).
+ * @odr_table: Hw sensors odr table (Hz + val).
++ * @samples_to_discard: Number of samples to discard for filters settling time.
+ * @fs_table: Hw sensors gain table (gain + val).
+ * @decimator: List of decimator register info (addr + mask).
+ * @batch: List of FIFO batching register info (addr + mask).
+@@ -323,6 +331,7 @@ struct st_lsm6dsx_settings {
+ } irq_config;
+ struct st_lsm6dsx_reg drdy_mask;
+ struct st_lsm6dsx_odr_table_entry odr_table[2];
++ struct st_lsm6dsx_samples_to_discard samples_to_discard[2];
+ struct st_lsm6dsx_fs_table_entry fs_table[2];
+ struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID];
+ struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID];
+@@ -353,6 +362,7 @@ enum st_lsm6dsx_fifo_mode {
+ * @hw: Pointer to instance of struct st_lsm6dsx_hw.
+ * @gain: Configured sensor sensitivity.
+ * @odr: Output data rate of the sensor [Hz].
++ * @samples_to_discard: Number of samples to discard for filters settling time.
+ * @watermark: Sensor watermark level.
+ * @decimator: Sensor decimation factor.
+ * @sip: Number of samples in a given pattern.
+@@ -367,6 +377,7 @@ struct st_lsm6dsx_sensor {
+ u32 gain;
+ u32 odr;
+
++ u16 samples_to_discard;
+ u16 watermark;
+ u8 decimator;
+ u8 sip;
+diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
+index 7dd5205aea5b4..f6c11d6fb0b0f 100644
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
+@@ -457,17 +457,31 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
+ }
+
+ if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) {
+- iio_push_to_buffers_with_timestamp(
+- hw->iio_devs[ST_LSM6DSX_ID_GYRO],
+- &hw->scan[ST_LSM6DSX_ID_GYRO],
+- gyro_sensor->ts_ref + ts);
++ /*
++ * We need to discards gyro samples during
++ * filters settling time
++ */
++ if (gyro_sensor->samples_to_discard > 0)
++ gyro_sensor->samples_to_discard--;
++ else
++ iio_push_to_buffers_with_timestamp(
++ hw->iio_devs[ST_LSM6DSX_ID_GYRO],
++ &hw->scan[ST_LSM6DSX_ID_GYRO],
++ gyro_sensor->ts_ref + ts);
+ gyro_sip--;
+ }
+ if (acc_sip > 0 && !(sip % acc_sensor->decimator)) {
+- iio_push_to_buffers_with_timestamp(
+- hw->iio_devs[ST_LSM6DSX_ID_ACC],
+- &hw->scan[ST_LSM6DSX_ID_ACC],
+- acc_sensor->ts_ref + ts);
++ /*
++ * We need to discards accel samples during
++ * filters settling time
++ */
++ if (acc_sensor->samples_to_discard > 0)
++ acc_sensor->samples_to_discard--;
++ else
++ iio_push_to_buffers_with_timestamp(
++ hw->iio_devs[ST_LSM6DSX_ID_ACC],
++ &hw->scan[ST_LSM6DSX_ID_ACC],
++ acc_sensor->ts_ref + ts);
+ acc_sip--;
+ }
+ if (ext_sip > 0 && !(sip % ext_sensor->decimator)) {
+@@ -654,6 +668,30 @@ int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
+ return err;
+ }
+
++static void
++st_lsm6dsx_update_samples_to_discard(struct st_lsm6dsx_sensor *sensor)
++{
++ const struct st_lsm6dsx_samples_to_discard *data;
++ struct st_lsm6dsx_hw *hw = sensor->hw;
++ int i;
++
++ if (sensor->id != ST_LSM6DSX_ID_GYRO &&
++ sensor->id != ST_LSM6DSX_ID_ACC)
++ return;
++
++ /* check if drdy mask is supported in hw */
++ if (hw->settings->drdy_mask.addr)
++ return;
++
++ data = &hw->settings->samples_to_discard[sensor->id];
++ for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) {
++ if (data->val[i].milli_hz == sensor->odr) {
++ sensor->samples_to_discard = data->val[i].samples;
++ return;
++ }
++ }
++}
++
+ int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable)
+ {
+ struct st_lsm6dsx_hw *hw = sensor->hw;
+@@ -673,6 +711,9 @@ int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable)
+ goto out;
+ }
+
++ if (enable)
++ st_lsm6dsx_update_samples_to_discard(sensor);
++
+ err = st_lsm6dsx_device_set_enable(sensor, enable);
+ if (err < 0)
+ goto out;
+diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+index 3f6060c64f32b..966df6ffe8740 100644
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+@@ -634,6 +634,24 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+ .fs_len = 4,
+ },
+ },
++ .samples_to_discard = {
++ [ST_LSM6DSX_ID_ACC] = {
++ .val[0] = { 12500, 1 },
++ .val[1] = { 26000, 1 },
++ .val[2] = { 52000, 1 },
++ .val[3] = { 104000, 2 },
++ .val[4] = { 208000, 2 },
++ .val[5] = { 416000, 2 },
++ },
++ [ST_LSM6DSX_ID_GYRO] = {
++ .val[0] = { 12500, 2 },
++ .val[1] = { 26000, 5 },
++ .val[2] = { 52000, 7 },
++ .val[3] = { 104000, 12 },
++ .val[4] = { 208000, 20 },
++ .val[5] = { 416000, 36 },
++ },
++ },
+ .irq_config = {
+ .irq1 = {
+ .addr = 0x0d,
+--
+2.39.2
+
--- /dev/null
+From bdc6e65f1554403e8a4c178122227d03d66d7163 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Apr 2023 23:57:42 -0700
+Subject: Input: xpad - add constants for GIP interface numbers
+
+From: Vicki Pfau <vi@endrift.com>
+
+[ Upstream commit f9b2e603c6216824e34dc9a67205d98ccc9a41ca ]
+
+Wired GIP devices present multiple interfaces with the same USB identification
+other than the interface number. This adds constants for differentiating two of
+them and uses them where appropriate
+
+Signed-off-by: Vicki Pfau <vi@endrift.com>
+Link: https://lore.kernel.org/r/20230411031650.960322-2-vi@endrift.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/joystick/xpad.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
+index 29131f1a2f067..f617b2c60819c 100644
+--- a/drivers/input/joystick/xpad.c
++++ b/drivers/input/joystick/xpad.c
+@@ -559,6 +559,9 @@ struct xboxone_init_packet {
+ #define GIP_MOTOR_LT BIT(3)
+ #define GIP_MOTOR_ALL (GIP_MOTOR_R | GIP_MOTOR_L | GIP_MOTOR_RT | GIP_MOTOR_LT)
+
++#define GIP_WIRED_INTF_DATA 0
++#define GIP_WIRED_INTF_AUDIO 1
++
+ /*
+ * This packet is required for all Xbox One pads with 2015
+ * or later firmware installed (or present from the factory).
+@@ -2003,7 +2006,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
+ }
+
+ if (xpad->xtype == XTYPE_XBOXONE &&
+- intf->cur_altsetting->desc.bInterfaceNumber != 0) {
++ intf->cur_altsetting->desc.bInterfaceNumber != GIP_WIRED_INTF_DATA) {
+ /*
+ * The Xbox One controller lists three interfaces all with the
+ * same interface class, subclass and protocol. Differentiate by
+--
+2.39.2
+
--- /dev/null
+From c49e0f94bc7fbd3d7b92b32e67876ec281cf8ab8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Mar 2023 09:41:16 +0100
+Subject: iommu/arm-smmu: Drop if with an always false condition
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit a2972cb89935160bfe515b15d28a77694723ac06 ]
+
+The remove and shutdown callback are only called after probe completed
+successfully. In this case platform_set_drvdata() was called with a
+non-NULL argument and so smmu is never NULL. Other functions in this
+driver also don't check for smmu being non-NULL before using it.
+
+Also note that returning an error code from a remove callback doesn't
+result in the device staying bound. It's still removed and devm allocated
+resources are freed (among others *smmu and the register mapping). So
+after an early exit to iommu device stayed around and using it probably
+oopses.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/20230321084125.337021-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/arm/arm-smmu/arm-smmu.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
+index 2ff7a72cf3772..f4a36533ae478 100644
+--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
++++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
+@@ -2195,9 +2195,6 @@ static void arm_smmu_device_shutdown(struct platform_device *pdev)
+ {
+ struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
+
+- if (!smmu)
+- return;
+-
+ if (!bitmap_empty(smmu->context_map, ARM_SMMU_MAX_CBS))
+ dev_notice(&pdev->dev, "disabling translation\n");
+
+@@ -2218,9 +2215,6 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
+ {
+ struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
+
+- if (!smmu)
+- return -ENODEV;
+-
+ iommu_device_unregister(&smmu->iommu);
+ iommu_device_sysfs_remove(&smmu->iommu);
+
+--
+2.39.2
+
--- /dev/null
+From e84db11499a0f2a2aa26e8de4dbb5c8e6945ed26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Mar 2023 13:30:29 +0530
+Subject: iommu/arm-smmu-qcom: Limit the SMR groups to 128
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 12261134732689b7e30c59db9978f81230965181 ]
+
+Some platforms support more than 128 stream matching groups than what is
+defined by the ARM SMMU architecture specification. But due to some unknown
+reasons, those additional groups don't exhibit the same behavior as the
+architecture supported ones.
+
+For instance, the additional groups will not detect the quirky behavior of
+some firmware versions intercepting writes to S2CR register, thus skipping
+the quirk implemented in the driver and causing boot crash.
+
+So let's limit the groups to 128 for now until the issue with those groups
+are fixed and issue a notice to users in that case.
+
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Tested-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20230327080029.11584-1-manivannan.sadhasivam@linaro.org
+[will: Reworded the comment slightly]
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+index d1b296b95c860..ae09c627bc844 100644
+--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
++++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+@@ -268,12 +268,26 @@ static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
+
+ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
+ {
+- unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1);
+ struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
++ unsigned int last_s2cr;
+ u32 reg;
+ u32 smr;
+ int i;
+
++ /*
++ * Some platforms support more than the Arm SMMU architected maximum of
++ * 128 stream matching groups. For unknown reasons, the additional
++ * groups don't exhibit the same behavior as the architected registers,
++ * so limit the groups to 128 until the behavior is fixed for the other
++ * groups.
++ */
++ if (smmu->num_mapping_groups > 128) {
++ dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n");
++ smmu->num_mapping_groups = 128;
++ }
++
++ last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1);
++
+ /*
+ * With some firmware versions writes to S2CR of type FAULT are
+ * ignored, and writing BYPASS will end up written as FAULT in the
+--
+2.39.2
+
--- /dev/null
+From 167b052f825d1b2233716222e24ae8b3a0aba087 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Mar 2023 12:34:19 +0000
+Subject: iommu/arm-smmu-v3: Acknowledge pri/event queue overflow if any
+
+From: Tomas Krcka <krckatom@amazon.de>
+
+[ Upstream commit 67ea0b7ce41844eae7c10bb04dfe66a23318c224 ]
+
+When an overflow occurs in the PRI queue, the SMMU toggles the overflow
+flag in the PROD register. To exit the overflow condition, the PRI thread
+is supposed to acknowledge it by toggling this flag in the CONS register.
+Unacknowledged overflow causes the queue to stop adding anything new.
+
+Currently, the priq thread always writes the CONS register back to the
+SMMU after clearing the queue.
+
+The writeback is not necessary if the OVFLG in the PROD register has not
+been changed, no overflow has occured.
+
+This commit checks the difference of the overflow flag between CONS and
+PROD register. If it's different, toggles the OVACKFLG flag in the CONS
+register and write it to the SMMU.
+
+The situation is similar for the event queue.
+The acknowledge register is also toggled after clearing the event
+queue but never propagated to the hardware. This would only be done the
+next time when executing evtq thread.
+
+Unacknowledged event queue overflow doesn't affect the event
+queue, because the SMMU still adds elements to that queue when the
+overflow condition is active.
+But it feel nicer to keep SMMU in sync when possible, so use the same
+way here as well.
+
+Signed-off-by: Tomas Krcka <krckatom@amazon.de>
+Link: https://lore.kernel.org/r/20230329123420.34641-1-tomas.krcka@gmail.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+index f2425b0f0cd62..7614739ea2c1b 100644
+--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+@@ -152,6 +152,18 @@ static void queue_inc_cons(struct arm_smmu_ll_queue *q)
+ q->cons = Q_OVF(q->cons) | Q_WRP(q, cons) | Q_IDX(q, cons);
+ }
+
++static void queue_sync_cons_ovf(struct arm_smmu_queue *q)
++{
++ struct arm_smmu_ll_queue *llq = &q->llq;
++
++ if (likely(Q_OVF(llq->prod) == Q_OVF(llq->cons)))
++ return;
++
++ llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
++ Q_IDX(llq, llq->cons);
++ queue_sync_cons_out(q);
++}
++
+ static int queue_sync_prod_in(struct arm_smmu_queue *q)
+ {
+ u32 prod;
+@@ -1577,8 +1589,7 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev)
+ } while (!queue_empty(llq));
+
+ /* Sync our overflow flag, as we believe we're up to speed */
+- llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
+- Q_IDX(llq, llq->cons);
++ queue_sync_cons_ovf(q);
+ return IRQ_HANDLED;
+ }
+
+@@ -1636,9 +1647,7 @@ static irqreturn_t arm_smmu_priq_thread(int irq, void *dev)
+ } while (!queue_empty(llq));
+
+ /* Sync our overflow flag, as we believe we're up to speed */
+- llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
+- Q_IDX(llq, llq->cons);
+- queue_sync_cons_out(q);
++ queue_sync_cons_ovf(q);
+ return IRQ_HANDLED;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 2575b2b844617300bcc073cde35e9cf2b2a1b703 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Mar 2023 11:31:23 +0800
+Subject: iommu/sprd: Release dma buffer to avoid memory leak
+
+From: Chunyan Zhang <chunyan.zhang@unisoc.com>
+
+[ Upstream commit 9afea57384d4ae7b2034593eac7fa76c7122762a ]
+
+When attaching to a domain, the driver would alloc a DMA buffer which
+is used to store address mapping table, and it need to be released
+when the IOMMU domain is freed.
+
+Signed-off-by: Chunyan Zhang <chunyan.zhang@unisoc.com>
+Link: https://lore.kernel.org/r/20230331033124.864691-2-zhang.lyra@gmail.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/sprd-iommu.c | 29 ++++++++++++++++++++++-------
+ 1 file changed, 22 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
+index ae94d74b73f46..7df1f730c778e 100644
+--- a/drivers/iommu/sprd-iommu.c
++++ b/drivers/iommu/sprd-iommu.c
+@@ -151,13 +151,6 @@ static struct iommu_domain *sprd_iommu_domain_alloc(unsigned int domain_type)
+ return &dom->domain;
+ }
+
+-static void sprd_iommu_domain_free(struct iommu_domain *domain)
+-{
+- struct sprd_iommu_domain *dom = to_sprd_domain(domain);
+-
+- kfree(dom);
+-}
+-
+ static void sprd_iommu_first_vpn(struct sprd_iommu_domain *dom)
+ {
+ struct sprd_iommu_device *sdev = dom->sdev;
+@@ -230,6 +223,28 @@ static void sprd_iommu_hw_en(struct sprd_iommu_device *sdev, bool en)
+ sprd_iommu_update_bits(sdev, reg_cfg, mask, 0, val);
+ }
+
++static void sprd_iommu_cleanup(struct sprd_iommu_domain *dom)
++{
++ size_t pgt_size;
++
++ /* Nothing need to do if the domain hasn't been attached */
++ if (!dom->sdev)
++ return;
++
++ pgt_size = sprd_iommu_pgt_size(&dom->domain);
++ dma_free_coherent(dom->sdev->dev, pgt_size, dom->pgt_va, dom->pgt_pa);
++ dom->sdev = NULL;
++ sprd_iommu_hw_en(dom->sdev, false);
++}
++
++static void sprd_iommu_domain_free(struct iommu_domain *domain)
++{
++ struct sprd_iommu_domain *dom = to_sprd_domain(domain);
++
++ sprd_iommu_cleanup(dom);
++ kfree(dom);
++}
++
+ static int sprd_iommu_attach_device(struct iommu_domain *domain,
+ struct device *dev)
+ {
+--
+2.39.2
+
--- /dev/null
+From 9025e6cd2bc17f2193caa71997e6726bf775e3b3 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 6d71a5ff52dfd..e20f1f92066d1 100644
+--- a/include/net/ip_vs.h
++++ b/include/net/ip_vs.h
+@@ -630,8 +630,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 7aa9a281e6992a527bce74ed997cd2da2823c4aa 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 ec5f889d76819..e31f6c0687041 100644
+--- a/Documentation/arm64/silicon-errata.rst
++++ b/Documentation/arm64/silicon-errata.rst
+@@ -172,6 +172,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 7dc990eb2c9ba..9efb383fc688f 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 fd134e1f481a2..6fcee221f2017 100644
+--- a/drivers/irqchip/irq-gic-v3.c
++++ b/drivers/irqchip/irq-gic-v3.c
+@@ -24,6 +24,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>
+@@ -47,6 +50,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;
+@@ -59,6 +63,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);
+
+@@ -179,6 +187,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)) {
+@@ -337,7 +378,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);
+ }
+@@ -588,7 +629,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);
+
+@@ -1708,6 +1749,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",
+@@ -1739,6 +1817,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,
++ },
+ {
+ }
+ };
+@@ -1798,7 +1882,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,
+@@ -1814,6 +1899,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;
+@@ -1841,10 +1927,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;
+@@ -2050,6 +2139,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;
+@@ -2063,6 +2153,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);
+@@ -2094,8 +2186,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;
+
+@@ -2411,8 +2503,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 6ff036b60f2b1f338b2997945f1e36079844f0aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Mar 2023 18:45:28 +0400
+Subject: KVM: selftests: Add 'malloc' failure check in vcpu_save_state
+
+From: Ivan Orlov <ivan.orlov0322@gmail.com>
+
+[ Upstream commit 735b0e0f2d001b7ed9486db84453fb860e764a4d ]
+
+There is a 'malloc' call in vcpu_save_state function, which can
+be unsuccessful. This patch will add the malloc failure checking
+to avoid possible null dereference and give more information
+about test fail reasons.
+
+Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
+Link: https://lore.kernel.org/r/20230322144528.704077-1-ivan.orlov0322@gmail.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/kvm/lib/x86_64/processor.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
+index c39a4353ba194..827647ff3d41b 100644
+--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
++++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
+@@ -954,6 +954,7 @@ struct kvm_x86_state *vcpu_save_state(struct kvm_vcpu *vcpu)
+ vcpu_run_complete_io(vcpu);
+
+ state = malloc(sizeof(*state) + msr_list->nmsrs * sizeof(state->msrs.entries[0]));
++ TEST_ASSERT(state, "-ENOMEM when allocating kvm state");
+
+ vcpu_events_get(vcpu, &state->events);
+ vcpu_mp_state_get(vcpu, &state->mp_state);
+--
+2.39.2
+
--- /dev/null
+From 157148be7c272dc7856cf70c2ba509eb8801b603 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 7628a3304e3657655f0f621f16c57b723db7413e 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 561126ad26280f8327be0f5d47c6c19906b05271 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 68e3ac4aa49ad328de3307334e4b011ee0dcc35c 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 13321dbb5fbcf..d479e1656ef33 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -8029,16 +8029,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 c0316dc4e63ad1835fb4df7a6ea8c9be90d09ef7 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 b5a58ece097ab373fea56ccde7e57ede8d49359f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Feb 2023 19:38:05 +0100
+Subject: media: imx-jpeg: Bounds check sizeimage access
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 474acc639fc8671fa4c1919d9e03253c82b6d321 ]
+
+The call of mxc_jpeg_get_plane_size() from mxc_jpeg_dec_irq() sets
+plane_no argument to 1. The compiler sees that it's possible to end up
+with an access beyond the bounds of sizeimage, if mem_planes was too
+large:
+
+ if (plane_no >= fmt->mem_planes) // mem_planes = 2+
+ return 0;
+
+ if (fmt->mem_planes == fmt->comp_planes) // comp_planes != mem_planes
+ return q_data->sizeimage[plane_no];
+
+ if (plane_no < fmt->mem_planes - 1) // mem_planes = 2
+ return q_data->sizeimage[plane_no];
+
+comp_planes == 0 or 1 is safe. comp_planes > 2 would be out of bounds.
+
+(This isn't currently possible given the contents of mxc_formats, though.)
+
+Silence the warning by bounds checking comp_planes for future
+robustness. Seen with GCC 13:
+
+In function 'mxc_jpeg_get_plane_size',
+ inlined from 'mxc_jpeg_dec_irq' at ../drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c:729:14:
+../drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c:641:42: warning: array subscript 2 is above array bounds of 'u32[2]' {aka 'unsigned int[2]'} [-Warray-bounds=]
+ 641 | size += q_data->sizeimage[i];
+ | ~~~~~~~~~~~~~~~~~^~~
+In file included from ../drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h:112,
+ from ../drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c:63:
+../drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h: In function 'mxc_jpeg_dec_irq':
+../drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h:84:41: note: while referencing 'sizeimage'
+ 84 | u32 sizeimage[MXC_JPEG_MAX_PLANES];
+ | ^~~~~~~~~
+
+Cc: Mirela Rabulea <mirela.rabulea@nxp.com>
+Cc: NXP Linux Team <linux-imx@nxp.com>
+Cc: Shawn Guo <shawnguo@kernel.org>
+Cc: Sascha Hauer <s.hauer@pengutronix.de>
+Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
+Cc: Fabio Estevam <festevam@gmail.com>
+Cc: linux-arm-kernel@lists.infradead.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+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/nxp/imx-jpeg/mxc-jpeg.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index f085f14d676ad..c898116b763a2 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -637,6 +637,11 @@ static u32 mxc_jpeg_get_plane_size(struct mxc_jpeg_q_data *q_data, u32 plane_no)
+ return q_data->sizeimage[plane_no];
+
+ size = q_data->sizeimage[fmt->mem_planes - 1];
++
++ /* Should be impossible given mxc_formats. */
++ if (WARN_ON_ONCE(fmt->comp_planes > ARRAY_SIZE(q_data->sizeimage)))
++ return size;
++
+ for (i = fmt->mem_planes; i < fmt->comp_planes; i++)
+ size += q_data->sizeimage[i];
+
+--
+2.39.2
+
--- /dev/null
+From dd0c54f21eb51f1f135e5e1404adedc734254630 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Mar 2023 23:19:10 +0800
+Subject: media: ipu3-cio2: support multiple sensors and VCMs with same HID
+
+From: Bingbu Cao <bingbu.cao@intel.com>
+
+[ Upstream commit 567f97bd381fd79fa8563808118fc757cb6fa4ff ]
+
+In current cio2-bridge, it is using the hid name to register software
+node and software node will create kobject and sysfs entry according to
+the node name, if there are multiple sensors and VCMs which are sharing
+same HID name, it will cause the software nodes registration failure:
+
+sysfs: cannot create duplicate filename '/kernel/software_nodes/dw9714'
+...
+Call Trace:
+software_node_register_nodes
+cio2_bridge_init
+...
+kobject_add_internal failed for dw9714 with -EEXIST,
+don't try to register things with the same name in the same directory.
+
+One solution is appending the sensor link(Mipi Port) in SSDB as suffix
+of the node name to fix this problem.
+
+Signed-off-by: Bingbu Cao <bingbu.cao@intel.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/intel/ipu3/cio2-bridge.c | 15 +++++++++++----
+ drivers/media/pci/intel/ipu3/cio2-bridge.h | 3 ++-
+ 2 files changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
+index dfefe0d8aa959..45427a3a3a252 100644
+--- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
++++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
+@@ -212,6 +212,7 @@ static void cio2_bridge_create_connection_swnodes(struct cio2_bridge *bridge,
+ struct cio2_sensor *sensor)
+ {
+ struct software_node *nodes = sensor->swnodes;
++ char vcm_name[ACPI_ID_LEN + 4];
+
+ cio2_bridge_init_swnode_names(sensor);
+
+@@ -229,9 +230,13 @@ static void cio2_bridge_create_connection_swnodes(struct cio2_bridge *bridge,
+ sensor->node_names.endpoint,
+ &nodes[SWNODE_CIO2_PORT],
+ sensor->cio2_properties);
+- if (sensor->ssdb.vcmtype)
+- nodes[SWNODE_VCM] =
+- NODE_VCM(cio2_vcm_types[sensor->ssdb.vcmtype - 1]);
++ if (sensor->ssdb.vcmtype) {
++ /* append ssdb.link to distinguish VCM nodes with same HID */
++ snprintf(vcm_name, sizeof(vcm_name), "%s-%u",
++ cio2_vcm_types[sensor->ssdb.vcmtype - 1],
++ sensor->ssdb.link);
++ nodes[SWNODE_VCM] = NODE_VCM(vcm_name);
++ }
+
+ cio2_bridge_init_swnode_group(sensor);
+ }
+@@ -295,7 +300,6 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
+ }
+
+ sensor = &bridge->sensors[bridge->n_sensors];
+- strscpy(sensor->name, cfg->hid, sizeof(sensor->name));
+
+ ret = cio2_bridge_read_acpi_buffer(adev, "SSDB",
+ &sensor->ssdb,
+@@ -303,6 +307,9 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
+ if (ret)
+ goto err_put_adev;
+
++ snprintf(sensor->name, sizeof(sensor->name), "%s-%u",
++ cfg->hid, sensor->ssdb.link);
++
+ if (sensor->ssdb.vcmtype > ARRAY_SIZE(cio2_vcm_types)) {
+ dev_warn(&adev->dev, "Unknown VCM type %d\n",
+ sensor->ssdb.vcmtype);
+diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
+index b93b749c65bda..b76ed8a641e20 100644
+--- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
++++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
+@@ -113,7 +113,8 @@ struct cio2_sensor_config {
+ };
+
+ struct cio2_sensor {
+- char name[ACPI_ID_LEN];
++ /* append ssdb.link(u8) in "-%u" format as suffix of HID */
++ char name[ACPI_ID_LEN + 4];
+ struct acpi_device *adev;
+ struct i2c_client *vcm_i2c_client;
+
+--
+2.39.2
+
--- /dev/null
+From c726d1b4af7cee3f3d50b0d94a1caee944dec448 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 55eee07aa14414a91366598f7f56a1075b61d4c0 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 de3d77ce67fe58c00c58f8c6b9314dda626c0ac6 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 411e907b68eba..b545750ca5262 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 05548eab7daad..74fb0d185a8ff 100644
+--- a/drivers/staging/media/omap4iss/iss_video.c
++++ b/drivers/staging/media/omap4iss/iss_video.c
+@@ -237,7 +237,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;
+@@ -246,9 +248,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 b91d2cda8b1d8208f5da60ac9763ecd0ec9d88b8 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 c1dc5ffd0fe5fb29311c7d6a77d588dc6a9e4138 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 dffc1d65247791bdd560b106005ed1632a29d162 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 f36de553c5be4cf5d22de0b38c6dee989399b0f4 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 c386c3d010075f0b0002653a787c8d32145f412b 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 d53dae2554906..871776d511e31 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"),
+ },
+ }, {
+ /* Lenovo Yoga Tab 3 Pro YT3-X90F */
+--
+2.39.2
+
--- /dev/null
+From 5fb8e15637afbd63fb90551e716045901a9d9bc7 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 592cfa8b765a5..e1c954094b6c0 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);
+
+@@ -1111,6 +1114,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 0338c8d37cf4d9d3bce0dacbcc87ecf1a2c7976f 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 8fbd241849c01..b3d8e74fcaf06 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2535,6 +2535,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 e7eaa74c71db5e079abfc0b198c861044ec4a710 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 525e094a95c4a440abbbecfed64c62bb2269d781 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Apr 2023 21:01:53 +0300
+Subject: net/sched: pass netlink extack to mqprio and taprio offload
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit c54876cd5961ce0f8e74807f79a6739cd6b35ddf ]
+
+With the multiplexed ndo_setup_tc() model which lacks a first-class
+struct netlink_ext_ack * argument, the only way to pass the netlink
+extended ACK message down to the device driver is to embed it within the
+offload structure.
+
+Do this for struct tc_mqprio_qopt_offload and struct tc_taprio_qopt_offload.
+
+Since struct tc_taprio_qopt_offload also contains a tc_mqprio_qopt_offload
+structure, and since device drivers might effectively reuse their mqprio
+implementation for the mqprio portion of taprio, we make taprio set the
+extack in both offload structures to point at the same netlink extack
+message.
+
+In fact, the taprio handling is a bit more tricky, for 2 reasons.
+
+First is because the offload structure has a longer lifetime than the
+extack structure. The driver is supposed to populate the extack
+synchronously from ndo_setup_tc() and leave it alone afterwards.
+To not have any use-after-free surprises, we zero out the extack pointer
+when we leave taprio_enable_offload().
+
+The second reason is because taprio does overwrite the extack message on
+ndo_setup_tc() error. We need to switch to the weak form of setting an
+extack message, which preserves a potential message set by the driver.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/pkt_sched.h | 2 ++
+ net/sched/sch_mqprio.c | 5 ++++-
+ net/sched/sch_taprio.c | 12 ++++++++++--
+ 3 files changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
+index 2016839991a42..fc688c7e95951 100644
+--- a/include/net/pkt_sched.h
++++ b/include/net/pkt_sched.h
+@@ -167,6 +167,7 @@ struct tc_mqprio_caps {
+ struct tc_mqprio_qopt_offload {
+ /* struct tc_mqprio_qopt must always be the first element */
+ struct tc_mqprio_qopt qopt;
++ struct netlink_ext_ack *extack;
+ u16 mode;
+ u16 shaper;
+ u32 flags;
+@@ -194,6 +195,7 @@ struct tc_taprio_sched_entry {
+
+ struct tc_taprio_qopt_offload {
+ struct tc_mqprio_qopt_offload mqprio;
++ struct netlink_ext_ack *extack;
+ u8 enable;
+ ktime_t base_time;
+ u64 cycle_time;
+diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
+index 48ed87b91086e..fc6225f15fcdb 100644
+--- a/net/sched/sch_mqprio.c
++++ b/net/sched/sch_mqprio.c
+@@ -33,9 +33,12 @@ static int mqprio_enable_offload(struct Qdisc *sch,
+ const struct tc_mqprio_qopt *qopt,
+ struct netlink_ext_ack *extack)
+ {
+- struct tc_mqprio_qopt_offload mqprio = {.qopt = *qopt};
+ struct mqprio_sched *priv = qdisc_priv(sch);
+ struct net_device *dev = qdisc_dev(sch);
++ struct tc_mqprio_qopt_offload mqprio = {
++ .qopt = *qopt,
++ .extack = extack,
++ };
+ int err, i;
+
+ switch (priv->mode) {
+diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
+index 1f469861eae32..cbad430191721 100644
+--- a/net/sched/sch_taprio.c
++++ b/net/sched/sch_taprio.c
+@@ -1520,7 +1520,9 @@ static int taprio_enable_offload(struct net_device *dev,
+ return -ENOMEM;
+ }
+ offload->enable = 1;
++ offload->extack = extack;
+ mqprio_qopt_reconstruct(dev, &offload->mqprio.qopt);
++ offload->mqprio.extack = extack;
+ taprio_sched_to_offload(dev, sched, offload, &caps);
+
+ for (tc = 0; tc < TC_MAX_QUEUE; tc++)
+@@ -1528,14 +1530,20 @@ static int taprio_enable_offload(struct net_device *dev,
+
+ err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_TAPRIO, offload);
+ if (err < 0) {
+- NL_SET_ERR_MSG(extack,
+- "Device failed to setup taprio offload");
++ NL_SET_ERR_MSG_WEAK(extack,
++ "Device failed to setup taprio offload");
+ goto done;
+ }
+
+ q->offloaded = true;
+
+ done:
++ /* The offload structure may linger around via a reference taken by the
++ * device driver, so clear up the netlink extack pointer so that the
++ * driver isn't tempted to dereference data which stopped being valid
++ */
++ offload->extack = NULL;
++ offload->mqprio.extack = NULL;
+ taprio_offload_free(offload);
+
+ return err;
+--
+2.39.2
+
--- /dev/null
+From ea5bcad95921a77446d1eaa01c0204756e82d01e 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 c35f04f636f15..7db9f960221d3 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -2463,6 +2463,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 80294a851a1b3035a61f14b659a9133a074448b9 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 9e6b032c8ecc2..14491952047f5 100644
+--- a/drivers/block/null_blk/main.c
++++ b/drivers/block/null_blk/main.c
+@@ -1964,6 +1964,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 d257b3c7e287ea758b8a9b4a2b21aeeff83e3fb4 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 4401a73d4032d..4478adcc4f3a0 100644
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -1196,13 +1196,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 9ab368cd8ced32746b051bedabcfccc0e5e1ad5a 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 40793bef8429f..2b4fad8328e85 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 6817892a2c585..cc124d9f1f7f7 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 7332de2e4744e5d362ec215446dcac97f89b7451 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 175e5a369664a6b571968ce4db051a824c0b5a5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 15:42:38 +0200
+Subject: pinctrl: at91: use devm_kasprintf() to avoid potential leaks (part 2)
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit f494c1913cbb34b9e2078b7b045c87c1ca6df791 ]
+
+Use devm_kasprintf() instead of kasprintf() to avoid any potential
+leaks. At the moment drivers have no remove functionality hence
+there is no need for fixes tag.
+
+While at it, switch to use devm_kasprintf_strarray().
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Tested-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20230215134242.37618-2-andriy.shevchenko@linux.intel.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-at91.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
+index 735c501e7a06c..9fa68ca4a412d 100644
+--- a/drivers/pinctrl/pinctrl-at91.c
++++ b/drivers/pinctrl/pinctrl-at91.c
+@@ -18,6 +18,7 @@
+ #include <linux/pm.h>
+ #include <linux/seq_file.h>
+ #include <linux/slab.h>
++#include <linux/string_helpers.h>
+
+ /* Since we request GPIOs from ourself */
+ #include <linux/pinctrl/consumer.h>
+@@ -1371,6 +1372,7 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev,
+
+ static int at91_pinctrl_probe(struct platform_device *pdev)
+ {
++ struct device *dev = &pdev->dev;
+ struct at91_pinctrl *info;
+ struct pinctrl_pin_desc *pdesc;
+ int ret, i, j, k;
+@@ -1394,9 +1396,19 @@ static int at91_pinctrl_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ for (i = 0, k = 0; i < gpio_banks; i++) {
++ char **names;
++
++ names = devm_kasprintf_strarray(dev, "pio", MAX_NB_GPIO_PER_BANK);
++ if (!names)
++ return -ENOMEM;
++
+ for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) {
++ char *name = names[j];
++
++ strreplace(name, '-', i + 'A');
++
+ pdesc->number = k;
+- pdesc->name = kasprintf(GFP_KERNEL, "pio%c%d", i + 'A', j);
++ pdesc->name = name;
+ pdesc++;
+ }
+ }
+@@ -1797,7 +1809,8 @@ static const struct of_device_id at91_gpio_of_match[] = {
+
+ static int at91_gpio_probe(struct platform_device *pdev)
+ {
+- struct device_node *np = pdev->dev.of_node;
++ struct device *dev = &pdev->dev;
++ struct device_node *np = dev->of_node;
+ struct at91_gpio_chip *at91_chip = NULL;
+ struct gpio_chip *chip;
+ struct pinctrl_gpio_range *range;
+@@ -1866,16 +1879,14 @@ static int at91_gpio_probe(struct platform_device *pdev)
+ chip->ngpio = ngpio;
+ }
+
+- names = devm_kcalloc(&pdev->dev, chip->ngpio, sizeof(char *),
+- GFP_KERNEL);
+-
++ names = devm_kasprintf_strarray(dev, "pio", chip->ngpio);
+ if (!names) {
+ ret = -ENOMEM;
+ goto clk_enable_err;
+ }
+
+ for (i = 0; i < chip->ngpio; i++)
+- names[i] = devm_kasprintf(&pdev->dev, GFP_KERNEL, "pio%c%d", alias_idx + 'A', i);
++ strreplace(names[i], '-', alias_idx + 'A');
+
+ chip->names = (const char *const *)names;
+
+--
+2.39.2
+
--- /dev/null
+From 3fb0f23d5845a1e6236ac5e79e775dfe16c770f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Apr 2023 17:37:34 +0800
+Subject: platform/x86/amd: pmc: Fix memory leak in
+ amd_pmc_stb_debugfs_open_v2()
+
+From: Feng Jiang <jiangfeng@kylinos.cn>
+
+[ Upstream commit f6e7ac4c35a28aef0be93b32c533ae678ad0b9e7 ]
+
+Function amd_pmc_stb_debugfs_open_v2() may be called when the STB
+debug mechanism enabled.
+
+When amd_pmc_send_cmd() fails, the 'buf' needs to be released.
+
+Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn>
+Link: https://lore.kernel.org/r/20230412093734.1126410-1-jiangfeng@kylinos.cn
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/amd/pmc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c
+index 69f305496643f..73dedc9950144 100644
+--- a/drivers/platform/x86/amd/pmc.c
++++ b/drivers/platform/x86/amd/pmc.c
+@@ -265,6 +265,7 @@ static int amd_pmc_stb_debugfs_open_v2(struct inode *inode, struct file *filp)
+ dev->msg_port = 0;
+ if (ret) {
+ dev_err(dev->dev, "error: S2D_NUM_SAMPLES not supported : %d\n", ret);
++ kfree(buf);
+ return ret;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From ca36bf7650869a825c93a43b3005948c081e3e72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Mar 2023 15:46:28 -0700
+Subject: platform/x86/intel: vsec: Explicitly enable capabilities
+
+From: David E. Box <david.e.box@linux.intel.com>
+
+[ Upstream commit 3f95ecf2a3e4db09e58d307932037e8f1210d6e7 ]
+
+Discovered Intel VSEC/DVSEC capabilities are enabled by default and only
+get disabled by quirk. Instead, remove such quirks and only enable support
+for capabilities that have been explicitly added to a new capabilities
+field. While here, also reorder the device info structures alphabetically.
+
+Signed-off-by: David E. Box <david.e.box@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20230316224628.2855884-1-david.e.box@linux.intel.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel/vsec.c | 69 ++++++++++++++-----------------
+ drivers/platform/x86/intel/vsec.h | 9 +++-
+ 2 files changed, 38 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c
+index 2311c16cb975d..91be391bba3f7 100644
+--- a/drivers/platform/x86/intel/vsec.c
++++ b/drivers/platform/x86/intel/vsec.c
+@@ -67,14 +67,6 @@ enum intel_vsec_id {
+ VSEC_ID_TPMI = 66,
+ };
+
+-static enum intel_vsec_id intel_vsec_allow_list[] = {
+- VSEC_ID_TELEMETRY,
+- VSEC_ID_WATCHER,
+- VSEC_ID_CRASHLOG,
+- VSEC_ID_SDSI,
+- VSEC_ID_TPMI,
+-};
+-
+ static const char *intel_vsec_name(enum intel_vsec_id id)
+ {
+ switch (id) {
+@@ -98,26 +90,19 @@ static const char *intel_vsec_name(enum intel_vsec_id id)
+ }
+ }
+
+-static bool intel_vsec_allowed(u16 id)
+-{
+- int i;
+-
+- for (i = 0; i < ARRAY_SIZE(intel_vsec_allow_list); i++)
+- if (intel_vsec_allow_list[i] == id)
+- return true;
+-
+- return false;
+-}
+-
+-static bool intel_vsec_disabled(u16 id, unsigned long quirks)
++static bool intel_vsec_supported(u16 id, unsigned long caps)
+ {
+ switch (id) {
++ case VSEC_ID_TELEMETRY:
++ return !!(caps & VSEC_CAP_TELEMETRY);
+ case VSEC_ID_WATCHER:
+- return !!(quirks & VSEC_QUIRK_NO_WATCHER);
+-
++ return !!(caps & VSEC_CAP_WATCHER);
+ case VSEC_ID_CRASHLOG:
+- return !!(quirks & VSEC_QUIRK_NO_CRASHLOG);
+-
++ return !!(caps & VSEC_CAP_CRASHLOG);
++ case VSEC_ID_SDSI:
++ return !!(caps & VSEC_CAP_SDSI);
++ case VSEC_ID_TPMI:
++ return !!(caps & VSEC_CAP_TPMI);
+ default:
+ return false;
+ }
+@@ -206,7 +191,7 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he
+ unsigned long quirks = info->quirks;
+ int i;
+
+- if (!intel_vsec_allowed(header->id) || intel_vsec_disabled(header->id, quirks))
++ if (!intel_vsec_supported(header->id, info->caps))
+ return -EINVAL;
+
+ if (!header->num_entries) {
+@@ -261,14 +246,14 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he
+ static bool intel_vsec_walk_header(struct pci_dev *pdev,
+ struct intel_vsec_platform_info *info)
+ {
+- struct intel_vsec_header **header = info->capabilities;
++ struct intel_vsec_header **header = info->headers;
+ bool have_devices = false;
+ int ret;
+
+ for ( ; *header; header++) {
+ ret = intel_vsec_add_dev(pdev, *header, info);
+ if (ret)
+- dev_info(&pdev->dev, "Could not add device for DVSEC id %d\n",
++ dev_info(&pdev->dev, "Could not add device for VSEC id %d\n",
+ (*header)->id);
+ else
+ have_devices = true;
+@@ -403,14 +388,8 @@ static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id
+ return 0;
+ }
+
+-/* TGL info */
+-static const struct intel_vsec_platform_info tgl_info = {
+- .quirks = VSEC_QUIRK_NO_WATCHER | VSEC_QUIRK_NO_CRASHLOG |
+- VSEC_QUIRK_TABLE_SHIFT | VSEC_QUIRK_EARLY_HW,
+-};
+-
+ /* DG1 info */
+-static struct intel_vsec_header dg1_telemetry = {
++static struct intel_vsec_header dg1_header = {
+ .length = 0x10,
+ .id = 2,
+ .num_entries = 1,
+@@ -419,19 +398,31 @@ static struct intel_vsec_header dg1_telemetry = {
+ .offset = 0x466000,
+ };
+
+-static struct intel_vsec_header *dg1_capabilities[] = {
+- &dg1_telemetry,
++static struct intel_vsec_header *dg1_headers[] = {
++ &dg1_header,
+ NULL
+ };
+
+ static const struct intel_vsec_platform_info dg1_info = {
+- .capabilities = dg1_capabilities,
++ .caps = VSEC_CAP_TELEMETRY,
++ .headers = dg1_headers,
+ .quirks = VSEC_QUIRK_NO_DVSEC | VSEC_QUIRK_EARLY_HW,
+ };
+
+ /* MTL info */
+ static const struct intel_vsec_platform_info mtl_info = {
+- .quirks = VSEC_QUIRK_NO_WATCHER | VSEC_QUIRK_NO_CRASHLOG,
++ .caps = VSEC_CAP_TELEMETRY,
++};
++
++/* OOBMSM info */
++static const struct intel_vsec_platform_info oobmsm_info = {
++ .caps = VSEC_CAP_TELEMETRY | VSEC_CAP_SDSI | VSEC_CAP_TPMI,
++};
++
++/* TGL info */
++static const struct intel_vsec_platform_info tgl_info = {
++ .caps = VSEC_CAP_TELEMETRY,
++ .quirks = VSEC_QUIRK_TABLE_SHIFT | VSEC_QUIRK_EARLY_HW,
+ };
+
+ #define PCI_DEVICE_ID_INTEL_VSEC_ADL 0x467d
+@@ -446,7 +437,7 @@ static const struct pci_device_id intel_vsec_pci_ids[] = {
+ { PCI_DEVICE_DATA(INTEL, VSEC_DG1, &dg1_info) },
+ { PCI_DEVICE_DATA(INTEL, VSEC_MTL_M, &mtl_info) },
+ { PCI_DEVICE_DATA(INTEL, VSEC_MTL_S, &mtl_info) },
+- { PCI_DEVICE_DATA(INTEL, VSEC_OOBMSM, &(struct intel_vsec_platform_info) {}) },
++ { PCI_DEVICE_DATA(INTEL, VSEC_OOBMSM, &oobmsm_info) },
+ { PCI_DEVICE_DATA(INTEL, VSEC_RPL, &tgl_info) },
+ { PCI_DEVICE_DATA(INTEL, VSEC_TGL, &tgl_info) },
+ { }
+diff --git a/drivers/platform/x86/intel/vsec.h b/drivers/platform/x86/intel/vsec.h
+index ae8fe92c5595b..0fd042c171ba0 100644
+--- a/drivers/platform/x86/intel/vsec.h
++++ b/drivers/platform/x86/intel/vsec.h
+@@ -5,6 +5,12 @@
+ #include <linux/auxiliary_bus.h>
+ #include <linux/bits.h>
+
++#define VSEC_CAP_TELEMETRY BIT(0)
++#define VSEC_CAP_WATCHER BIT(1)
++#define VSEC_CAP_CRASHLOG BIT(2)
++#define VSEC_CAP_SDSI BIT(3)
++#define VSEC_CAP_TPMI BIT(4)
++
+ struct pci_dev;
+ struct resource;
+
+@@ -27,7 +33,8 @@ enum intel_vsec_quirks {
+
+ /* Platform specific data */
+ struct intel_vsec_platform_info {
+- struct intel_vsec_header **capabilities;
++ struct intel_vsec_header **headers;
++ unsigned long caps;
+ unsigned long quirks;
+ };
+
+--
+2.39.2
+
--- /dev/null
+From abe8ae2e28772f2af2c4e9e27060bbbf59baf33a 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 111b007656fc4..8405e1c58d520 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 f7a513d7b198727d9deb439c0525738fb9fcfc94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Apr 2023 17:06:51 +0200
+Subject: power: supply: axp288_charger: Use alt usb-id extcon on some x86
+ android tablets
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit ce38f3fc0f87a358a9560a3815265a94f1b38c37 ]
+
+x86 ACPI boards which ship with only Android as their factory image may
+have pretty broken ACPI tables. This includes broken _AEI ACPI GPIO event
+handlers, which are normally used to listen to the micro-USB ID pin and:
+
+1. Switch the USB-mux to the host / device USB controllers
+2. Disable Vbus path before enabling the 5V boost (AXP reg 0x30 bit 7)
+3. Turn 5V Vboost on / off
+
+On non broken systems where this is not done through an ACPI GPIO event
+handler, there is an ACPI INT3496 device describing the involved GPIOs
+which are handled by the extcon-intel-int3496 driver; and axp288-charger.ko
+listens to this extcon-device and disables the Vbus path when necessary.
+
+On x86 Android boards, with broken ACPI GPIO event handlers, these are
+disabled by acpi_quirk_skip_gpio_event_handlers() and an intel-int3496
+extcon device is manually instantiated by x86-android-tablets.ko .
+
+Add support to the axp288-charger code for this setup, so that it
+properly disables the Vbus path when necessary. Note this uses
+acpi_quirk_skip_gpio_event_handlers() to identify these systems,
+to avoid the need to add a separate DMI match table for this.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/axp288_charger.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/power/supply/axp288_charger.c b/drivers/power/supply/axp288_charger.c
+index 15219ed43ce95..b5903193e2f96 100644
+--- a/drivers/power/supply/axp288_charger.c
++++ b/drivers/power/supply/axp288_charger.c
+@@ -836,6 +836,7 @@ static int axp288_charger_probe(struct platform_device *pdev)
+ struct device *dev = &pdev->dev;
+ struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
+ struct power_supply_config charger_cfg = {};
++ const char *extcon_name = NULL;
+ unsigned int val;
+
+ /*
+@@ -872,8 +873,18 @@ static int axp288_charger_probe(struct platform_device *pdev)
+ return PTR_ERR(info->cable.edev);
+ }
+
+- if (acpi_dev_present(USB_HOST_EXTCON_HID, NULL, -1)) {
+- info->otg.cable = extcon_get_extcon_dev(USB_HOST_EXTCON_NAME);
++ /*
++ * On devices with broken ACPI GPIO event handlers there also is no ACPI
++ * "INT3496" (USB_HOST_EXTCON_HID) device. x86-android-tablets.ko
++ * instantiates an "intel-int3496" extcon on these devs as a workaround.
++ */
++ if (acpi_quirk_skip_gpio_event_handlers())
++ extcon_name = "intel-int3496";
++ else if (acpi_dev_present(USB_HOST_EXTCON_HID, NULL, -1))
++ extcon_name = USB_HOST_EXTCON_NAME;
++
++ if (extcon_name) {
++ info->otg.cable = extcon_get_extcon_dev(extcon_name);
+ if (IS_ERR(info->otg.cable)) {
+ dev_err_probe(dev, PTR_ERR(info->otg.cable),
+ "extcon_get_extcon_dev(%s) failed\n",
+--
+2.39.2
+
--- /dev/null
+From 6bd230624b0c0b8d2549fd8880146fc673be4b90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Mar 2023 08:46:56 -0600
+Subject: powerpc: Use of_property_present() for testing DT property presence
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 857d423c74228cfa064f79ff3a16b163fdb8d542 ]
+
+It is preferred to use typed property access functions (i.e.
+of_property_read_<type> functions) rather than low-level
+of_get_property/of_find_property functions for reading properties. As
+part of this, convert of_get_property/of_find_property calls to the
+recently added of_property_present() helper when we just want to test
+for presence of a property and nothing more.
+
+Signed-off-by: Rob Herring <robh@kernel.org>
+[mpe: Drop change in ppc4xx_probe_pci_bridge(), formatting]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230310144657.1541039-1-robh@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/legacy_serial.c | 8 ++++----
+ arch/powerpc/platforms/44x/iss4xx.c | 2 +-
+ arch/powerpc/platforms/44x/ppc476.c | 2 +-
+ arch/powerpc/platforms/cell/spu_manage.c | 2 +-
+ arch/powerpc/platforms/powermac/pic.c | 3 +--
+ arch/powerpc/platforms/powernv/opal-lpc.c | 2 +-
+ arch/powerpc/platforms/pseries/hotplug-cpu.c | 2 +-
+ arch/powerpc/platforms/pseries/vio.c | 2 +-
+ arch/powerpc/sysdev/mpic_msgr.c | 2 +-
+ 9 files changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
+index f048c424c525b..1a3b7f3513b40 100644
+--- a/arch/powerpc/kernel/legacy_serial.c
++++ b/arch/powerpc/kernel/legacy_serial.c
+@@ -171,11 +171,11 @@ static int __init add_legacy_soc_port(struct device_node *np,
+ /* We only support ports that have a clock frequency properly
+ * encoded in the device-tree.
+ */
+- if (of_get_property(np, "clock-frequency", NULL) == NULL)
++ if (!of_property_present(np, "clock-frequency"))
+ return -1;
+
+ /* if reg-offset don't try to use it */
+- if ((of_get_property(np, "reg-offset", NULL) != NULL))
++ if (of_property_present(np, "reg-offset"))
+ return -1;
+
+ /* if rtas uses this device, don't try to use it as well */
+@@ -237,7 +237,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
+ * Note: Don't even try on P8 lpc, we know it's not directly mapped
+ */
+ if (!of_device_is_compatible(isa_brg, "ibm,power8-lpc") ||
+- of_get_property(isa_brg, "ranges", NULL)) {
++ of_property_present(isa_brg, "ranges")) {
+ taddr = of_translate_address(np, reg);
+ if (taddr == OF_BAD_ADDR)
+ taddr = 0;
+@@ -268,7 +268,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
+ * compatible UARTs on PCI need all sort of quirks (port offsets
+ * etc...) that this code doesn't know about
+ */
+- if (of_get_property(np, "clock-frequency", NULL) == NULL)
++ if (!of_property_present(np, "clock-frequency"))
+ return -1;
+
+ /* Get the PCI address. Assume BAR 0 */
+diff --git a/arch/powerpc/platforms/44x/iss4xx.c b/arch/powerpc/platforms/44x/iss4xx.c
+index c5f82591408c1..812765cf06324 100644
+--- a/arch/powerpc/platforms/44x/iss4xx.c
++++ b/arch/powerpc/platforms/44x/iss4xx.c
+@@ -52,7 +52,7 @@ static void __init iss4xx_init_irq(void)
+
+ /* Find top level interrupt controller */
+ for_each_node_with_property(np, "interrupt-controller") {
+- if (of_get_property(np, "interrupts", NULL) == NULL)
++ if (!of_property_present(np, "interrupts"))
+ break;
+ }
+ if (np == NULL)
+diff --git a/arch/powerpc/platforms/44x/ppc476.c b/arch/powerpc/platforms/44x/ppc476.c
+index 7c91ac5a5241b..70556fd10f6b4 100644
+--- a/arch/powerpc/platforms/44x/ppc476.c
++++ b/arch/powerpc/platforms/44x/ppc476.c
+@@ -122,7 +122,7 @@ static void __init ppc47x_init_irq(void)
+
+ /* Find top level interrupt controller */
+ for_each_node_with_property(np, "interrupt-controller") {
+- if (of_get_property(np, "interrupts", NULL) == NULL)
++ if (!of_property_present(np, "interrupts"))
+ break;
+ }
+ if (np == NULL)
+diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c
+index f1ac4c7420690..74567b32c48c2 100644
+--- a/arch/powerpc/platforms/cell/spu_manage.c
++++ b/arch/powerpc/platforms/cell/spu_manage.c
+@@ -402,7 +402,7 @@ static int __init of_has_vicinity(void)
+ struct device_node *dn;
+
+ for_each_node_by_type(dn, "spe") {
+- if (of_find_property(dn, "vicinity", NULL)) {
++ if (of_property_present(dn, "vicinity")) {
+ of_node_put(dn);
+ return 1;
+ }
+diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
+index 8c8d8e0a7d137..7425f94e271e5 100644
+--- a/arch/powerpc/platforms/powermac/pic.c
++++ b/arch/powerpc/platforms/powermac/pic.c
+@@ -475,8 +475,7 @@ static int __init pmac_pic_probe_mpic(void)
+
+ /* We can have up to 2 MPICs cascaded */
+ for_each_node_by_type(np, "open-pic") {
+- if (master == NULL &&
+- of_get_property(np, "interrupts", NULL) == NULL)
++ if (master == NULL && !of_property_present(np, "interrupts"))
+ master = of_node_get(np);
+ else if (slave == NULL)
+ slave = of_node_get(np);
+diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c
+index d129d6d45a500..a16f07cdab267 100644
+--- a/arch/powerpc/platforms/powernv/opal-lpc.c
++++ b/arch/powerpc/platforms/powernv/opal-lpc.c
+@@ -403,7 +403,7 @@ void __init opal_lpc_init(void)
+ return;
+
+ /* Does it support direct mapping ? */
+- if (of_get_property(np, "ranges", NULL)) {
++ if (of_property_present(np, "ranges")) {
+ pr_info("OPAL: Found memory mapped LPC bus on chip %d\n",
+ opal_lpc_chip_id);
+ isa_bridge_init_non_pci(np);
+diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
+index 982e5e4b5e065..1a3cb313976a4 100644
+--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
++++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
+@@ -493,7 +493,7 @@ static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index)
+ bool found = false;
+ int rc, index;
+
+- if (of_find_property(parent, "ibm,drc-info", NULL))
++ if (of_property_present(parent, "ibm,drc-info"))
+ return drc_info_valid_index(parent, drc_index);
+
+ /* Note that the format of the ibm,drc-indexes array is
+diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
+index 770df9351aaa9..d54306a936d55 100644
+--- a/arch/powerpc/platforms/pseries/vio.c
++++ b/arch/powerpc/platforms/pseries/vio.c
+@@ -1440,7 +1440,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
+ viodev->dev.bus = &vio_bus_type;
+ viodev->dev.release = vio_dev_release;
+
+- if (of_get_property(viodev->dev.of_node, "ibm,my-dma-window", NULL)) {
++ if (of_property_present(viodev->dev.of_node, "ibm,my-dma-window")) {
+ if (firmware_has_feature(FW_FEATURE_CMO))
+ vio_cmo_set_dma_ops(viodev);
+ else
+diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c
+index d75064fb7d12f..1a3ac0b5dd89c 100644
+--- a/arch/powerpc/sysdev/mpic_msgr.c
++++ b/arch/powerpc/sysdev/mpic_msgr.c
+@@ -116,7 +116,7 @@ static unsigned int mpic_msgr_number_of_blocks(void)
+
+ for (;;) {
+ snprintf(buf, sizeof(buf), "mpic-msgr-block%d", count);
+- if (!of_find_property(aliases, buf, NULL))
++ if (!of_property_present(aliases, buf))
+ break;
+
+ count += 1;
+--
+2.39.2
+
--- /dev/null
+From c55056124fa8184d2494824c6cb88ff7552ea07c 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 249c2967d9e6c..54e8fb258c98d 100644
+--- a/kernel/rcu/tree_exp.h
++++ b/kernel/rcu/tree_exp.h
+@@ -802,9 +802,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 d688bded8a36e98a4b4f312535bf8ae6d7d60dd4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Mar 2023 17:47:03 -0600
+Subject: RDMA/core: Fix multiple -Warray-bounds warnings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit aa4d540b4150052ae3b36d286b9c833a961ce291 ]
+
+GCC-13 (and Clang)[1] does not like to access a partially allocated
+object, since it cannot reason about it for bounds checking.
+
+In this case 140 bytes are allocated for an object of type struct
+ib_umad_packet:
+
+ packet = kzalloc(sizeof(*packet) + IB_MGMT_RMPP_HDR, GFP_KERNEL);
+
+However, notice that sizeof(*packet) is only 104 bytes:
+
+struct ib_umad_packet {
+ struct ib_mad_send_buf * msg; /* 0 8 */
+ struct ib_mad_recv_wc * recv_wc; /* 8 8 */
+ struct list_head list; /* 16 16 */
+ int length; /* 32 4 */
+
+ /* XXX 4 bytes hole, try to pack */
+
+ struct ib_user_mad mad __attribute__((__aligned__(8))); /* 40 64 */
+
+ /* size: 104, cachelines: 2, members: 5 */
+ /* sum members: 100, holes: 1, sum holes: 4 */
+ /* forced alignments: 1, forced holes: 1, sum forced holes: 4 */
+ /* last cacheline: 40 bytes */
+} __attribute__((__aligned__(8)));
+
+and 36 bytes extra bytes are allocated for a flexible-array member in
+struct ib_user_mad:
+
+include/rdma/ib_mad.h:
+120 enum {
+...
+123 IB_MGMT_RMPP_HDR = 36,
+... }
+
+struct ib_user_mad {
+ struct ib_user_mad_hdr hdr; /* 0 64 */
+ /* --- cacheline 1 boundary (64 bytes) --- */
+ __u64 data[] __attribute__((__aligned__(8))); /* 64 0 */
+
+ /* size: 64, cachelines: 1, members: 2 */
+ /* forced alignments: 1 */
+} __attribute__((__aligned__(8)));
+
+So we have sizeof(*packet) + IB_MGMT_RMPP_HDR == 140 bytes
+
+Then the address of the flex-array member (for which only 36 bytes were
+allocated) is casted and copied into a pointer to struct ib_rmpp_mad,
+which, in turn, is of size 256 bytes:
+
+ rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data;
+
+struct ib_rmpp_mad {
+ struct ib_mad_hdr mad_hdr; /* 0 24 */
+ struct ib_rmpp_hdr rmpp_hdr; /* 24 12 */
+ u8 data[220]; /* 36 220 */
+
+ /* size: 256, cachelines: 4, members: 3 */
+};
+
+The thing is that those 36 bytes allocated for flex-array member data
+in struct ib_user_mad onlly account for the size of both struct ib_mad_hdr
+and struct ib_rmpp_hdr, but nothing is left for array u8 data[220].
+So, the compiler is legitimately complaining about accessing an object
+for which not enough memory was allocated.
+
+Apparently, the only members of struct ib_rmpp_mad that are relevant
+(that are actually being used) in function ib_umad_write() are mad_hdr
+and rmpp_hdr. So, instead of casting packet->mad.data to
+(struct ib_rmpp_mad *) create a new structure
+
+struct ib_rmpp_mad_hdr {
+ struct ib_mad_hdr mad_hdr;
+ struct ib_rmpp_hdr rmpp_hdr;
+} __packed;
+
+and cast packet->mad.data to (struct ib_rmpp_mad_hdr *).
+
+Notice that
+
+ IB_MGMT_RMPP_HDR == sizeof(struct ib_rmpp_mad_hdr) == 36 bytes
+
+Refactor the rest of the code, accordingly.
+
+Fix the following warnings seen under GCC-13 and -Warray-bounds:
+drivers/infiniband/core/user_mad.c:564:50: warning: array subscript ‘struct ib_rmpp_mad[0]’ is partly outside array bounds of ‘unsigned char[140]’ [-Warray-bounds=]
+drivers/infiniband/core/user_mad.c:566:42: warning: array subscript ‘struct ib_rmpp_mad[0]’ is partly outside array bounds of ‘unsigned char[140]’ [-Warray-bounds=]
+drivers/infiniband/core/user_mad.c:618:25: warning: array subscript ‘struct ib_rmpp_mad[0]’ is partly outside array bounds of ‘unsigned char[140]’ [-Warray-bounds=]
+drivers/infiniband/core/user_mad.c:622:44: warning: array subscript ‘struct ib_rmpp_mad[0]’ is partly outside array bounds of ‘unsigned char[140]’ [-Warray-bounds=]
+
+Link: https://github.com/KSPP/linux/issues/273
+Link: https://godbolt.org/z/oYWaGM4Yb [1]
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Link: https://lore.kernel.org/r/ZBpB91qQcB10m3Fw@work
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/user_mad.c | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
+index f83954180a338..d21c0a042f0a5 100644
+--- a/drivers/infiniband/core/user_mad.c
++++ b/drivers/infiniband/core/user_mad.c
+@@ -131,6 +131,11 @@ struct ib_umad_packet {
+ struct ib_user_mad mad;
+ };
+
++struct ib_rmpp_mad_hdr {
++ struct ib_mad_hdr mad_hdr;
++ struct ib_rmpp_hdr rmpp_hdr;
++} __packed;
++
+ #define CREATE_TRACE_POINTS
+ #include <trace/events/ib_umad.h>
+
+@@ -494,11 +499,11 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *pos)
+ {
+ struct ib_umad_file *file = filp->private_data;
++ struct ib_rmpp_mad_hdr *rmpp_mad_hdr;
+ struct ib_umad_packet *packet;
+ struct ib_mad_agent *agent;
+ struct rdma_ah_attr ah_attr;
+ struct ib_ah *ah;
+- struct ib_rmpp_mad *rmpp_mad;
+ __be64 *tid;
+ int ret, data_len, hdr_len, copy_offset, rmpp_active;
+ u8 base_version;
+@@ -506,7 +511,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
+ if (count < hdr_size(file) + IB_MGMT_RMPP_HDR)
+ return -EINVAL;
+
+- packet = kzalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL);
++ packet = kzalloc(sizeof(*packet) + IB_MGMT_RMPP_HDR, GFP_KERNEL);
+ if (!packet)
+ return -ENOMEM;
+
+@@ -560,13 +565,13 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
+ goto err_up;
+ }
+
+- rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data;
+- hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class);
++ rmpp_mad_hdr = (struct ib_rmpp_mad_hdr *)packet->mad.data;
++ hdr_len = ib_get_mad_data_offset(rmpp_mad_hdr->mad_hdr.mgmt_class);
+
+- if (ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)
++ if (ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class)
+ && ib_mad_kernel_rmpp_agent(agent)) {
+ copy_offset = IB_MGMT_RMPP_HDR;
+- rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
++ rmpp_active = ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) &
+ IB_MGMT_RMPP_FLAG_ACTIVE;
+ } else {
+ copy_offset = IB_MGMT_MAD_HDR;
+@@ -615,12 +620,12 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
+ tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid;
+ *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |
+ (be64_to_cpup(tid) & 0xffffffff));
+- rmpp_mad->mad_hdr.tid = *tid;
++ rmpp_mad_hdr->mad_hdr.tid = *tid;
+ }
+
+ if (!ib_mad_kernel_rmpp_agent(agent)
+- && ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)
+- && (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) {
++ && ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class)
++ && (ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) {
+ spin_lock_irq(&file->send_lock);
+ list_add_tail(&packet->list, &file->send_list);
+ spin_unlock_irq(&file->send_lock);
+--
+2.39.2
+
--- /dev/null
+From ed51423763f7dec4ccac4217aa02bf603ef4dead Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Apr 2023 16:07:50 +0300
+Subject: RDMA/mlx5: Remove pcie_relaxed_ordering_enabled() check for RO write
+
+From: Avihai Horon <avihaih@nvidia.com>
+
+[ Upstream commit ed4b0661cce119870edb1994fd06c9cbc1dc05c3 ]
+
+pcie_relaxed_ordering_enabled() check was added to avoid a syndrome when
+creating a MKey with relaxed ordering (RO) enabled when the driver's
+relaxed_ordering_{read,write} HCA capabilities are out of sync with FW.
+
+While this can happen with relaxed_ordering_read, it can't happen with
+relaxed_ordering_write as it's set if the device supports RO write,
+regardless of RO in PCI config space, and thus can't change during
+runtime.
+
+Therefore, drop the pcie_relaxed_ordering_enabled() check for
+relaxed_ordering_write while keeping it for relaxed_ordering_read.
+Doing so will also allow the usage of RO write in VFs and VMs (where RO
+in PCI config space is not reported/emulated properly).
+
+Signed-off-by: Avihai Horon <avihaih@nvidia.com>
+Reviewed-by: Shay Drory <shayd@nvidia.com>
+Link: https://lore.kernel.org/r/7e8f55e31572c1702d69cae015a395d3a824a38a.1681131553.git.leon@kernel.org
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/mr.c | 6 +++---
+ drivers/net/ethernet/mellanox/mlx5/core/en/params.c | 3 +--
+ drivers/net/ethernet/mellanox/mlx5/core/en_common.c | 2 +-
+ 3 files changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
+index 67356f5152616..bd0a818ba1cd8 100644
+--- a/drivers/infiniband/hw/mlx5/mr.c
++++ b/drivers/infiniband/hw/mlx5/mr.c
+@@ -67,11 +67,11 @@ static void set_mkc_access_pd_addr_fields(void *mkc, int acc, u64 start_addr,
+ MLX5_SET(mkc, mkc, lw, !!(acc & IB_ACCESS_LOCAL_WRITE));
+ MLX5_SET(mkc, mkc, lr, 1);
+
+- if ((acc & IB_ACCESS_RELAXED_ORDERING) &&
+- pcie_relaxed_ordering_enabled(dev->mdev->pdev)) {
++ if (acc & IB_ACCESS_RELAXED_ORDERING) {
+ if (MLX5_CAP_GEN(dev->mdev, relaxed_ordering_write))
+ MLX5_SET(mkc, mkc, relaxed_ordering_write, 1);
+- if (MLX5_CAP_GEN(dev->mdev, relaxed_ordering_read))
++ if (MLX5_CAP_GEN(dev->mdev, relaxed_ordering_read) &&
++ pcie_relaxed_ordering_enabled(dev->mdev->pdev))
+ MLX5_SET(mkc, mkc, relaxed_ordering_read, 1);
+ }
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
+index a21bd1179477b..d840a59aec88a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
+@@ -867,8 +867,7 @@ static void mlx5e_build_rx_cq_param(struct mlx5_core_dev *mdev,
+ static u8 rq_end_pad_mode(struct mlx5_core_dev *mdev, struct mlx5e_params *params)
+ {
+ bool lro_en = params->packet_merge.type == MLX5E_PACKET_MERGE_LRO;
+- bool ro = pcie_relaxed_ordering_enabled(mdev->pdev) &&
+- MLX5_CAP_GEN(mdev, relaxed_ordering_write);
++ bool ro = MLX5_CAP_GEN(mdev, relaxed_ordering_write);
+
+ return ro && lro_en ?
+ MLX5_WQ_END_PAD_MODE_NONE : MLX5_WQ_END_PAD_MODE_ALIGN;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c
+index 4c9a3210600c2..993af4c12d909 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c
+@@ -44,7 +44,7 @@ void mlx5e_mkey_set_relaxed_ordering(struct mlx5_core_dev *mdev, void *mkc)
+ bool ro_read = MLX5_CAP_GEN(mdev, relaxed_ordering_read);
+
+ MLX5_SET(mkc, mkc, relaxed_ordering_read, ro_pci_enable && ro_read);
+- MLX5_SET(mkc, mkc, relaxed_ordering_write, ro_pci_enable && ro_write);
++ MLX5_SET(mkc, mkc, relaxed_ordering_write, ro_write);
+ }
+
+ int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn, u32 *mkey)
+--
+2.39.2
+
--- /dev/null
+From 8b834f0e739f3cd2637ff2652374f8a65cab0ca6 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 e30216525325b..40ae6b2c7a6da 100644
+--- a/scripts/recordmcount.c
++++ b/scripts/recordmcount.c
+@@ -110,6 +110,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;
+
+@@ -117,7 +118,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 a4c3ef7f7e666b7eb11873500cde8e07821f1411 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 afa3e1a2f6902..1970ce5f22d40 100644
+--- a/kernel/rcu/refscale.c
++++ b/kernel/rcu/refscale.c
+@@ -1031,7 +1031,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 28127a8cae686f7b45a78d2eefceb1785cdb8ffb 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 e81f2372962b410e38e50b48b5111aebfbf580f4 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 0eec0c8d2344898e6a62e6471fa1ff8cf855d5a8 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 38449b7bb461de822b8be2cedc033ffa13ffb377 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Feb 2023 08:52:30 +0100
+Subject: riscv: Fix EFI stub usage of KASAN instrumented strcmp function
+
+From: Alexandre Ghiti <alexghiti@rivosinc.com>
+
+[ Upstream commit 617955ca6e275c4dd0dcf5316fca7fc04a8f2fe6 ]
+
+The EFI stub must not use any KASAN instrumented code as the kernel
+proper did not initialize the thread pointer and the mapping for the
+KASAN shadow region.
+
+Avoid using the generic strcmp function, instead use the one in
+drivers/firmware/efi/libstub/string.c.
+
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Reviewed-by: Atish Patra <atishp@rivosinc.com>
+Link: https://lore.kernel.org/r/20230203075232.274282-5-alexghiti@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/image-vars.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h
+index 7e2962ef73f92..15616155008cc 100644
+--- a/arch/riscv/kernel/image-vars.h
++++ b/arch/riscv/kernel/image-vars.h
+@@ -23,8 +23,6 @@
+ * linked at. The routines below are all implemented in assembler in a
+ * position independent manner
+ */
+-__efistub_strcmp = strcmp;
+-
+ __efistub__start = _start;
+ __efistub__start_kernel = _start_kernel;
+ __efistub__end = _end;
+--
+2.39.2
+
--- /dev/null
+From 117c991f91d560dc4c6b6a762e008eeb1e64a5f9 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 b27e01158a92fb295f3081a8437ccd79dac3e450 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 d147193befac76a6a6a50a6ae82777225f6553f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Mar 2023 11:34:22 +0800
+Subject: scsi: hisi_sas: Grab sas_dev lock when traversing the members of
+ sas_dev.list
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit 71fb36b5ff113a7674710b9d6063241eada84ff7 ]
+
+When freeing slots in function slot_complete_v3_hw(), it is possible that
+sas_dev.list is being traversed elsewhere, and it may trigger a NULL
+pointer exception, such as follows:
+
+==>cq thread ==>scsi_eh_6
+
+ ==>scsi_error_handler()
+ ==>sas_eh_handle_sas_errors()
+ ==>sas_scsi_find_task()
+ ==>lldd_abort_task()
+==>slot_complete_v3_hw() ==>hisi_sas_abort_task()
+ ==>hisi_sas_slot_task_free() ==>dereg_device_v3_hw()
+ ==>list_del_init() ==>list_for_each_entry_safe()
+
+[ 7165.434918] sas: Enter sas_scsi_recover_host busy: 32 failed: 32
+[ 7165.434926] sas: trying to find task 0x00000000769b5ba5
+[ 7165.434927] sas: sas_scsi_find_task: aborting task 0x00000000769b5ba5
+[ 7165.434940] hisi_sas_v3_hw 0000:b4:02.0: slot complete: task(00000000769b5ba5) aborted
+[ 7165.434964] hisi_sas_v3_hw 0000:b4:02.0: slot complete: task(00000000c9f7aa07) ignored
+[ 7165.434965] hisi_sas_v3_hw 0000:b4:02.0: slot complete: task(00000000e2a1cf01) ignored
+[ 7165.434968] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
+[ 7165.434972] hisi_sas_v3_hw 0000:b4:02.0: slot complete: task(0000000022d52d93) ignored
+[ 7165.434975] hisi_sas_v3_hw 0000:b4:02.0: slot complete: task(0000000066a7516c) ignored
+[ 7165.434976] Mem abort info:
+[ 7165.434982] ESR = 0x96000004
+[ 7165.434991] Exception class = DABT (current EL), IL = 32 bits
+[ 7165.434992] SET = 0, FnV = 0
+[ 7165.434993] EA = 0, S1PTW = 0
+[ 7165.434994] Data abort info:
+[ 7165.434994] ISV = 0, ISS = 0x00000004
+[ 7165.434995] CM = 0, WnR = 0
+[ 7165.434997] user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000f29543f2
+[ 7165.434998] [0000000000000000] pgd=0000000000000000
+[ 7165.435003] Internal error: Oops: 96000004 [#1] SMP
+[ 7165.439863] Process scsi_eh_6 (pid: 4109, stack limit = 0x00000000c43818d5)
+[ 7165.468862] pstate: 00c00009 (nzcv daif +PAN +UAO)
+[ 7165.473637] pc : dereg_device_v3_hw+0x68/0xa8 [hisi_sas_v3_hw]
+[ 7165.479443] lr : dereg_device_v3_hw+0x2c/0xa8 [hisi_sas_v3_hw]
+[ 7165.485247] sp : ffff00001d623bc0
+[ 7165.488546] x29: ffff00001d623bc0 x28: ffffa027d03b9508
+[ 7165.493835] x27: ffff80278ed50af0 x26: ffffa027dd31e0a8
+[ 7165.499123] x25: ffffa027d9b27f88 x24: ffffa027d9b209f8
+[ 7165.504411] x23: ffffa027c45b0d60 x22: ffff80278ec07c00
+[ 7165.509700] x21: 0000000000000008 x20: ffffa027d9b209f8
+[ 7165.514988] x19: ffffa027d9b27f88 x18: ffffffffffffffff
+[ 7165.520276] x17: 0000000000000000 x16: 0000000000000000
+[ 7165.525564] x15: ffff0000091d9708 x14: ffff0000093b7dc8
+[ 7165.530852] x13: ffff0000093b7a23 x12: 6e7265746e692067
+[ 7165.536140] x11: 0000000000000000 x10: 0000000000000bb0
+[ 7165.541429] x9 : ffff00001d6238f0 x8 : ffffa027d877af00
+[ 7165.546718] x7 : ffffa027d6329600 x6 : ffff7e809f58ca00
+[ 7165.552006] x5 : 0000000000001f8a x4 : 000000000000088e
+[ 7165.557295] x3 : ffffa027d9b27fa8 x2 : 0000000000000000
+[ 7165.562583] x1 : 0000000000000000 x0 : 000000003000188e
+[ 7165.567872] Call trace:
+[ 7165.570309] dereg_device_v3_hw+0x68/0xa8 [hisi_sas_v3_hw]
+[ 7165.575775] hisi_sas_abort_task+0x248/0x358 [hisi_sas_main]
+[ 7165.581415] sas_eh_handle_sas_errors+0x258/0x8e0 [libsas]
+[ 7165.586876] sas_scsi_recover_host+0x134/0x458 [libsas]
+[ 7165.592082] scsi_error_handler+0xb4/0x488
+[ 7165.596163] kthread+0x134/0x138
+[ 7165.599380] ret_from_fork+0x10/0x18
+[ 7165.602940] Code: d5033e9f b9000040 aa0103e2 eb03003f (f9400021)
+[ 7165.609004] kernel fault(0x1) notification starting on CPU 75
+[ 7165.700728] ---[ end trace fc042cbbea224efc ]---
+[ 7165.705326] Kernel panic - not syncing: Fatal exception
+
+To fix the issue, grab sas_dev lock when traversing the members of
+sas_dev.list in dereg_device_v3_hw() and hisi_sas_release_tasks() to avoid
+concurrency of adding and deleting member. When function
+hisi_sas_release_tasks() calls hisi_sas_do_release_task() to free slot, the
+lock cannot be grabbed again in hisi_sas_slot_task_free(), then a bool
+parameter need_lock is added.
+
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Link: https://lore.kernel.org/r/1679283265-115066-2-git-send-email-chenxiang66@hisilicon.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 3 ++-
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 25 ++++++++++++++++---------
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 +++-
+ 5 files changed, 23 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 6f8a52a1b8087..423af1dc36487 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -653,7 +653,8 @@ extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy,
+ extern void hisi_sas_phy_bcast(struct hisi_sas_phy *phy);
+ extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,
+ struct sas_task *task,
+- struct hisi_sas_slot *slot);
++ struct hisi_sas_slot *slot,
++ bool need_lock);
+ extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba);
+ extern void hisi_sas_rst_work_handler(struct work_struct *work);
+ extern void hisi_sas_sync_rst_work_handler(struct work_struct *work);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 8c038ccf1c095..2093c1e828177 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -205,7 +205,7 @@ static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba,
+ }
+
+ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
+- struct hisi_sas_slot *slot)
++ struct hisi_sas_slot *slot, bool need_lock)
+ {
+ int device_id = slot->device_id;
+ struct hisi_sas_device *sas_dev = &hisi_hba->devices[device_id];
+@@ -239,9 +239,13 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
+ }
+ }
+
+- spin_lock(&sas_dev->lock);
+- list_del_init(&slot->entry);
+- spin_unlock(&sas_dev->lock);
++ if (need_lock) {
++ spin_lock(&sas_dev->lock);
++ list_del_init(&slot->entry);
++ spin_unlock(&sas_dev->lock);
++ } else {
++ list_del_init(&slot->entry);
++ }
+
+ memset(slot, 0, offsetof(struct hisi_sas_slot, buf));
+
+@@ -1021,7 +1025,7 @@ static void hisi_sas_port_notify_formed(struct asd_sas_phy *sas_phy)
+ }
+
+ static void hisi_sas_do_release_task(struct hisi_hba *hisi_hba, struct sas_task *task,
+- struct hisi_sas_slot *slot)
++ struct hisi_sas_slot *slot, bool need_lock)
+ {
+ if (task) {
+ unsigned long flags;
+@@ -1038,7 +1042,7 @@ static void hisi_sas_do_release_task(struct hisi_hba *hisi_hba, struct sas_task
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+ }
+
+- hisi_sas_slot_task_free(hisi_hba, task, slot);
++ hisi_sas_slot_task_free(hisi_hba, task, slot, need_lock);
+ }
+
+ static void hisi_sas_release_task(struct hisi_hba *hisi_hba,
+@@ -1047,8 +1051,11 @@ static void hisi_sas_release_task(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot, *slot2;
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+
++ spin_lock(&sas_dev->lock);
+ list_for_each_entry_safe(slot, slot2, &sas_dev->list, entry)
+- hisi_sas_do_release_task(hisi_hba, slot->task, slot);
++ hisi_sas_do_release_task(hisi_hba, slot->task, slot, false);
++
++ spin_unlock(&sas_dev->lock);
+ }
+
+ void hisi_sas_release_tasks(struct hisi_hba *hisi_hba)
+@@ -1574,7 +1581,7 @@ static int hisi_sas_abort_task(struct sas_task *task)
+ */
+ if (rc == TMF_RESP_FUNC_COMPLETE && rc2 != TMF_RESP_FUNC_SUCC) {
+ if (task->lldd_task)
+- hisi_sas_do_release_task(hisi_hba, task, slot);
++ hisi_sas_do_release_task(hisi_hba, task, slot, true);
+ }
+ } else if (task->task_proto & SAS_PROTOCOL_SATA ||
+ task->task_proto & SAS_PROTOCOL_STP) {
+@@ -1594,7 +1601,7 @@ static int hisi_sas_abort_task(struct sas_task *task)
+ */
+ if ((sas_dev->dev_status == HISI_SAS_DEV_NCQ_ERR) &&
+ qc && qc->scsicmd) {
+- hisi_sas_do_release_task(hisi_hba, task, slot);
++ hisi_sas_do_release_task(hisi_hba, task, slot, true);
+ rc = TMF_RESP_FUNC_COMPLETE;
+ } else {
+ rc = hisi_sas_softreset_ata_disk(device);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+index 70c24377c6a19..76176b1fc035d 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -1310,7 +1310,7 @@ static void slot_complete_v1_hw(struct hisi_hba *hisi_hba,
+ }
+
+ out:
+- hisi_sas_slot_task_free(hisi_hba, task, slot);
++ hisi_sas_slot_task_free(hisi_hba, task, slot, true);
+
+ if (task->task_done)
+ task->task_done(task);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 02575d81afca2..746e4d77de04a 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2466,7 +2466,7 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba,
+ }
+ task->task_state_flags |= SAS_TASK_STATE_DONE;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+- hisi_sas_slot_task_free(hisi_hba, task, slot);
++ hisi_sas_slot_task_free(hisi_hba, task, slot, true);
+
+ if (!is_internal && (task->task_proto != SAS_PROTOCOL_SMP)) {
+ spin_lock_irqsave(&device->done_lock, flags);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 9afc23e3a80fc..71820a1170b4f 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -883,6 +883,7 @@ static void dereg_device_v3_hw(struct hisi_hba *hisi_hba,
+
+ cfg_abt_set_query_iptt = hisi_sas_read32(hisi_hba,
+ CFG_ABT_SET_QUERY_IPTT);
++ spin_lock(&sas_dev->lock);
+ list_for_each_entry_safe(slot, slot2, &sas_dev->list, entry) {
+ cfg_abt_set_query_iptt &= ~CFG_SET_ABORTED_IPTT_MSK;
+ cfg_abt_set_query_iptt |= (1 << CFG_SET_ABORTED_EN_OFF) |
+@@ -890,6 +891,7 @@ static void dereg_device_v3_hw(struct hisi_hba *hisi_hba,
+ hisi_sas_write32(hisi_hba, CFG_ABT_SET_QUERY_IPTT,
+ cfg_abt_set_query_iptt);
+ }
++ spin_unlock(&sas_dev->lock);
+ cfg_abt_set_query_iptt &= ~(1 << CFG_SET_ABORTED_EN_OFF);
+ hisi_sas_write32(hisi_hba, CFG_ABT_SET_QUERY_IPTT,
+ cfg_abt_set_query_iptt);
+@@ -2378,7 +2380,7 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
+ }
+ task->task_state_flags |= SAS_TASK_STATE_DONE;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+- hisi_sas_slot_task_free(hisi_hba, task, slot);
++ hisi_sas_slot_task_free(hisi_hba, task, slot, true);
+
+ if (!is_internal && (task->task_proto != SAS_PROTOCOL_SMP)) {
+ spin_lock_irqsave(&device->done_lock, flags);
+--
+2.39.2
+
--- /dev/null
+From 1ec4ff4a186ef2f52d62ebae691341e4d633e875 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 35b252f1ef731..62d2ca688cd14 100644
+--- a/drivers/scsi/lpfc/lpfc_els.c
++++ b/drivers/scsi/lpfc/lpfc_els.c
+@@ -5455,18 +5455,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 6ea0206e4441b40e5aa8dd36ee7465378195c8d1 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 8ee2ba5acdb2dfd5951551e1ac5973e26427f2ac 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 59bf86dd12184ed8aa621d5ba2632b098b05b3f0 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 959ae5a2b9b5d6a45c08ef21581a1da34b497e3a 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 1427f69db7ff030103fd5fa0ef887a77c32d07b3 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 1e616a8c6a9cf..f4f7c0aef702b 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;
+
+@@ -778,6 +788,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 c2a1e3a5ddb324a6a593d86d49ccc37cf69bb747 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 ab63c308be0a2..13bf535eedcd5 100644
+--- a/drivers/tty/serial/8250/8250_core.c
++++ b/drivers/tty/serial/8250/8250_core.c
+@@ -1158,6 +1158,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
+drm-amd-display-enable-dpg-when-disabling-plane-for-.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
+accel-habanalabs-postpone-mem_mgr-idr-destruction-to.patch
+drm-amd-display-reallocate-det-for-dual-displays-wit.patch
+media-imx-jpeg-bounds-check-sizeimage-access.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
+platform-x86-intel-vsec-explicitly-enable-capabiliti.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
+accel-ivpu-remove-d3hot-delay-for-meteorlake.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
+arm64-dts-qcom-sm6115-j606f-add-ramoops-node.patch
+irqchip-gicv3-workaround-for-nvidia-erratum-t241-fab.patch
+media-ipu3-cio2-support-multiple-sensors-and-vcms-wi.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
+drm-amdgpu-enable-ih-retry-cam-on-gfx9.patch
+media-mediatek-vcodec-fix-potential-array-out-of-bou.patch
+platform-x86-amd-pmc-fix-memory-leak-in-amd_pmc_stb_.patch
+hwmon-nzxt-smart2-add-another-usb-id.patch
+wifi-ath-silence-memcpy-run-time-false-positive-warn.patch
+wifi-ath12k-handle-lock-during-peer_id-find.patch
+wifi-ath12k-pci-ops-for-wakeup-release-mhi.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
+wifi-brcmfmac-pcie-add-ids-properties-for-bcm4387.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
+wifi-rtw88-fix-memory-leak-in-rtw_usb_probe.patch
+bnxt-avoid-overflow-in-bnxt_get_nvram_directory.patch
+net-pasemi-fix-return-type-of-pasemi_mac_start_tx.patch
+wifi-ath12k-fix-memory-leak-in-ath12k_qmi_driver_eve.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
+scsi-hisi_sas-grab-sas_dev-lock-when-traversing-the-.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
+net-sched-pass-netlink-extack-to-mqprio-and-taprio-o.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-mt76-mt7921-add-netgear-axe3000-a8000-support.patch
+wifi-iwlwifi-fix-iwl_mvm_max_amsdu_size-for-mlo.patch
+f2fs-relax-sanity-check-if-checkpoint-is-corrupted.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
+wifi-rtw88-fix-memory-leak-in-rtw88_usb.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
+iio-imu-st_lsm6dsx-discard-samples-during-filters-se.patch
+staging-axis-fifo-initialize-timeouts-in-init-only.patch
+xhci-mem-carefully-calculate-size-for-memory-allocat.patch
+xhci-avoid-pci-msi-msix-interrupt-reinitialization-a.patch
+spi-intel-pci-add-support-for-meteor-lake-s-spi-seri.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
+asoc-amd-add-check-for-acp-config-flags.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
+powerpc-use-of_property_present-for-testing-dt-prope.patch
+sched-fix-kcsan-noinstr-violation.patch
+lkdtm-stackleak-fix-noinstr-violation.patch
+riscv-fix-efi-stub-usage-of-kasan-instrumented-strcm.patch
+recordmcount-fix-memory-leaks-in-the-uwrite-function.patch
+rdma-core-fix-multiple-warray-bounds-warnings.patch
+kvm-selftests-add-malloc-failure-check-in-vcpu_save_.patch
+iommu-arm-smmu-qcom-limit-the-smr-groups-to-128.patch
+fs-ntfs3-fix-null-pointer-dereference-in-ni_write_in.patch
+fs-ntfs3-enhance-the-attribute-size-check.patch
+fs-ntfs3-fix-null-dereference-in-ni_write_inode.patch
+fs-ntfs3-validate-mft-flags-before-replaying-logs.patch
+fs-ntfs3-add-length-check-in-indx_get_root.patch
+fs-ntfs3-fix-a-possible-null-pointer-dereference-in-.patch
+clk-tegra20-fix-gcc-7-constant-overflow-warning.patch
+iommu-arm-smmu-v3-acknowledge-pri-event-queue-overfl.patch
+iommu-arm-smmu-drop-if-with-an-always-false-conditio.patch
+iommu-sprd-release-dma-buffer-to-avoid-memory-leak.patch
+power-supply-axp288_charger-use-alt-usb-id-extcon-on.patch
+input-xpad-add-constants-for-gip-interface-numbers.patch
+rdma-mlx5-remove-pcie_relaxed_ordering_enabled-check.patch
+clk-rockchip-rk3588-make-gate-linked-clocks-critical.patch
+cifs-missing-lock-when-updating-session-status.patch
+pinctrl-at91-use-devm_kasprintf-to-avoid-potential-l.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 6d39fa5de457ba9000aef8a9843f5e9c69cb16e0 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 b6aca59c31300..7fd99e581a574 100644
+--- a/drivers/soundwire/bus.c
++++ b/drivers/soundwire/bus.c
+@@ -546,9 +546,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);
+
+@@ -570,9 +572,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);
+
+@@ -1541,9 +1545,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 bea7c3e8041dde2e9807539953000fc740466dbd 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 9aefd71f65dd7b708f89f728b3c691fd9de754b0 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 ba502129150d5..30575ed20947e 100644
+--- a/drivers/soundwire/qcom.c
++++ b/drivers/soundwire/qcom.c
+@@ -1217,6 +1217,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 d03fd4c8ac9a28c3d681fb0b351d439598344086 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Mar 2023 08:28:12 +0300
+Subject: spi: intel-pci: Add support for Meteor Lake-S SPI serial flash
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit c2912d42e86e494935722669e4d9eade69649072 ]
+
+Intel Meteor Lake-S has the same SPI serial flash controller as Meteor
+Lake-P. Add Meteor Lake-S PCI ID to the driver list of supported
+devices.
+
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Link: https://lore.kernel.org/r/20230331052812.39983-1-mika.westerberg@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-intel-pci.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c
+index 4d69e320d0185..a7381e774b953 100644
+--- a/drivers/spi/spi-intel-pci.c
++++ b/drivers/spi/spi-intel-pci.c
+@@ -83,6 +83,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = {
+ { PCI_VDEVICE(INTEL, 0xa2a4), (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info },
+ { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info },
++ { PCI_VDEVICE(INTEL, 0xae23), (unsigned long)&cnl_info },
+ { },
+ };
+ MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids);
+--
+2.39.2
+
--- /dev/null
+From f55c9460880856c5ad93c0342876c7bacf24baa7 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 6c9c87cd14cae..a2a5ada61c3af 100644
+--- a/drivers/spi/spi-imx.c
++++ b/drivers/spi/spi-imx.c
+@@ -252,6 +252,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)
+@@ -260,16 +272,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 0bc0bbea6937ce524a9882deedd92a3d1d87058a 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 6adaf446177100a72ad99950116f8714280fc9cb 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 72d76dc7df781..92552ce30cd58 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 fd96eef90c7fa..bbc1c4bac3588 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 8485402f2d675c4ca1165dc235bfa8ae896a900f 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 1ee774c263f08..be1708e30e917 100644
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -1523,7 +1523,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 35279aedc7c462b1ebd502d6fa720d6808310099 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 83691709f1b8b5ed4ae8eb7d737871d1a64c7f4f 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 54bd396ef5886384af7d4fd6d6e69d9a35bbded0 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 294c6fcfa1aa8..32a4f88861d58 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 8d1b5bd11fd50ccb2a8dae297a1d8bb535a70e56 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 b65a84a882641..294c6fcfa1aa8 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 ed4d610a38946c328f050f7715f307484bcb2705 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Mar 2023 14:36:32 +0530
+Subject: wifi: ath12k: fix memory leak in ath12k_qmi_driver_event_work()
+
+From: Rajat Soni <quic_rajson@quicinc.com>
+
+[ Upstream commit 960412bee0ea75f6b3c2dca4a3535795ee84c47a ]
+
+Currently the buffer pointed by event is not freed in case
+ATH12K_FLAG_UNREGISTERING bit is set, this causes memory leak.
+
+Add a goto skip instead of return, to ensure event and all the
+list entries are freed properly.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Rajat Soni <quic_rajson@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230315090632.15065-1-quic_rajson@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/qmi.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
+index 979a63f2e2ab8..03ba245fbee92 100644
+--- a/drivers/net/wireless/ath/ath12k/qmi.c
++++ b/drivers/net/wireless/ath/ath12k/qmi.c
+@@ -2991,7 +2991,7 @@ static void ath12k_qmi_driver_event_work(struct work_struct *work)
+ spin_unlock(&qmi->event_lock);
+
+ if (test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags))
+- return;
++ goto skip;
+
+ switch (event->type) {
+ case ATH12K_QMI_EVENT_SERVER_ARRIVE:
+@@ -3032,6 +3032,8 @@ static void ath12k_qmi_driver_event_work(struct work_struct *work)
+ ath12k_warn(ab, "invalid event type: %d", event->type);
+ break;
+ }
++
++skip:
+ kfree(event);
+ spin_lock(&qmi->event_lock);
+ }
+--
+2.39.2
+
--- /dev/null
+From f6a2e1b222d135f2a864e0b660db7e8375b96aa9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Jan 2023 07:19:36 +0530
+Subject: wifi: ath12k: Handle lock during peer_id find
+
+From: Ramya Gnanasekar <quic_rgnanase@quicinc.com>
+
+[ Upstream commit 95a389e2ff3212d866cc51c77d682d2934074eb8 ]
+
+ath12k_peer_find_by_id() requires that the caller hold the
+ab->base_lock. Currently the WBM error path does not hold
+the lock and calling that function, leads to the
+following lockdep_assert()in QCN9274:
+
+[105162.160893] ------------[ cut here ]------------
+[105162.160916] WARNING: CPU: 3 PID: 0 at drivers/net/wireless/ath/ath12k/peer.c:71 ath12k_peer_find_by_id+0x52/0x60 [ath12k]
+[105162.160933] Modules linked in: ath12k(O) qrtr_mhi qrtr mac80211 cfg80211 mhi qmi_helpers libarc4 nvme nvme_core [last unloaded: ath12k(O)]
+[105162.160967] CPU: 3 PID: 0 Comm: swapper/3 Tainted: G W O 6.1.0-rc2+ #3
+[105162.160972] Hardware name: Intel(R) Client Systems NUC8i7HVK/NUC8i7HVB, BIOS HNKBLi70.86A.0056.2019.0506.1527 05/06/2019
+[105162.160977] RIP: 0010:ath12k_peer_find_by_id+0x52/0x60 [ath12k]
+[105162.160990] Code: 07 eb 0f 39 68 24 74 0a 48 8b 00 48 39 f8 75 f3 31 c0 5b 5d c3 48 8d bf b0 f2 00 00 be ff ff ff ff e8 22 20 c4 e2 85 c0 75 bf <0f> 0b eb bb 66 2e 0f 1f 84 00 00 00 00 00 41 54 4c 8d a7 98 f2 00
+[105162.160996] RSP: 0018:ffffa223001acc60 EFLAGS: 00010246
+[105162.161003] RAX: 0000000000000000 RBX: ffff9f0573940000 RCX: 0000000000000000
+[105162.161008] RDX: 0000000000000001 RSI: ffffffffa3951c8e RDI: ffffffffa39a96d7
+[105162.161013] RBP: 000000000000000a R08: 0000000000000000 R09: 0000000000000000
+[105162.161017] R10: ffffa223001acb40 R11: ffffffffa3d57c60 R12: ffff9f057394f2e0
+[105162.161022] R13: ffff9f0573940000 R14: ffff9f04ecd659c0 R15: ffff9f04d5a9b040
+[105162.161026] FS: 0000000000000000(0000) GS:ffff9f0575600000(0000) knlGS:0000000000000000
+[105162.161031] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[105162.161036] CR2: 00001d5c8277a008 CR3: 00000001e6224006 CR4: 00000000003706e0
+[105162.161041] Call Trace:
+[105162.161046] <IRQ>
+[105162.161051] ath12k_dp_rx_process_wbm_err+0x6da/0xaf0 [ath12k]
+[105162.161072] ? ath12k_dp_rx_process_err+0x80e/0x15a0 [ath12k]
+[105162.161084] ? __lock_acquire+0x4ca/0x1a60
+[105162.161104] ath12k_dp_service_srng+0x263/0x310 [ath12k]
+[105162.161120] ath12k_pci_ext_grp_napi_poll+0x1c/0x70 [ath12k]
+[105162.161133] __napi_poll+0x22/0x260
+[105162.161141] net_rx_action+0x2f8/0x380
+[105162.161153] __do_softirq+0xd0/0x4c9
+[105162.161162] irq_exit_rcu+0x88/0xe0
+[105162.161169] common_interrupt+0xa5/0xc0
+[105162.161174] </IRQ>
+[105162.161179] <TASK>
+[105162.161184] asm_common_interrupt+0x22/0x40
+
+Handle spin lock/unlock in WBM error path to hold the necessary lock
+expected by ath12k_peer_find_by_id().
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0-03171-QCAHKSWPL_SILICONZ-1
+
+Signed-off-by: Ramya Gnanasekar <quic_rgnanase@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230122014936.3594-1-quic_rgnanase@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_rx.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
+index 83a43ad48c512..de9a4ca66c664 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
+@@ -3494,11 +3494,14 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
+ msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc);
+ peer_id = ath12k_dp_rx_h_peer_id(ab, desc);
+
++ spin_lock(&ab->base_lock);
+ if (!ath12k_peer_find_by_id(ab, peer_id)) {
++ spin_unlock(&ab->base_lock);
+ ath12k_dbg(ab, ATH12K_DBG_DATA, "invalid peer id received in wbm err pkt%d\n",
+ peer_id);
+ return -EINVAL;
+ }
++ spin_unlock(&ab->base_lock);
+
+ if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) {
+ /* First buffer will be freed by the caller, so deduct it's length */
+--
+2.39.2
+
--- /dev/null
+From 134bf0c8e5266d6003a2661b572b091755dbb6a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Jan 2023 15:21:41 +0530
+Subject: wifi: ath12k: PCI ops for wakeup/release MHI
+
+From: Ramya Gnanasekar <quic_rgnanase@quicinc.com>
+
+[ Upstream commit 80e396586d0a94c42015dd9472176d89a3b0e4ca ]
+
+Wakeup/release MHI is not needed before pci_read/write for QCN9274.
+Since wakeup & release MHI is enabled for all QCN9274 and
+WCN7850, below MHI assert is seen in QCN9274
+
+[ 784.906613] BUG: sleeping function called from invalid context at drivers/bus/mhi/host/pm.c:989
+[ 784.906633] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 0, name: swapper/3
+[ 784.906637] preempt_count: 503, expected: 0
+[ 784.906641] RCU nest depth: 0, expected: 0
+[ 784.906644] 2 locks held by swapper/3/0:
+[ 784.906646] #0: ffff8ed348e429e0 (&ab->ce.ce_lock){+.-.}-{2:2}, at: ath12k_ce_recv_process_cb+0xb3/0x2f0 [ath12k]
+[ 784.906664] #1: ffff8ed348e491f0 (&srng->lock_key#3){+.-.}-{2:2}, at: ath12k_ce_recv_process_cb+0xfb/0x2f0 [ath12k]
+[ 784.906678] Preemption disabled at:
+[ 784.906680] [<0000000000000000>] 0x0
+[ 784.906686] CPU: 3 PID: 0 Comm: swapper/3 Tainted: G W O 6.1.0-rc2+ #3
+[ 784.906688] Hardware name: Intel(R) Client Systems NUC8i7HVK/NUC8i7HVB, BIOS HNKBLi70.86A.0056.2019.0506.1527 05/06/2019
+[ 784.906690] Call Trace:
+[ 784.906691] <IRQ>
+[ 784.906693] dump_stack_lvl+0x56/0x7b
+[ 784.906698] __might_resched+0x21c/0x270
+[ 784.906704] __mhi_device_get_sync+0x7d/0x1c0 [mhi]
+[ 784.906714] mhi_device_get_sync+0xd/0x20 [mhi]
+[ 784.906719] ath12k_pci_write32+0x75/0x170 [ath12k]
+[ 784.906729] ath12k_hal_srng_access_end+0x55/0xc0 [ath12k]
+[ 784.906737] ath12k_ce_recv_process_cb+0x1f3/0x2f0 [ath12k]
+[ 784.906776] ? ath12k_pci_ce_tasklet+0x11/0x30 [ath12k]
+[ 784.906788] ath12k_pci_ce_tasklet+0x11/0x30 [ath12k]
+[ 784.906813] tasklet_action_common.isra.18+0xb7/0xe0
+[ 784.906820] __do_softirq+0xd0/0x4c9
+[ 784.906826] irq_exit_rcu+0x88/0xe0
+[ 784.906828] common_interrupt+0xa5/0xc0
+[ 784.906831] </IRQ>
+[ 784.906832] <TASK>
+
+Adding function callbacks for MHI wakeup and release operations.
+QCN9274 does not need wakeup/release, function callbacks are initialized
+to NULL. In case of WCN7850, shadow registers are used to access rings.
+Since, shadow register's offset is less than ACCESS_ALWAYS_OFF,
+mhi_device_get_sync() or mhi_device_put() to wakeup
+and release mhi will not be called during service ring accesses.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0-03171-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
+
+Signed-off-by: Ramya Gnanasekar <quic_rgnanase@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230123095141.5310-1-quic_rgnanase@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/pci.c | 47 ++++++++++++++++++++++-----
+ drivers/net/wireless/ath/ath12k/pci.h | 6 ++++
+ 2 files changed, 44 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
+index f523aa15885f6..00b0080dbac38 100644
+--- a/drivers/net/wireless/ath/ath12k/pci.c
++++ b/drivers/net/wireless/ath/ath12k/pci.c
+@@ -119,6 +119,30 @@ static const char *irq_name[ATH12K_IRQ_NUM_MAX] = {
+ "tcl2host-status-ring",
+ };
+
++static int ath12k_pci_bus_wake_up(struct ath12k_base *ab)
++{
++ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
++
++ return mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
++}
++
++static void ath12k_pci_bus_release(struct ath12k_base *ab)
++{
++ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
++
++ mhi_device_put(ab_pci->mhi_ctrl->mhi_dev);
++}
++
++static const struct ath12k_pci_ops ath12k_pci_ops_qcn9274 = {
++ .wakeup = NULL,
++ .release = NULL,
++};
++
++static const struct ath12k_pci_ops ath12k_pci_ops_wcn7850 = {
++ .wakeup = ath12k_pci_bus_wake_up,
++ .release = ath12k_pci_bus_release,
++};
++
+ static void ath12k_pci_select_window(struct ath12k_pci *ab_pci, u32 offset)
+ {
+ struct ath12k_base *ab = ab_pci->ab;
+@@ -989,13 +1013,14 @@ u32 ath12k_pci_read32(struct ath12k_base *ab, u32 offset)
+ {
+ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
+ u32 val, window_start;
++ int ret = 0;
+
+ /* for offset beyond BAR + 4K - 32, may
+ * need to wakeup MHI to access.
+ */
+ if (test_bit(ATH12K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
+- offset >= ACCESS_ALWAYS_OFF)
+- mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
++ offset >= ACCESS_ALWAYS_OFF && ab_pci->pci_ops->wakeup)
++ ret = ab_pci->pci_ops->wakeup(ab);
+
+ if (offset < WINDOW_START) {
+ val = ioread32(ab->mem + offset);
+@@ -1023,9 +1048,9 @@ u32 ath12k_pci_read32(struct ath12k_base *ab, u32 offset)
+ }
+
+ if (test_bit(ATH12K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
+- offset >= ACCESS_ALWAYS_OFF)
+- mhi_device_put(ab_pci->mhi_ctrl->mhi_dev);
+-
++ offset >= ACCESS_ALWAYS_OFF && ab_pci->pci_ops->release &&
++ !ret)
++ ab_pci->pci_ops->release(ab);
+ return val;
+ }
+
+@@ -1033,13 +1058,14 @@ void ath12k_pci_write32(struct ath12k_base *ab, u32 offset, u32 value)
+ {
+ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
+ u32 window_start;
++ int ret = 0;
+
+ /* for offset beyond BAR + 4K - 32, may
+ * need to wakeup MHI to access.
+ */
+ if (test_bit(ATH12K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
+- offset >= ACCESS_ALWAYS_OFF)
+- mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
++ offset >= ACCESS_ALWAYS_OFF && ab_pci->pci_ops->wakeup)
++ ret = ab_pci->pci_ops->wakeup(ab);
+
+ if (offset < WINDOW_START) {
+ iowrite32(value, ab->mem + offset);
+@@ -1067,8 +1093,9 @@ void ath12k_pci_write32(struct ath12k_base *ab, u32 offset, u32 value)
+ }
+
+ if (test_bit(ATH12K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
+- offset >= ACCESS_ALWAYS_OFF)
+- mhi_device_put(ab_pci->mhi_ctrl->mhi_dev);
++ offset >= ACCESS_ALWAYS_OFF && ab_pci->pci_ops->release &&
++ !ret)
++ ab_pci->pci_ops->release(ab);
+ }
+
+ int ath12k_pci_power_up(struct ath12k_base *ab)
+@@ -1182,6 +1209,7 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
+ case QCN9274_DEVICE_ID:
+ ab_pci->msi_config = &ath12k_msi_config[0];
+ ab->static_window_map = true;
++ ab_pci->pci_ops = &ath12k_pci_ops_qcn9274;
+ ath12k_pci_read_hw_version(ab, &soc_hw_version_major,
+ &soc_hw_version_minor);
+ switch (soc_hw_version_major) {
+@@ -1203,6 +1231,7 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
+ ab_pci->msi_config = &ath12k_msi_config[0];
+ ab->static_window_map = false;
+ ab->hw_rev = ATH12K_HW_WCN7850_HW20;
++ ab_pci->pci_ops = &ath12k_pci_ops_wcn7850;
+ break;
+
+ default:
+diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h
+index 0d9e40ab31f26..0f24fd9395cd9 100644
+--- a/drivers/net/wireless/ath/ath12k/pci.h
++++ b/drivers/net/wireless/ath/ath12k/pci.h
+@@ -86,6 +86,11 @@ enum ath12k_pci_flags {
+ ATH12K_PCI_ASPM_RESTORE,
+ };
+
++struct ath12k_pci_ops {
++ int (*wakeup)(struct ath12k_base *ab);
++ void (*release)(struct ath12k_base *ab);
++};
++
+ struct ath12k_pci {
+ struct pci_dev *pdev;
+ struct ath12k_base *ab;
+@@ -103,6 +108,7 @@ struct ath12k_pci {
+ /* enum ath12k_pci_flags */
+ unsigned long flags;
+ u16 link_ctl;
++ const struct ath12k_pci_ops *pci_ops;
+ };
+
+ static inline struct ath12k_pci *ath12k_pci_priv(struct ath12k_base *ab)
+--
+2.39.2
+
--- /dev/null
+From b45a38b5375a7f18b16cf62e16e93655827ec45e 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 3d33e687964ad..06c362e0b12fc 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -1617,13 +1617,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 dfd068e0f77aec9c8ee234e97894e598d695ec26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 18:24:20 +0900
+Subject: wifi: brcmfmac: pcie: Add IDs/properties for BCM4387
+
+From: Hector Martin <marcan@marcan.st>
+
+[ Upstream commit 117ace4014cce3fb78b40eb8028bb0f4fc37dd6f ]
+
+This chip is present on Apple M1 Pro/Max (t600x) platforms:
+
+* maldives (apple,j314s): MacBook Pro (14-inch, M1 Pro, 2021)
+* maldives (apple,j314c): MacBook Pro (14-inch, M1 Max, 2021)
+* madagascar (apple,j316s): MacBook Pro (16-inch, M1 Pro, 2021)
+* madagascar (apple,j316c): MacBook Pro (16-inch, M1 Max, 2021)
+
+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-7-marcan@marcan.st
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 2 ++
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 8 ++++++++
+ .../net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++
+ 3 files changed, 12 insertions(+)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+index 8073f31be27d9..9cdbd8d438439 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+@@ -737,6 +737,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
+ return 0x170000;
+ case BRCM_CC_4378_CHIP_ID:
+ return 0x352000;
++ case BRCM_CC_4387_CHIP_ID:
++ return 0x740000;
+ default:
+ brcmf_err("unknown chip: %s\n", ci->pub.name);
+ break;
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+index 2835ef4edb18f..d2dad5414f396 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -67,6 +67,7 @@ BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie");
+ BRCMF_FW_DEF(4371, "brcmfmac4371-pcie");
+ BRCMF_FW_CLM_DEF(4377B3, "brcmfmac4377b3-pcie");
+ BRCMF_FW_CLM_DEF(4378B1, "brcmfmac4378b1-pcie");
++BRCMF_FW_CLM_DEF(4387C2, "brcmfmac4387c2-pcie");
+
+ /* firmware config files */
+ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.txt");
+@@ -101,6 +102,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
+ BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
+ BRCMF_FW_ENTRY(BRCM_CC_4377_CHIP_ID, 0xFFFFFFFF, 4377B3), /* revision ID 4 */
+ BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0xFFFFFFFF, 4378B1), /* revision ID 3 */
++ BRCMF_FW_ENTRY(BRCM_CC_4387_CHIP_ID, 0xFFFFFFFF, 4387C2), /* revision ID 7 */
+ };
+
+ #define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */
+@@ -2048,6 +2050,11 @@ static int brcmf_pcie_read_otp(struct brcmf_pciedev_info *devinfo)
+ base = 0x1120;
+ words = 0x170;
+ break;
++ case BRCM_CC_4387_CHIP_ID:
++ coreid = BCMA_CORE_GCI;
++ base = 0x113c;
++ words = 0x170;
++ break;
+ default:
+ /* OTP not supported on this chip */
+ return 0;
+@@ -2662,6 +2669,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = {
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_43596_DEVICE_ID, CYW),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC),
++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC),
+
+ { /* end: all zeroes */ }
+ };
+diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+index 896615f579522..44684bf1b9acc 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+@@ -54,6 +54,7 @@
+ #define BRCM_CC_4371_CHIP_ID 0x4371
+ #define BRCM_CC_4377_CHIP_ID 0x4377
+ #define BRCM_CC_4378_CHIP_ID 0x4378
++#define BRCM_CC_4387_CHIP_ID 0x4387
+ #define CY_CC_4373_CHIP_ID 0x4373
+ #define CY_CC_43012_CHIP_ID 43012
+ #define CY_CC_43439_CHIP_ID 43439
+@@ -95,6 +96,7 @@
+ #define BRCM_PCIE_43596_DEVICE_ID 0x4415
+ #define BRCM_PCIE_4377_DEVICE_ID 0x4488
+ #define BRCM_PCIE_4378_DEVICE_ID 0x4425
++#define BRCM_PCIE_4387_DEVICE_ID 0x4433
+
+ /* brcmsmac IDs */
+ #define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
+--
+2.39.2
+
--- /dev/null
+From d18204d0bc3f5bb47189ad7227a68f8ea6e8a26a 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 a9b9b2dc62d4f..2835ef4edb18f 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -15,6 +15,7 @@
+ #include <linux/sched/signal.h>
+ #include <linux/kthread.h>
+ #include <linux/io.h>
++#include <linux/random.h>
+ #include <asm/unaligned.h>
+
+ #include <soc.h>
+@@ -1653,6 +1654,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,
+@@ -1689,6 +1697,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 5a654f00564867b9a0cdac7d4d57b9b95b60cbc3 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 f83ae0d301d0e..25b2d41de4c1d 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 d65d2b735b4e6c5fad901ce175c40b6186d71fd9 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 e3d44071e06ae03611110f68fc59edc29eabec23 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 9813d7fa18007..1c454392de0be 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+@@ -791,10 +791,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)))
+@@ -808,7 +809,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 125e2f8cdac788170eea0bc198c0b221e945f287 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 9fc2d5d8b7d75..a25fd90816f5b 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -3587,7 +3587,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;
+ u32 sec_key_id = WIDE_ID(DATA_PATH_GROUP, SEC_KEY_CMD);
+ u8 sec_key_ver = iwl_fw_lookup_cmd_ver(mvm->fw, sec_key_id, 0);
+@@ -3739,6 +3739,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 3f15cd11d33cd20e2607ffe81aa976fba05a1df4 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 171b6bf4a65a0..3cc61c30cca16 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+@@ -2861,7 +2861,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 5784bb1be446b95f4532662a23d6f203cd9efa74 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 a0bf19b18635c..f83ae0d301d0e 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+@@ -1698,6 +1698,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
+
--- /dev/null
+From 54ed691081defa064ca970cd6a39b4420a08685b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Apr 2023 00:35:12 -0700
+Subject: wifi: mt76: mt7921: add Netgear AXE3000 (A8000) support
+
+From: Reese Russell <git@qrsnap.io>
+
+[ Upstream commit 03eb52dd78cab08f13925aeec8315fbdbcba3253 ]
+
+Issue: Though the Netgear AXE3000 (A8000) is based on the mt7921
+chipset because of the unique USB VID:PID combination this device
+does not initialize/register. Thus making it not plug and play.
+
+Fix: Adds support for the Netgear AXE3000 (A8000) based on the Mediatek
+mt7921au chipset. The method of action is adding the USD VID/PID
+pair to the mt7921u_device_table[] array.
+
+Notes: A retail sample of the Netgear AXE3000 (A8000) yeilds the following
+from lsusb D 0846:9060 NetGear, Inc. Wireless_Device. This pair
+0846:9060 VID:PID has been reported by other users on Github.
+
+Signed-off-by: Reese Russell <git@qrsnap.io>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/usb.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
+index 70c9bbdbf60e9..09ab9b83c2011 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
+@@ -18,6 +18,9 @@ static const struct usb_device_id mt7921u_device_table[] = {
+ /* Comfast CF-952AX */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x3574, 0x6211, 0xff, 0xff, 0xff),
+ .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
++ /* Netgear, Inc. [A8000,AXE3000] */
++ { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9060, 0xff, 0xff, 0xff),
++ .driver_info = (kernel_ulong_t)MT7921_FIRMWARE_WM },
+ { },
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 93a649e2ce55e154cf496d0d04dad9461b754bb8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 11:03:31 -0500
+Subject: wifi: rtw88: Fix memory leak in rtw88_usb
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+[ Upstream commit 59a3a312009723e3e5082899655fdcc420e2b47a ]
+
+Kmemleak shows the following leak arising from routine in the usb
+probe routine:
+
+unreferenced object 0xffff895cb29bba00 (size 512):
+ comm "(udev-worker)", pid 534, jiffies 4294903932 (age 102751.088s)
+ hex dump (first 32 bytes):
+ 77 30 30 30 00 00 00 00 02 2f 2d 2b 30 00 00 00 w000...../-+0...
+ 02 00 2a 28 00 00 00 00 ff 55 ff ff ff 00 00 00 ..*(.....U......
+ backtrace:
+ [<ffffffff9265fa36>] kmalloc_trace+0x26/0x90
+ [<ffffffffc17eec41>] rtw_usb_probe+0x2f1/0x680 [rtw_usb]
+ [<ffffffffc03e19fd>] usb_probe_interface+0xdd/0x2e0 [usbcore]
+ [<ffffffff92b4f2fe>] really_probe+0x18e/0x3d0
+ [<ffffffff92b4f5b8>] __driver_probe_device+0x78/0x160
+ [<ffffffff92b4f6bf>] driver_probe_device+0x1f/0x90
+ [<ffffffff92b4f8df>] __driver_attach+0xbf/0x1b0
+ [<ffffffff92b4d350>] bus_for_each_dev+0x70/0xc0
+ [<ffffffff92b4e51e>] bus_add_driver+0x10e/0x210
+ [<ffffffff92b50935>] driver_register+0x55/0xf0
+ [<ffffffffc03e0708>] usb_register_driver+0x88/0x140 [usbcore]
+ [<ffffffff92401153>] do_one_initcall+0x43/0x210
+ [<ffffffff9254f42a>] do_init_module+0x4a/0x200
+ [<ffffffff92551d1c>] __do_sys_finit_module+0xac/0x120
+ [<ffffffff92ee6626>] do_syscall_64+0x56/0x80
+ [<ffffffff9300006a>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+The leak was verified to be real by unloading the driver, which resulted
+in a dangling pointer to the allocation.
+
+The allocated memory is freed in rtw_usb_intf_deinit().
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Cc: Sascha Hauer <s.hauer@pengutronix.de>
+Cc: Ping-Ke Shih <pkshih@realtek.com>
+Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230417160331.23071-1-Larry.Finger@lwfinger.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/usb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
+index 8e2c99f9c3662..44a5fafb99055 100644
+--- a/drivers/net/wireless/realtek/rtw88/usb.c
++++ b/drivers/net/wireless/realtek/rtw88/usb.c
+@@ -804,6 +804,7 @@ static void rtw_usb_intf_deinit(struct rtw_dev *rtwdev,
+ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
+
+ usb_put_dev(rtwusb->udev);
++ kfree(rtwusb->usb_data);
+ usb_set_intfdata(intf, NULL);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 3bc47779db4ebaeb943e2d97c7ef5b14110704ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Mar 2023 10:16:36 +0800
+Subject: wifi: rtw88: fix memory leak in rtw_usb_probe()
+
+From: Dongliang Mu <dzm91@hust.edu.cn>
+
+[ Upstream commit 48181d285623198c33bb9698992502687b258efa ]
+
+drivers/net/wireless/realtek/rtw88/usb.c:876 rtw_usb_probe()
+warn: 'hw' from ieee80211_alloc_hw() not released on lines: 811
+
+Fix this by modifying return to a goto statement.
+
+Signed-off-by: Dongliang Mu <dzm91@hust.edu.cn>
+Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230309021636.528601-1-dzm91@hust.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
+index a10d6fef4ffaf..8e2c99f9c3662 100644
+--- a/drivers/net/wireless/realtek/rtw88/usb.c
++++ b/drivers/net/wireless/realtek/rtw88/usb.c
+@@ -832,7 +832,7 @@ int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+
+ ret = rtw_usb_alloc_rx_bufs(rtwusb);
+ if (ret)
+- return ret;
++ goto err_release_hw;
+
+ ret = rtw_core_init(rtwdev);
+ if (ret)
+--
+2.39.2
+
--- /dev/null
+From d159f7548b881f8dea8943ca192b1660b0122ac7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Mar 2023 17:47:10 +0200
+Subject: xhci: Avoid PCI MSI/MSIX interrupt reinitialization at resume
+
+From: Josue David Hernandez Gutierrez <josue.d.hernandez.gutierrez@intel.com>
+
+[ Upstream commit 944e7deb4238d10cd16905474574236ac8a8e847 ]
+
+xhci MSI setup is currently done at the same time as xHC host is started
+in xhci_run(). This couples the generic xhci code with PCI, and will
+reconfigure MSI/MSIX interrupts every time xHC is started.
+
+Decouple MSI/MSIX configuration from generic xhci code by moving MSI/MSIX
+part to a PCI specific xhci_pci_run() function overriding xhci_run().
+
+This allows us to remove unnecessay MSI/MSIX reconfiguration done every
+time PCI xhci resumes from suspend. i.e. remove the xhci_cleanup_msix()
+call from xhci_resume() and the xhci_try_enale_msi() call in xhci_run()
+called a bit later by xhci_resume()
+
+[minor changes and commit message rewrite -Mathias]
+
+Signed-off-by: Josue David Hernandez Gutierrez <josue.d.hernandez.gutierrez@intel.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20230317154715.535523-10-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-pci.c | 15 +++++++++++++++
+ drivers/usb/host/xhci.c | 8 ++------
+ drivers/usb/host/xhci.h | 1 +
+ 3 files changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index 6db07ca419c31..8060782a2367d 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -78,14 +78,29 @@ static const char hcd_name[] = "xhci_hcd";
+ static struct hc_driver __read_mostly xhci_pci_hc_driver;
+
+ static int xhci_pci_setup(struct usb_hcd *hcd);
++static int xhci_pci_run(struct usb_hcd *hcd);
+ static int xhci_pci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
+ struct usb_tt *tt, gfp_t mem_flags);
+
+ static const struct xhci_driver_overrides xhci_pci_overrides __initconst = {
+ .reset = xhci_pci_setup,
++ .start = xhci_pci_run,
+ .update_hub_device = xhci_pci_update_hub_device,
+ };
+
++static int xhci_pci_run(struct usb_hcd *hcd)
++{
++ int ret;
++
++ if (usb_hcd_is_primary_hcd(hcd)) {
++ ret = xhci_try_enable_msi(hcd);
++ if (ret)
++ return ret;
++ }
++
++ return xhci_run(hcd);
++}
++
+ /* called after powerup, by probe or system-pm "wakeup" */
+ static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev)
+ {
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 6307bae9cddff..f498df6b02c80 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -436,7 +436,7 @@ static void __maybe_unused xhci_msix_sync_irqs(struct xhci_hcd *xhci)
+ }
+ }
+
+-static int xhci_try_enable_msi(struct usb_hcd *hcd)
++int xhci_try_enable_msi(struct usb_hcd *hcd)
+ {
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ struct pci_dev *pdev;
+@@ -490,6 +490,7 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
+ hcd->irq = pdev->irq;
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(xhci_try_enable_msi);
+
+ #else
+
+@@ -705,10 +706,6 @@ int xhci_run(struct usb_hcd *hcd)
+
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init, "xhci_run");
+
+- ret = xhci_try_enable_msi(hcd);
+- if (ret)
+- return ret;
+-
+ temp_64 = xhci_read_64(xhci, &ir->ir_set->erst_dequeue);
+ temp_64 &= ~ERST_PTR_MASK;
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init,
+@@ -1250,7 +1247,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
+ spin_unlock_irq(&xhci->lock);
+ if (retval)
+ return retval;
+- xhci_cleanup_msix(xhci);
+
+ xhci_dbg(xhci, "// Disabling event ring interrupts\n");
+ temp = readl(&xhci->op_regs->status);
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 786002bb35db0..26fccc8d90556 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -2143,6 +2143,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated);
+
+ irqreturn_t xhci_irq(struct usb_hcd *hcd);
+ irqreturn_t xhci_msi_irq(int irq, void *hcd);
++int xhci_try_enable_msi(struct usb_hcd *hcd);
+ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev);
+ int xhci_alloc_tt_info(struct xhci_hcd *xhci,
+ struct xhci_virt_device *virt_dev,
+--
+2.39.2
+
--- /dev/null
+From 479165f2f05b12d5912189b24460aec8e7ed34aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Mar 2023 17:47:02 +0200
+Subject: xhci: mem: Carefully calculate size for memory allocations
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 347284984f415e52590373253c6943bbdc806ebf ]
+
+Carefully calculate size for memory allocations, i.e. with help
+of size_mul() macro from overflow.h.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20230317154715.535523-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-mem.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index d0a9467aa5fc4..c385513ad00b6 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -9,6 +9,7 @@
+ */
+
+ #include <linux/usb.h>
++#include <linux/overflow.h>
+ #include <linux/pci.h>
+ #include <linux/slab.h>
+ #include <linux/dmapool.h>
+@@ -568,7 +569,7 @@ static struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci,
+ gfp_t mem_flags)
+ {
+ struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
+- size_t size = sizeof(struct xhci_stream_ctx) * num_stream_ctxs;
++ size_t size = size_mul(sizeof(struct xhci_stream_ctx), num_stream_ctxs);
+
+ if (size > MEDIUM_STREAM_ARRAY_SIZE)
+ return dma_alloc_coherent(dev, size,
+@@ -1660,7 +1661,7 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
+ goto fail_sp;
+
+ xhci->scratchpad->sp_array = dma_alloc_coherent(dev,
+- num_sp * sizeof(u64),
++ size_mul(sizeof(u64), num_sp),
+ &xhci->scratchpad->sp_dma, flags);
+ if (!xhci->scratchpad->sp_array)
+ goto fail_sp2;
+@@ -1799,7 +1800,7 @@ int xhci_alloc_erst(struct xhci_hcd *xhci,
+ struct xhci_segment *seg;
+ struct xhci_erst_entry *entry;
+
+- size = sizeof(struct xhci_erst_entry) * evt_ring->num_segs;
++ size = size_mul(sizeof(struct xhci_erst_entry), evt_ring->num_segs);
+ erst->entries = dma_alloc_coherent(xhci_to_hcd(xhci)->self.sysdev,
+ size, &erst->erst_dma_addr, flags);
+ if (!erst->entries)
+@@ -1830,7 +1831,7 @@ xhci_free_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir)
+ if (!ir)
+ return;
+
+- erst_size = sizeof(struct xhci_erst_entry) * (ir->erst.num_entries);
++ erst_size = sizeof(struct xhci_erst_entry) * ir->erst.num_entries;
+ if (ir->erst.entries)
+ dma_free_coherent(dev, erst_size,
+ ir->erst.entries,
+--
+2.39.2
+