--- /dev/null
+From 3912a78cf72eb45f8153a395162b08fef9c5ec3d Mon Sep 17 00:00:00 2001
+From: Kenneth Feng <kenneth.feng@amd.com>
+Date: Wed, 4 Dec 2024 13:22:10 +0530
+Subject: drm/amd/pm: Set SMU v13.0.7 default workload type
+
+From: Kenneth Feng <kenneth.feng@amd.com>
+
+commit 3912a78cf72eb45f8153a395162b08fef9c5ec3d upstream.
+
+Set the default workload type to bootup type on smu v13.0.7.
+This is because of the constraint on smu v13.0.7.
+Gfx activity has an even higher set point on 3D fullscreen
+mode than the one on bootup mode. This causes the 3D fullscreen
+mode's performance is worse than the bootup mode's performance
+for the lightweighted/medium workload. For the high workload,
+the performance is the same between 3D fullscreen mode and bootup
+mode.
+
+v2: set the default workload in ASIC specific file
+
+Signed-off-by: Kenneth Feng <kenneth.feng@amd.com>
+Reviewed-by: Yang Wang <kevinyang.wang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org # 6.11.x
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+@@ -2717,4 +2717,5 @@ void smu_v13_0_7_set_ppt_funcs(struct sm
+ smu->workload_map = smu_v13_0_7_workload_map;
+ smu->smc_driver_if_version = SMU13_0_7_DRIVER_IF_VERSION;
+ smu_v13_0_set_smu_mailbox_registers(smu);
++ smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
+ }
--- /dev/null
+From 12f325bcd2411e571dbb500bf6862c812c479735 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Fri, 29 Nov 2024 14:19:21 +0100
+Subject: drm/amdgpu: fix UVD contiguous CS mapping problem
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian König <christian.koenig@amd.com>
+
+commit 12f325bcd2411e571dbb500bf6862c812c479735 upstream.
+
+When starting the mpv player, Radeon R9 users are observing
+the below error in dmesg.
+
+[drm:amdgpu_uvd_cs_pass2 [amdgpu]]
+*ERROR* msg/fb buffer ff00f7c000-ff00f7e000 out of 256MB segment!
+
+The patch tries to set the TTM_PL_FLAG_CONTIGUOUS for both user
+flag(AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS) set and not set cases.
+
+v2: Make the TTM_PL_FLAG_CONTIGUOUS mandatory for user BO's.
+v3: revert back to v1, but fix the check instead (chk).
+
+Closes:https://gitlab.freedesktop.org/drm/amd/-/issues/3599
+Closes:https://gitlab.freedesktop.org/drm/amd/-/issues/3501
+Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org # 6.10+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 17 +++++++++++------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 2 ++
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+index d891ab779ca7..5df21529b3b1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -1801,13 +1801,18 @@ int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
+ if (dma_resv_locking_ctx((*bo)->tbo.base.resv) != &parser->exec.ticket)
+ return -EINVAL;
+
++ /* Make sure VRAM is allocated contigiously */
+ (*bo)->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
+- amdgpu_bo_placement_from_domain(*bo, (*bo)->allowed_domains);
+- for (i = 0; i < (*bo)->placement.num_placement; i++)
+- (*bo)->placements[i].flags |= TTM_PL_FLAG_CONTIGUOUS;
+- r = ttm_bo_validate(&(*bo)->tbo, &(*bo)->placement, &ctx);
+- if (r)
+- return r;
++ if ((*bo)->tbo.resource->mem_type == TTM_PL_VRAM &&
++ !((*bo)->tbo.resource->placement & TTM_PL_FLAG_CONTIGUOUS)) {
++
++ amdgpu_bo_placement_from_domain(*bo, (*bo)->allowed_domains);
++ for (i = 0; i < (*bo)->placement.num_placement; i++)
++ (*bo)->placements[i].flags |= TTM_PL_FLAG_CONTIGUOUS;
++ r = ttm_bo_validate(&(*bo)->tbo, &(*bo)->placement, &ctx);
++ if (r)
++ return r;
++ }
+
+ return amdgpu_ttm_alloc_gart(&(*bo)->tbo);
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+index 31fd30dcd593..65bb26215e86 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+@@ -551,6 +551,8 @@ static void amdgpu_uvd_force_into_uvd_segment(struct amdgpu_bo *abo)
+ for (i = 0; i < abo->placement.num_placement; ++i) {
+ abo->placements[i].fpfn = 0 >> PAGE_SHIFT;
+ abo->placements[i].lpfn = (256 * 1024 * 1024) >> PAGE_SHIFT;
++ if (abo->placements[i].mem_type == TTM_PL_VRAM)
++ abo->placements[i].flags |= TTM_PL_FLAG_CONTIGUOUS;
+ }
+ }
+
+--
+2.47.1
+
--- /dev/null
+From f4df208177d02f1c90f3644da3a2453080b8c24f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Fri, 6 Dec 2024 14:46:06 +0100
+Subject: drm/amdgpu: fix when the cleaner shader is emitted
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian König <christian.koenig@amd.com>
+
+commit f4df208177d02f1c90f3644da3a2453080b8c24f upstream.
+
+Emitting the cleaner shader must come after the check if a VM switch is
+necessary or not.
+
+Otherwise we will emit the cleaner shader every time and not just when it is
+necessary because we switched between applications.
+
+This can otherwise crash on gang submit and probably decreases performance
+quite a bit.
+
+v2: squash in fix from Srini (Alex)
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Fixes: ee7a846ea27b ("drm/amdgpu: Emit cleaner shader at end of IB submission")
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index 8d9bf7a0857f..ddd7f05e4db9 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -674,12 +674,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
+ pasid_mapping_needed &= adev->gmc.gmc_funcs->emit_pasid_mapping &&
+ ring->funcs->emit_wreg;
+
+- if (adev->gfx.enable_cleaner_shader &&
+- ring->funcs->emit_cleaner_shader &&
+- job->enforce_isolation)
+- ring->funcs->emit_cleaner_shader(ring);
+-
+- if (!vm_flush_needed && !gds_switch_needed && !need_pipe_sync)
++ if (!vm_flush_needed && !gds_switch_needed && !need_pipe_sync &&
++ !(job->enforce_isolation && !job->vmid))
+ return 0;
+
+ amdgpu_ring_ib_begin(ring);
+@@ -690,6 +686,11 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
+ if (need_pipe_sync)
+ amdgpu_ring_emit_pipeline_sync(ring);
+
++ if (adev->gfx.enable_cleaner_shader &&
++ ring->funcs->emit_cleaner_shader &&
++ job->enforce_isolation)
++ ring->funcs->emit_cleaner_shader(ring);
++
+ if (vm_flush_needed) {
+ trace_amdgpu_vm_flush(ring, job->vmid, job->vm_pd_addr);
+ amdgpu_ring_emit_vm_flush(ring, job->vmid, job->vm_pd_addr);
+--
+2.47.1
+
--- /dev/null
+From a592bb19abdc2072875c87da606461bfd7821b08 Mon Sep 17 00:00:00 2001
+From: Andrew Martin <Andrew.Martin@amd.com>
+Date: Tue, 26 Nov 2024 12:10:59 -0500
+Subject: drm/amdkfd: Dereference null return value
+
+From: Andrew Martin <Andrew.Martin@amd.com>
+
+commit a592bb19abdc2072875c87da606461bfd7821b08 upstream.
+
+In the function pqm_uninit there is a call-assignment of "pdd =
+kfd_get_process_device_data" which could be null, and this value was
+later dereferenced without checking.
+
+Fixes: fb91065851cd ("drm/amdkfd: Refactor queue wptr_bo GART mapping")
+Signed-off-by: Andrew Martin <Andrew.Martin@amd.com>
+Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+index c76db22a1000..59b92d66e958 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+@@ -212,13 +212,17 @@ static void pqm_clean_queue_resource(struct process_queue_manager *pqm,
+ void pqm_uninit(struct process_queue_manager *pqm)
+ {
+ struct process_queue_node *pqn, *next;
+- struct kfd_process_device *pdd;
+
+ list_for_each_entry_safe(pqn, next, &pqm->queues, process_queue_list) {
+ if (pqn->q) {
+- pdd = kfd_get_process_device_data(pqn->q->device, pqm->process);
+- kfd_queue_unref_bo_vas(pdd, &pqn->q->properties);
+- kfd_queue_release_buffers(pdd, &pqn->q->properties);
++ struct kfd_process_device *pdd = kfd_get_process_device_data(pqn->q->device,
++ pqm->process);
++ if (pdd) {
++ kfd_queue_unref_bo_vas(pdd, &pqn->q->properties);
++ kfd_queue_release_buffers(pdd, &pqn->q->properties);
++ } else {
++ WARN_ON(!pdd);
++ }
+ pqm_clean_queue_resource(pqm, pqn);
+ }
+
+--
+2.47.1
+
--- /dev/null
+From 321048c4a3e375416b51b4093978f9ce2aa4d391 Mon Sep 17 00:00:00 2001
+From: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
+Date: Wed, 27 Nov 2024 14:01:35 -0500
+Subject: drm/amdkfd: hard-code cacheline size for gfx11
+
+From: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
+
+commit 321048c4a3e375416b51b4093978f9ce2aa4d391 upstream.
+
+This information is not available in ip discovery table.
+
+Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
+Reviewed-by: David Belanger <david.belanger@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 22 ++++++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+@@ -1422,6 +1422,7 @@ err:
+
+
+ static int kfd_fill_gpu_cache_info_from_gfx_config(struct kfd_dev *kdev,
++ bool cache_line_size_missing,
+ struct kfd_gpu_cache_info *pcache_info)
+ {
+ struct amdgpu_device *adev = kdev->adev;
+@@ -1436,6 +1437,8 @@ static int kfd_fill_gpu_cache_info_from_
+ CRAT_CACHE_FLAGS_SIMD_CACHE);
+ pcache_info[i].num_cu_shared = adev->gfx.config.gc_num_tcp_per_wpg / 2;
+ pcache_info[i].cache_line_size = adev->gfx.config.gc_tcp_cache_line_size;
++ if (cache_line_size_missing && !pcache_info[i].cache_line_size)
++ pcache_info[i].cache_line_size = 128;
+ i++;
+ }
+ /* Scalar L1 Instruction Cache per SQC */
+@@ -1448,6 +1451,8 @@ static int kfd_fill_gpu_cache_info_from_
+ CRAT_CACHE_FLAGS_SIMD_CACHE);
+ pcache_info[i].num_cu_shared = adev->gfx.config.gc_num_sqc_per_wgp * 2;
+ pcache_info[i].cache_line_size = adev->gfx.config.gc_instruction_cache_line_size;
++ if (cache_line_size_missing && !pcache_info[i].cache_line_size)
++ pcache_info[i].cache_line_size = 128;
+ i++;
+ }
+ /* Scalar L1 Data Cache per SQC */
+@@ -1459,6 +1464,8 @@ static int kfd_fill_gpu_cache_info_from_
+ CRAT_CACHE_FLAGS_SIMD_CACHE);
+ pcache_info[i].num_cu_shared = adev->gfx.config.gc_num_sqc_per_wgp * 2;
+ pcache_info[i].cache_line_size = adev->gfx.config.gc_scalar_data_cache_line_size;
++ if (cache_line_size_missing && !pcache_info[i].cache_line_size)
++ pcache_info[i].cache_line_size = 64;
+ i++;
+ }
+ /* GL1 Data Cache per SA */
+@@ -1471,7 +1478,8 @@ static int kfd_fill_gpu_cache_info_from_
+ CRAT_CACHE_FLAGS_DATA_CACHE |
+ CRAT_CACHE_FLAGS_SIMD_CACHE);
+ pcache_info[i].num_cu_shared = adev->gfx.config.max_cu_per_sh;
+- pcache_info[i].cache_line_size = 0;
++ if (cache_line_size_missing)
++ pcache_info[i].cache_line_size = 128;
+ i++;
+ }
+ /* L2 Data Cache per GPU (Total Tex Cache) */
+@@ -1483,6 +1491,8 @@ static int kfd_fill_gpu_cache_info_from_
+ CRAT_CACHE_FLAGS_SIMD_CACHE);
+ pcache_info[i].num_cu_shared = adev->gfx.config.max_cu_per_sh;
+ pcache_info[i].cache_line_size = adev->gfx.config.gc_tcc_cache_line_size;
++ if (cache_line_size_missing && !pcache_info[i].cache_line_size)
++ pcache_info[i].cache_line_size = 128;
+ i++;
+ }
+ /* L3 Data Cache per GPU */
+@@ -1568,6 +1578,7 @@ static int kfd_fill_gpu_cache_info_from_
+ int kfd_get_gpu_cache_info(struct kfd_node *kdev, struct kfd_gpu_cache_info **pcache_info)
+ {
+ int num_of_cache_types = 0;
++ bool cache_line_size_missing = false;
+
+ switch (kdev->adev->asic_type) {
+ case CHIP_KAVERI:
+@@ -1691,10 +1702,17 @@ int kfd_get_gpu_cache_info(struct kfd_no
+ case IP_VERSION(11, 5, 0):
+ case IP_VERSION(11, 5, 1):
+ case IP_VERSION(11, 5, 2):
++ /* Cacheline size not available in IP discovery for gc11.
++ * kfd_fill_gpu_cache_info_from_gfx_config to hard code it
++ */
++ cache_line_size_missing = true;
++ fallthrough;
+ case IP_VERSION(12, 0, 0):
+ case IP_VERSION(12, 0, 1):
+ num_of_cache_types =
+- kfd_fill_gpu_cache_info_from_gfx_config(kdev->kfd, *pcache_info);
++ kfd_fill_gpu_cache_info_from_gfx_config(kdev->kfd,
++ cache_line_size_missing,
++ *pcache_info);
+ break;
+ default:
+ *pcache_info = dummy_cache_info;
--- /dev/null
+From d50bf3f0fab636574c163ba8b5863e12b1ed19bd Mon Sep 17 00:00:00 2001
+From: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
+Date: Thu, 28 Nov 2024 11:07:57 -0500
+Subject: drm/amdkfd: hard-code MALL cacheline size for gfx11, gfx12
+
+From: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
+
+commit d50bf3f0fab636574c163ba8b5863e12b1ed19bd upstream.
+
+This information is not available in ip discovery table.
+
+Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
+Reviewed-by: David Belanger <david.belanger@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+@@ -1503,7 +1503,7 @@ static int kfd_fill_gpu_cache_info_from_
+ CRAT_CACHE_FLAGS_DATA_CACHE |
+ CRAT_CACHE_FLAGS_SIMD_CACHE);
+ pcache_info[i].num_cu_shared = adev->gfx.config.max_cu_per_sh;
+- pcache_info[i].cache_line_size = 0;
++ pcache_info[i].cache_line_size = 64;
+ i++;
+ }
+ return i;
--- /dev/null
+From 438b39ac74e2a9dc0a5c9d653b7d8066877e86b1 Mon Sep 17 00:00:00 2001
+From: "Jesse.zhang@amd.com" <Jesse.zhang@amd.com>
+Date: Thu, 5 Dec 2024 17:41:26 +0800
+Subject: drm/amdkfd: pause autosuspend when creating pdd
+
+From: Jesse.zhang@amd.com <Jesse.zhang@amd.com>
+
+commit 438b39ac74e2a9dc0a5c9d653b7d8066877e86b1 upstream.
+
+When using MES creating a pdd will require talking to the GPU to
+setup the relevant context. The code here forgot to wake up the GPU
+in case it was in suspend, this causes KVM to EFAULT for passthrough
+GPU for example. This issue can be masked if the GPU was woken up by
+other things (e.g. opening the KMS node) first and have not yet gone to sleep.
+
+v4: do the allocation of proc_ctx_bo in a lazy fashion
+when the first queue is created in a process (Felix)
+
+Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
+Reviewed-by: Yunxiang Li <Yunxiang.Li@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 15 +++++++++++
+ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 23 +-----------------
+ 2 files changed, 17 insertions(+), 21 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+@@ -205,6 +205,21 @@ static int add_queue_mes(struct device_q
+ if (!down_read_trylock(&adev->reset_domain->sem))
+ return -EIO;
+
++ if (!pdd->proc_ctx_cpu_ptr) {
++ r = amdgpu_amdkfd_alloc_gtt_mem(adev,
++ AMDGPU_MES_PROC_CTX_SIZE,
++ &pdd->proc_ctx_bo,
++ &pdd->proc_ctx_gpu_addr,
++ &pdd->proc_ctx_cpu_ptr,
++ false);
++ if (r) {
++ dev_err(adev->dev,
++ "failed to allocate process context bo\n");
++ return r;
++ }
++ memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);
++ }
++
+ memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input));
+ queue_input.process_id = qpd->pqm->process->pasid;
+ queue_input.page_table_base_addr = qpd->page_table_base;
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+@@ -1076,7 +1076,8 @@ static void kfd_process_destroy_pdds(str
+
+ kfd_free_process_doorbells(pdd->dev->kfd, pdd);
+
+- if (pdd->dev->kfd->shared_resources.enable_mes)
++ if (pdd->dev->kfd->shared_resources.enable_mes &&
++ pdd->proc_ctx_cpu_ptr)
+ amdgpu_amdkfd_free_gtt_mem(pdd->dev->adev,
+ &pdd->proc_ctx_bo);
+ /*
+@@ -1610,7 +1611,6 @@ struct kfd_process_device *kfd_create_pr
+ struct kfd_process *p)
+ {
+ struct kfd_process_device *pdd = NULL;
+- int retval = 0;
+
+ if (WARN_ON_ONCE(p->n_pdds >= MAX_GPU_INSTANCE))
+ return NULL;
+@@ -1634,21 +1634,6 @@ struct kfd_process_device *kfd_create_pr
+ pdd->user_gpu_id = dev->id;
+ atomic64_set(&pdd->evict_duration_counter, 0);
+
+- if (dev->kfd->shared_resources.enable_mes) {
+- retval = amdgpu_amdkfd_alloc_gtt_mem(dev->adev,
+- AMDGPU_MES_PROC_CTX_SIZE,
+- &pdd->proc_ctx_bo,
+- &pdd->proc_ctx_gpu_addr,
+- &pdd->proc_ctx_cpu_ptr,
+- false);
+- if (retval) {
+- dev_err(dev->adev->dev,
+- "failed to allocate process context bo\n");
+- goto err_free_pdd;
+- }
+- memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);
+- }
+-
+ p->pdds[p->n_pdds++] = pdd;
+ if (kfd_dbg_is_per_vmid_supported(pdd->dev))
+ pdd->spi_dbg_override = pdd->dev->kfd2kgd->disable_debug_trap(
+@@ -1660,10 +1645,6 @@ struct kfd_process_device *kfd_create_pr
+ idr_init(&pdd->alloc_idr);
+
+ return pdd;
+-
+-err_free_pdd:
+- kfree(pdd);
+- return NULL;
+ }
+
+ /**
--- /dev/null
+From cd3da567e2e46b8f75549637b960a83b024d6b6e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Wed, 20 Nov 2024 18:41:21 +0200
+Subject: drm/i915/color: Stop using non-posted DSB writes for legacy LUT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit cd3da567e2e46b8f75549637b960a83b024d6b6e upstream.
+
+DSB LUT register writes vs. palette anti-collision logic
+appear to interact in interesting ways:
+- posted DSB writes simply vanish into thin air while
+ anti-collision is active
+- non-posted DSB writes actually get blocked by the anti-collision
+ logic, but unfortunately this ends up hogging the bus for
+ long enough that unrelated parallel CPU MMIO accesses start
+ to disappear instead
+
+Even though we are updating the LUT during vblank we aren't
+immune to the anti-collision logic because it kicks in briefly
+for pipe prefill (initiated at frame start). The safe time
+window for performing the LUT update is thus between the
+undelayed vblank and frame start. Turns out that with low
+enough CDCLK frequency (DSB execution speed depends on CDCLK)
+we can exceed that.
+
+As we are currently using non-posted writes for the legacy LUT
+updates, in which case we can hit the far more severe failure
+mode. The problem is exacerbated by the fact that non-posted
+writes are much slower than posted writes (~4x it seems).
+
+To mititage the problem let's switch to using posted DSB
+writes for legacy LUT updates (which will involve using the
+double write approach to avoid other problems with DSB
+vs. legacy LUT writes). Despite writing each register twice
+this will in fact make the legacy LUT update faster when
+compared to the non-posted write approach, making the
+problem less likely to appear. The failure mode is also
+less severe.
+
+This isn't the 100% solution we need though. That will involve
+estimating how long the LUT update will take, and pushing
+frame start and/or delayed vblank forward to guarantee that
+the update will have finished by the time the pipe prefill
+starts...
+
+Cc: stable@vger.kernel.org
+Fixes: 34d8311f4a1c ("drm/i915/dsb: Re-instate DSB for LUT updates")
+Fixes: 25ea3411bd23 ("drm/i915/dsb: Use non-posted register writes for legacy LUT")
+Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12494
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20241120164123.12706-3-ville.syrjala@linux.intel.com
+Reviewed-by: Uma Shankar <uma.shankar@intel.com>
+(cherry picked from commit 2504a316b35d49522f39cf0dc01830d7c36a9be4)
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/display/intel_color.c | 30 +++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+--- a/drivers/gpu/drm/i915/display/intel_color.c
++++ b/drivers/gpu/drm/i915/display/intel_color.c
+@@ -1333,19 +1333,29 @@ static void ilk_load_lut_8(const struct
+ lut = blob->data;
+
+ /*
+- * DSB fails to correctly load the legacy LUT
+- * unless we either write each entry twice,
+- * or use non-posted writes
++ * DSB fails to correctly load the legacy LUT unless
++ * we either write each entry twice when using posted
++ * writes, or we use non-posted writes.
++ *
++ * If palette anti-collision is active during LUT
++ * register writes:
++ * - posted writes simply get dropped and thus the LUT
++ * contents may not be correctly updated
++ * - non-posted writes are blocked and thus the LUT
++ * contents are always correct, but simultaneous CPU
++ * MMIO access will start to fail
++ *
++ * Choose the lesser of two evils and use posted writes.
++ * Using posted writes is also faster, even when having
++ * to write each register twice.
+ */
+- if (crtc_state->dsb_color_vblank)
+- intel_dsb_nonpost_start(crtc_state->dsb_color_vblank);
+-
+- for (i = 0; i < 256; i++)
++ for (i = 0; i < 256; i++) {
+ ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
+ i9xx_lut_8(&lut[i]));
+-
+- if (crtc_state->dsb_color_vblank)
+- intel_dsb_nonpost_end(crtc_state->dsb_color_vblank);
++ if (crtc_state->dsb_color_vblank)
++ ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
++ i9xx_lut_8(&lut[i]));
++ }
+ }
+
+ static void ilk_load_lut_10(const struct intel_crtc_state *crtc_state,
--- /dev/null
+From 2828e5808bcd5aae7fdcd169cac1efa2701fa2dd Mon Sep 17 00:00:00 2001
+From: Jiasheng Jiang <jiashengjiangcool@outlook.com>
+Date: Wed, 27 Nov 2024 20:10:42 +0000
+Subject: drm/i915: Fix memory leak by correcting cache object name in error handler
+
+From: Jiasheng Jiang <jiashengjiangcool@outlook.com>
+
+commit 2828e5808bcd5aae7fdcd169cac1efa2701fa2dd upstream.
+
+Replace "slab_priorities" with "slab_dependencies" in the error handler
+to avoid memory leak.
+
+Fixes: 32eb6bcfdda9 ("drm/i915: Make request allocation caches global")
+Cc: <stable@vger.kernel.org> # v5.2+
+Signed-off-by: Jiasheng Jiang <jiashengjiangcool@outlook.com>
+Reviewed-by: Nirmoy Das <nirmoy.das@intel.com>
+Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
+Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20241127201042.29620-1-jiashengjiangcool@gmail.com
+(cherry picked from commit 9bc5e7dc694d3112bbf0fa4c46ef0fa0f114937a)
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/i915_scheduler.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/i915_scheduler.c
++++ b/drivers/gpu/drm/i915/i915_scheduler.c
+@@ -506,6 +506,6 @@ int __init i915_scheduler_module_init(vo
+ return 0;
+
+ err_priorities:
+- kmem_cache_destroy(slab_priorities);
++ kmem_cache_destroy(slab_dependencies);
+ return -ENOMEM;
+ }
--- /dev/null
+From da0b986256ae9a78b0215214ff44f271bfe237c1 Mon Sep 17 00:00:00 2001
+From: Eugene Kobyak <eugene.kobyak@intel.com>
+Date: Tue, 3 Dec 2024 14:54:06 +0000
+Subject: drm/i915: Fix NULL pointer dereference in capture_engine
+
+From: Eugene Kobyak <eugene.kobyak@intel.com>
+
+commit da0b986256ae9a78b0215214ff44f271bfe237c1 upstream.
+
+When the intel_context structure contains NULL,
+it raises a NULL pointer dereference error in drm_info().
+
+Fixes: e8a3319c31a1 ("drm/i915: Allow error capture without a request")
+Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12309
+Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
+Cc: John Harrison <John.C.Harrison@Intel.com>
+Cc: <stable@vger.kernel.org> # v6.3+
+Signed-off-by: Eugene Kobyak <eugene.kobyak@intel.com>
+Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/xmsgfynkhycw3cf56akp4he2ffg44vuratocsysaowbsnhutzi@augnqbm777at
+(cherry picked from commit 754302a5bc1bd8fd3b7d85c168b0a1af6d4bba4d)
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/i915_gpu_error.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_gpu_error.c
++++ b/drivers/gpu/drm/i915/i915_gpu_error.c
+@@ -1652,9 +1652,21 @@ capture_engine(struct intel_engine_cs *e
+ return NULL;
+
+ intel_engine_get_hung_entity(engine, &ce, &rq);
+- if (rq && !i915_request_started(rq))
+- drm_info(&engine->gt->i915->drm, "Got hung context on %s with active request %lld:%lld [0x%04X] not yet started\n",
+- engine->name, rq->fence.context, rq->fence.seqno, ce->guc_id.id);
++ if (rq && !i915_request_started(rq)) {
++ /*
++ * We want to know also what is the guc_id of the context,
++ * but if we don't have the context reference, then skip
++ * printing it.
++ */
++ if (ce)
++ drm_info(&engine->gt->i915->drm,
++ "Got hung context on %s with active request %lld:%lld [0x%04X] not yet started\n",
++ engine->name, rq->fence.context, rq->fence.seqno, ce->guc_id.id);
++ else
++ drm_info(&engine->gt->i915->drm,
++ "Got hung context on %s with active request %lld:%lld not yet started\n",
++ engine->name, rq->fence.context, rq->fence.seqno);
++ }
+
+ if (rq) {
+ capture = intel_engine_coredump_add_request(ee, rq, ATOMIC_MAYFAIL);
--- /dev/null
+From cefade70f346160f47cc24776160329e2ee63653 Mon Sep 17 00:00:00 2001
+From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Date: Thu, 5 Dec 2024 17:50:22 -0800
+Subject: drm/xe: Call invalidation_fence_fini for PT inval fences in error state
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+
+commit cefade70f346160f47cc24776160329e2ee63653 upstream.
+
+Invalidation_fence_init takes a PM reference, which is released in its
+_fini counterpart, so we need to make sure that the latter is called,
+even if the fence is in an error state.
+
+Since we already have a function that calls _fini() and signals the
+fence in the tlb inval code, we can expose that and call it from the PT
+code.
+
+Fixes: f002702290fc ("drm/xe: Hold a PM ref when GT TLB invalidations are inflight")
+Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Cc: <stable@vger.kernel.org> # v6.11+
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Nirmoy Das <nirmoy.das@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Reviewed-by: Nirmoy Das <nirmoy.das@intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20241206015022.1567113-1-daniele.ceraolospurio@intel.com
+(cherry picked from commit 65338639b79ce88aef5263cd518cde570a3c7c8e)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c | 8 ++++++++
+ drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h | 1 +
+ drivers/gpu/drm/xe/xe_pt.c | 3 +--
+ 3 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c
+index 3cb228c773cd..6146d1776bda 100644
+--- a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c
++++ b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c
+@@ -65,6 +65,14 @@ invalidation_fence_signal(struct xe_device *xe, struct xe_gt_tlb_invalidation_fe
+ __invalidation_fence_signal(xe, fence);
+ }
+
++void xe_gt_tlb_invalidation_fence_signal(struct xe_gt_tlb_invalidation_fence *fence)
++{
++ if (WARN_ON_ONCE(!fence->gt))
++ return;
++
++ __invalidation_fence_signal(gt_to_xe(fence->gt), fence);
++}
++
+ static void xe_gt_tlb_fence_timeout(struct work_struct *work)
+ {
+ struct xe_gt *gt = container_of(work, struct xe_gt,
+diff --git a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h
+index f430d5797af7..00b1c6c01e8d 100644
+--- a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h
++++ b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h
+@@ -28,6 +28,7 @@ int xe_guc_tlb_invalidation_done_handler(struct xe_guc *guc, u32 *msg, u32 len);
+ void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt,
+ struct xe_gt_tlb_invalidation_fence *fence,
+ bool stack);
++void xe_gt_tlb_invalidation_fence_signal(struct xe_gt_tlb_invalidation_fence *fence);
+
+ static inline void
+ xe_gt_tlb_invalidation_fence_wait(struct xe_gt_tlb_invalidation_fence *fence)
+diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
+index f27f579f4d85..797576690356 100644
+--- a/drivers/gpu/drm/xe/xe_pt.c
++++ b/drivers/gpu/drm/xe/xe_pt.c
+@@ -1333,8 +1333,7 @@ static void invalidation_fence_cb(struct dma_fence *fence,
+ queue_work(system_wq, &ifence->work);
+ } else {
+ ifence->base.base.error = ifence->fence->error;
+- dma_fence_signal(&ifence->base.base);
+- dma_fence_put(&ifence->base.base);
++ xe_gt_tlb_invalidation_fence_signal(&ifence->base);
+ }
+ dma_fence_put(ifence->fence);
+ }
+--
+2.47.1
+
--- /dev/null
+From 1f806218164d1bb93f3db21eaf61254b08acdf03 Mon Sep 17 00:00:00 2001
+From: "Luis Claudio R. Goncalves" <lgoncalv@redhat.com>
+Date: Fri, 6 Dec 2024 10:01:14 -0300
+Subject: iommu/tegra241-cmdqv: do not use smp_processor_id in preemptible context
+
+From: Luis Claudio R. Goncalves <lgoncalv@redhat.com>
+
+commit 1f806218164d1bb93f3db21eaf61254b08acdf03 upstream.
+
+During boot some of the calls to tegra241_cmdqv_get_cmdq() will happen
+in preemptible context. As this function calls smp_processor_id(), if
+CONFIG_DEBUG_PREEMPT is enabled, these calls will trigger a series of
+"BUG: using smp_processor_id() in preemptible" backtraces.
+
+As tegra241_cmdqv_get_cmdq() only calls smp_processor_id() to use the
+CPU number as a factor to balance out traffic on cmdq usage, it is safe
+to use raw_smp_processor_id() here.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 918eb5c856f6 ("iommu/arm-smmu-v3: Add in-kernel support for NVIDIA Tegra241 (Grace) CMDQV")
+Signed-off-by: Luis Claudio R. Goncalves <lgoncalv@redhat.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Link: https://lore.kernel.org/r/Z1L1mja3nXzsJ0Pk@uudg.org
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
+index c8ec74f089f3..6e41ddaa24d6 100644
+--- a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
++++ b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
+@@ -339,7 +339,7 @@ tegra241_cmdqv_get_cmdq(struct arm_smmu_device *smmu,
+ * one CPU at a time can enter the process, while the others
+ * will be spinning at the same lock.
+ */
+- lidx = smp_processor_id() % cmdqv->num_lvcmdqs_per_vintf;
++ lidx = raw_smp_processor_id() % cmdqv->num_lvcmdqs_per_vintf;
+ vcmdq = vintf->lvcmdqs[lidx];
+ if (!vcmdq || !READ_ONCE(vcmdq->enabled))
+ return NULL;
+--
+2.47.1
+
--- /dev/null
+From 74536f91962d5f6af0a42414773ce61e653c10ee Mon Sep 17 00:00:00 2001
+From: Yi Liu <yi.l.liu@intel.com>
+Date: Fri, 13 Dec 2024 09:17:51 +0800
+Subject: iommu/vt-d: Fix qi_batch NULL pointer with nested parent domain
+
+From: Yi Liu <yi.l.liu@intel.com>
+
+commit 74536f91962d5f6af0a42414773ce61e653c10ee upstream.
+
+The qi_batch is allocated when assigning cache tag for a domain. While
+for nested parent domain, it is missed. Hence, when trying to map pages
+to the nested parent, NULL dereference occurred. Also, there is potential
+memleak since there is no lock around domain->qi_batch allocation.
+
+To solve it, add a helper for qi_batch allocation, and call it in both
+the __cache_tag_assign_domain() and __cache_tag_assign_parent_domain().
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000200
+ #PF: supervisor read access in kernel mode
+ #PF: error_code(0x0000) - not-present page
+ PGD 8104795067 P4D 0
+ Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI
+ CPU: 223 UID: 0 PID: 4357 Comm: qemu-system-x86 Not tainted 6.13.0-rc1-00028-g4b50c3c3b998-dirty #2632
+ Call Trace:
+ ? __die+0x24/0x70
+ ? page_fault_oops+0x80/0x150
+ ? do_user_addr_fault+0x63/0x7b0
+ ? exc_page_fault+0x7c/0x220
+ ? asm_exc_page_fault+0x26/0x30
+ ? cache_tag_flush_range_np+0x13c/0x260
+ intel_iommu_iotlb_sync_map+0x1a/0x30
+ iommu_map+0x61/0xf0
+ batch_to_domain+0x188/0x250
+ iopt_area_fill_domains+0x125/0x320
+ ? rcu_is_watching+0x11/0x50
+ iopt_map_pages+0x63/0x100
+ iopt_map_common.isra.0+0xa7/0x190
+ iopt_map_user_pages+0x6a/0x80
+ iommufd_ioas_map+0xcd/0x1d0
+ iommufd_fops_ioctl+0x118/0x1c0
+ __x64_sys_ioctl+0x93/0xc0
+ do_syscall_64+0x71/0x140
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 705c1cdf1e73 ("iommu/vt-d: Introduce batched cache invalidation")
+Cc: stable@vger.kernel.org
+Co-developed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Yi Liu <yi.l.liu@intel.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20241210130322.17175-1-yi.l.liu@intel.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/intel/cache.c | 34 +++++++++++++++++++++++++++-------
+ 1 file changed, 27 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/iommu/intel/cache.c b/drivers/iommu/intel/cache.c
+index e5b89f728ad3..09694cca8752 100644
+--- a/drivers/iommu/intel/cache.c
++++ b/drivers/iommu/intel/cache.c
+@@ -105,12 +105,35 @@ static void cache_tag_unassign(struct dmar_domain *domain, u16 did,
+ spin_unlock_irqrestore(&domain->cache_lock, flags);
+ }
+
++/* domain->qi_batch will be freed in iommu_free_domain() path. */
++static int domain_qi_batch_alloc(struct dmar_domain *domain)
++{
++ unsigned long flags;
++ int ret = 0;
++
++ spin_lock_irqsave(&domain->cache_lock, flags);
++ if (domain->qi_batch)
++ goto out_unlock;
++
++ domain->qi_batch = kzalloc(sizeof(*domain->qi_batch), GFP_ATOMIC);
++ if (!domain->qi_batch)
++ ret = -ENOMEM;
++out_unlock:
++ spin_unlock_irqrestore(&domain->cache_lock, flags);
++
++ return ret;
++}
++
+ static int __cache_tag_assign_domain(struct dmar_domain *domain, u16 did,
+ struct device *dev, ioasid_t pasid)
+ {
+ struct device_domain_info *info = dev_iommu_priv_get(dev);
+ int ret;
+
++ ret = domain_qi_batch_alloc(domain);
++ if (ret)
++ return ret;
++
+ ret = cache_tag_assign(domain, did, dev, pasid, CACHE_TAG_IOTLB);
+ if (ret || !info->ats_enabled)
+ return ret;
+@@ -139,6 +162,10 @@ static int __cache_tag_assign_parent_domain(struct dmar_domain *domain, u16 did,
+ struct device_domain_info *info = dev_iommu_priv_get(dev);
+ int ret;
+
++ ret = domain_qi_batch_alloc(domain);
++ if (ret)
++ return ret;
++
+ ret = cache_tag_assign(domain, did, dev, pasid, CACHE_TAG_NESTING_IOTLB);
+ if (ret || !info->ats_enabled)
+ return ret;
+@@ -190,13 +217,6 @@ int cache_tag_assign_domain(struct dmar_domain *domain,
+ u16 did = domain_get_id_for_dev(domain, dev);
+ int ret;
+
+- /* domain->qi_bach will be freed in iommu_free_domain() path. */
+- if (!domain->qi_batch) {
+- domain->qi_batch = kzalloc(sizeof(*domain->qi_batch), GFP_KERNEL);
+- if (!domain->qi_batch)
+- return -ENOMEM;
+- }
+-
+ ret = __cache_tag_assign_domain(domain, did, dev, pasid);
+ if (ret || domain->domain.type != IOMMU_DOMAIN_NESTED)
+ return ret;
+--
+2.47.1
+
--- /dev/null
+From 1f2557e08a617a4b5e92a48a1a9a6f86621def18 Mon Sep 17 00:00:00 2001
+From: Lu Baolu <baolu.lu@linux.intel.com>
+Date: Fri, 13 Dec 2024 09:17:50 +0800
+Subject: iommu/vt-d: Remove cache tags before disabling ATS
+
+From: Lu Baolu <baolu.lu@linux.intel.com>
+
+commit 1f2557e08a617a4b5e92a48a1a9a6f86621def18 upstream.
+
+The current implementation removes cache tags after disabling ATS,
+leading to potential memory leaks and kernel crashes. Specifically,
+CACHE_TAG_DEVTLB type cache tags may still remain in the list even
+after the domain is freed, causing a use-after-free condition.
+
+This issue really shows up when multiple VFs from different PFs
+passed through to a single user-space process via vfio-pci. In such
+cases, the kernel may crash with kernel messages like:
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000014
+ PGD 19036a067 P4D 1940a3067 PUD 136c9b067 PMD 0
+ Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI
+ CPU: 74 UID: 0 PID: 3183 Comm: testCli Not tainted 6.11.9 #2
+ RIP: 0010:cache_tag_flush_range+0x9b/0x250
+ Call Trace:
+ <TASK>
+ ? __die+0x1f/0x60
+ ? page_fault_oops+0x163/0x590
+ ? exc_page_fault+0x72/0x190
+ ? asm_exc_page_fault+0x22/0x30
+ ? cache_tag_flush_range+0x9b/0x250
+ ? cache_tag_flush_range+0x5d/0x250
+ intel_iommu_tlb_sync+0x29/0x40
+ intel_iommu_unmap_pages+0xfe/0x160
+ __iommu_unmap+0xd8/0x1a0
+ vfio_unmap_unpin+0x182/0x340 [vfio_iommu_type1]
+ vfio_remove_dma+0x2a/0xb0 [vfio_iommu_type1]
+ vfio_iommu_type1_ioctl+0xafa/0x18e0 [vfio_iommu_type1]
+
+Move cache_tag_unassign_domain() before iommu_disable_pci_caps() to fix
+it.
+
+Fixes: 3b1d9e2b2d68 ("iommu/vt-d: Add cache tag assignment interface")
+Cc: stable@vger.kernel.org
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20241129020506.576413-1-baolu.lu@linux.intel.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/intel/iommu.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -3372,6 +3372,9 @@ void device_block_translation(struct dev
+ struct intel_iommu *iommu = info->iommu;
+ unsigned long flags;
+
++ if (info->domain)
++ cache_tag_unassign_domain(info->domain, dev, IOMMU_NO_PASID);
++
+ iommu_disable_pci_caps(info);
+ if (!dev_is_real_dma_subdevice(dev)) {
+ if (sm_supported(iommu))
+@@ -3388,7 +3391,6 @@ void device_block_translation(struct dev
+ list_del(&info->link);
+ spin_unlock_irqrestore(&info->domain->lock, flags);
+
+- cache_tag_unassign_domain(info->domain, dev, IOMMU_NO_PASID);
+ domain_detach_iommu(info->domain, iommu);
+ info->domain = NULL;
+ }
usb-dwc2-hcd-fix-getportstatus-setportfeature.patch
usb-dwc2-fix-hcd-port-connection-race.patch
scsi-ufs-core-update-compl_time_stamp_local_clock-after-completing-a-cqe.patch
+usb-gadget-midi2-fix-interpretation-of-is_midi1-bits.patch
+usb-ehci-hcd-fix-call-balance-of-clocks-handling-routines.patch
+usb-typec-anx7411-fix-fwnode_handle-reference-leak.patch
+usb-dwc3-imx8mp-fix-software-node-kernel-dump.patch
+usb-typec-anx7411-fix-of-node-reference-leaks-in-anx7411_typec_switch_probe.patch
+usb-gadget-u_serial-fix-the-issue-that-gs_start_io-crashed-due-to-accessing-null-pointer.patch
+usb-typec-ucsi-fix-completion-notifications.patch
+usb-dwc3-xilinx-make-sure-pipe-clock-is-deselected-in-usb2-only-mode.patch
+iommu-tegra241-cmdqv-do-not-use-smp_processor_id-in-preemptible-context.patch
+iommu-vt-d-remove-cache-tags-before-disabling-ats.patch
+iommu-vt-d-fix-qi_batch-null-pointer-with-nested-parent-domain.patch
+drm-xe-call-invalidation_fence_fini-for-pt-inval-fences-in-error-state.patch
+drm-amdkfd-pause-autosuspend-when-creating-pdd.patch
+drm-i915-fix-memory-leak-by-correcting-cache-object-name-in-error-handler.patch
+drm-i915-color-stop-using-non-posted-dsb-writes-for-legacy-lut.patch
+drm-i915-fix-null-pointer-dereference-in-capture_engine.patch
+drm-amdgpu-fix-uvd-contiguous-cs-mapping-problem.patch
+drm-amd-pm-set-smu-v13.0.7-default-workload-type.patch
+drm-amdgpu-fix-when-the-cleaner-shader-is-emitted.patch
+drm-amdkfd-dereference-null-return-value.patch
+drm-amdkfd-hard-code-cacheline-size-for-gfx11.patch
+drm-amdkfd-hard-code-mall-cacheline-size-for-gfx11-gfx12.patch
+xfs-set-xfs_sick_ino_symlink_zapped-explicitly-when-zapping-a-symlink.patch
+xfs-update-btree-keys-correctly-when-_insrec-splits-an-inode-root-block.patch
+xfs-don-t-drop-errno-values-when-we-fail-to-ficlone-the-entire-range.patch
+xfs-return-a-64-bit-block-count-from-xfs_btree_count_blocks.patch
+xfs-fix-null-bno_hint-handling-in-xfs_rtallocate_rtg.patch
--- /dev/null
+From a4faee01179a4d9cbad9ba6be2da8637c68c1438 Mon Sep 17 00:00:00 2001
+From: Xu Yang <xu.yang_2@nxp.com>
+Date: Tue, 26 Nov 2024 11:28:41 +0800
+Subject: usb: dwc3: imx8mp: fix software node kernel dump
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+commit a4faee01179a4d9cbad9ba6be2da8637c68c1438 upstream.
+
+When unbind and bind the device again, kernel will dump below warning:
+
+[ 173.972130] sysfs: cannot create duplicate filename '/devices/platform/soc/4c010010.usb/software_node'
+[ 173.981564] CPU: 2 UID: 0 PID: 536 Comm: sh Not tainted 6.12.0-rc6-06344-g2aed7c4a5c56 #144
+[ 173.989923] Hardware name: NXP i.MX95 15X15 board (DT)
+[ 173.995062] Call trace:
+[ 173.997509] dump_backtrace+0x90/0xe8
+[ 174.001196] show_stack+0x18/0x24
+[ 174.004524] dump_stack_lvl+0x74/0x8c
+[ 174.008198] dump_stack+0x18/0x24
+[ 174.011526] sysfs_warn_dup+0x64/0x80
+[ 174.015201] sysfs_do_create_link_sd+0xf0/0xf8
+[ 174.019656] sysfs_create_link+0x20/0x40
+[ 174.023590] software_node_notify+0x90/0x100
+[ 174.027872] device_create_managed_software_node+0xec/0x108
+...
+
+The '4c010010.usb' device is a platform device created during the initcall
+and is never removed, which causes its associated software node to persist
+indefinitely.
+
+The existing device_create_managed_software_node() does not provide a
+corresponding removal function.
+
+Replace device_create_managed_software_node() with the
+device_add_software_node() and device_remove_software_node() pair to ensure
+proper addition and removal of software nodes, addressing this issue.
+
+Fixes: a9400f1979a0 ("usb: dwc3: imx8mp: add 2 software managed quirk properties for host mode")
+Cc: stable@vger.kernel.org
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20241126032841.2458338-1-xu.yang_2@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/dwc3-imx8mp.c | 30 ++++++++++++++++--------------
+ 1 file changed, 16 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c
+index 356812cbcd88..3edc5aca76f9 100644
+--- a/drivers/usb/dwc3/dwc3-imx8mp.c
++++ b/drivers/usb/dwc3/dwc3-imx8mp.c
+@@ -129,6 +129,16 @@ static void dwc3_imx8mp_wakeup_disable(struct dwc3_imx8mp *dwc3_imx)
+ writel(val, dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
+ }
+
++static const struct property_entry dwc3_imx8mp_properties[] = {
++ PROPERTY_ENTRY_BOOL("xhci-missing-cas-quirk"),
++ PROPERTY_ENTRY_BOOL("xhci-skip-phy-init-quirk"),
++ {},
++};
++
++static const struct software_node dwc3_imx8mp_swnode = {
++ .properties = dwc3_imx8mp_properties,
++};
++
+ static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx)
+ {
+ struct dwc3_imx8mp *dwc3_imx = _dwc3_imx;
+@@ -148,17 +158,6 @@ static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx)
+ return IRQ_HANDLED;
+ }
+
+-static int dwc3_imx8mp_set_software_node(struct device *dev)
+-{
+- struct property_entry props[3] = { 0 };
+- int prop_idx = 0;
+-
+- props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-missing-cas-quirk");
+- props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-skip-phy-init-quirk");
+-
+- return device_create_managed_software_node(dev, props, NULL);
+-}
+-
+ static int dwc3_imx8mp_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -221,17 +220,17 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
+ if (err < 0)
+ goto disable_rpm;
+
+- err = dwc3_imx8mp_set_software_node(dev);
++ err = device_add_software_node(dev, &dwc3_imx8mp_swnode);
+ if (err) {
+ err = -ENODEV;
+- dev_err(dev, "failed to create software node\n");
++ dev_err(dev, "failed to add software node\n");
+ goto disable_rpm;
+ }
+
+ err = of_platform_populate(node, NULL, NULL, dev);
+ if (err) {
+ dev_err(&pdev->dev, "failed to create dwc3 core\n");
+- goto disable_rpm;
++ goto remove_swnode;
+ }
+
+ dwc3_imx->dwc3 = of_find_device_by_node(dwc3_np);
+@@ -255,6 +254,8 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
+
+ depopulate:
+ of_platform_depopulate(dev);
++remove_swnode:
++ device_remove_software_node(dev);
+ disable_rpm:
+ pm_runtime_disable(dev);
+ pm_runtime_put_noidle(dev);
+@@ -268,6 +269,7 @@ static void dwc3_imx8mp_remove(struct platform_device *pdev)
+
+ pm_runtime_get_sync(dev);
+ of_platform_depopulate(dev);
++ device_remove_software_node(dev);
+
+ pm_runtime_disable(dev);
+ pm_runtime_put_noidle(dev);
+--
+2.47.1
+
--- /dev/null
+From a48f744bef9ee74814a9eccb030b02223e48c76c Mon Sep 17 00:00:00 2001
+From: Neal Frager <neal.frager@amd.com>
+Date: Mon, 2 Dec 2024 23:41:51 +0530
+Subject: usb: dwc3: xilinx: make sure pipe clock is deselected in usb2 only mode
+
+From: Neal Frager <neal.frager@amd.com>
+
+commit a48f744bef9ee74814a9eccb030b02223e48c76c upstream.
+
+When the USB3 PHY is not defined in the Linux device tree, there could
+still be a case where there is a USB3 PHY active on the board and enabled
+by the first stage bootloader. If serdes clock is being used then the USB
+will fail to enumerate devices in 2.0 only mode.
+
+To solve this, make sure that the PIPE clock is deselected whenever the
+USB3 PHY is not defined and guarantees that the USB2 only mode will work
+in all cases.
+
+Fixes: 9678f3361afc ("usb: dwc3: xilinx: Skip resets and USB3 register settings for USB2.0 mode")
+Cc: stable@vger.kernel.org
+Signed-off-by: Neal Frager <neal.frager@amd.com>
+Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
+Acked-by: Peter Korsgaard <peter@korsgaard.com>
+Link: https://lore.kernel.org/r/1733163111-1414816-1-git-send-email-radhey.shyam.pandey@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/dwc3-xilinx.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/dwc3-xilinx.c
++++ b/drivers/usb/dwc3/dwc3-xilinx.c
+@@ -121,8 +121,11 @@ static int dwc3_xlnx_init_zynqmp(struct
+ * in use but the usb3-phy entry is missing from the device tree.
+ * Therefore, skip these operations in this case.
+ */
+- if (!priv_data->usb3_phy)
++ if (!priv_data->usb3_phy) {
++ /* Deselect the PIPE Clock Select bit in FPD PIPE Clock register */
++ writel(PIPE_CLK_DESELECT, priv_data->regs + XLNX_USB_FPD_PIPE_CLK);
+ goto skip_usb3_phy;
++ }
+
+ crst = devm_reset_control_get_exclusive(dev, "usb_crst");
+ if (IS_ERR(crst)) {
--- /dev/null
+From 97264eaaba0122a5b7e8ddd7bf4ff3ac57c2b170 Mon Sep 17 00:00:00 2001
+From: Vitalii Mordan <mordan@ispras.ru>
+Date: Thu, 21 Nov 2024 14:47:00 +0300
+Subject: usb: ehci-hcd: fix call balance of clocks handling routines
+
+From: Vitalii Mordan <mordan@ispras.ru>
+
+commit 97264eaaba0122a5b7e8ddd7bf4ff3ac57c2b170 upstream.
+
+If the clocks priv->iclk and priv->fclk were not enabled in ehci_hcd_sh_probe,
+they should not be disabled in any path.
+
+Conversely, if they was enabled in ehci_hcd_sh_probe, they must be disabled
+in all error paths to ensure proper cleanup.
+
+Found by Linux Verification Center (linuxtesting.org) with Klever.
+
+Fixes: 63c845522263 ("usb: ehci-hcd: Add support for SuperH EHCI.")
+Cc: stable@vger.kernel.org # ff30bd6a6618: sh: clk: Fix clk_enable() to return 0 on NULL clk
+Signed-off-by: Vitalii Mordan <mordan@ispras.ru>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20241121114700.2100520-1-mordan@ispras.ru
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/ehci-sh.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/ehci-sh.c
++++ b/drivers/usb/host/ehci-sh.c
+@@ -119,8 +119,12 @@ static int ehci_hcd_sh_probe(struct plat
+ if (IS_ERR(priv->iclk))
+ priv->iclk = NULL;
+
+- clk_enable(priv->fclk);
+- clk_enable(priv->iclk);
++ ret = clk_enable(priv->fclk);
++ if (ret)
++ goto fail_request_resource;
++ ret = clk_enable(priv->iclk);
++ if (ret)
++ goto fail_iclk;
+
+ ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ if (ret != 0) {
+@@ -136,6 +140,7 @@ static int ehci_hcd_sh_probe(struct plat
+
+ fail_add_hcd:
+ clk_disable(priv->iclk);
++fail_iclk:
+ clk_disable(priv->fclk);
+
+ fail_request_resource:
--- /dev/null
+From 82937056967da052cbc04b4435c13db84192dc52 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Wed, 27 Nov 2024 08:02:11 +0100
+Subject: usb: gadget: midi2: Fix interpretation of is_midi1 bits
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 82937056967da052cbc04b4435c13db84192dc52 upstream.
+
+The UMP Function Block info m1.0 field (represented by is_midi1 sysfs
+entry) is an enumeration from 0 to 2, while the midi2 gadget driver
+incorrectly copies it to the corresponding snd_ump_block_info.flags
+bits as-is. This made the wrong bit flags set when m1.0 = 2.
+
+This patch corrects the wrong interpretation of is_midi1 bits.
+
+Fixes: 29ee7a4dddd5 ("usb: gadget: midi2: Add configfs support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/20241127070213.8232-1-tiwai@suse.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_midi2.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/function/f_midi2.c
++++ b/drivers/usb/gadget/function/f_midi2.c
+@@ -1593,7 +1593,11 @@ static int f_midi2_create_card(struct f_
+ fb->info.midi_ci_version = b->midi_ci_version;
+ fb->info.ui_hint = reverse_dir(b->ui_hint);
+ fb->info.sysex8_streams = b->sysex8_streams;
+- fb->info.flags |= b->is_midi1;
++ if (b->is_midi1 < 2)
++ fb->info.flags |= b->is_midi1;
++ else
++ fb->info.flags |= SNDRV_UMP_BLOCK_IS_MIDI1 |
++ SNDRV_UMP_BLOCK_IS_LOWSPEED;
+ strscpy(fb->info.name, ump_fb_name(b),
+ sizeof(fb->info.name));
+ }
--- /dev/null
+From 4cfbca86f6a8b801f3254e0e3c8f2b1d2d64be2b Mon Sep 17 00:00:00 2001
+From: Lianqin Hu <hulianqin@vivo.com>
+Date: Tue, 3 Dec 2024 12:14:16 +0000
+Subject: usb: gadget: u_serial: Fix the issue that gs_start_io crashed due to accessing null pointer
+
+From: Lianqin Hu <hulianqin@vivo.com>
+
+commit 4cfbca86f6a8b801f3254e0e3c8f2b1d2d64be2b upstream.
+
+Considering that in some extreme cases,
+when u_serial driver is accessed by multiple threads,
+Thread A is executing the open operation and calling the gs_open,
+Thread B is executing the disconnect operation and calling the
+gserial_disconnect function,The port->port_usb pointer will be set to NULL.
+
+E.g.
+ Thread A Thread B
+ gs_open() gadget_unbind_driver()
+ gs_start_io() composite_disconnect()
+ gs_start_rx() gserial_disconnect()
+ ... ...
+ spin_unlock(&port->port_lock)
+ status = usb_ep_queue() spin_lock(&port->port_lock)
+ spin_lock(&port->port_lock) port->port_usb = NULL
+ gs_free_requests(port->port_usb->in) spin_unlock(&port->port_lock)
+ Crash
+
+This causes thread A to access a null pointer (port->port_usb is null)
+when calling the gs_free_requests function, causing a crash.
+
+If port_usb is NULL, the release request will be skipped as it
+will be done by gserial_disconnect.
+
+So add a null pointer check to gs_start_io before attempting
+to access the value of the pointer port->port_usb.
+
+Call trace:
+ gs_start_io+0x164/0x25c
+ gs_open+0x108/0x13c
+ tty_open+0x314/0x638
+ chrdev_open+0x1b8/0x258
+ do_dentry_open+0x2c4/0x700
+ vfs_open+0x2c/0x3c
+ path_openat+0xa64/0xc60
+ do_filp_open+0xb8/0x164
+ do_sys_openat2+0x84/0xf0
+ __arm64_sys_openat+0x70/0x9c
+ invoke_syscall+0x58/0x114
+ el0_svc_common+0x80/0xe0
+ do_el0_svc+0x1c/0x28
+ el0_svc+0x38/0x68
+
+Fixes: c1dca562be8a ("usb gadget: split out serial core")
+Cc: stable@vger.kernel.org
+Suggested-by: Prashanth K <quic_prashk@quicinc.com>
+Signed-off-by: Lianqin Hu <hulianqin@vivo.com>
+Acked-by: Prashanth K <quic_prashk@quicinc.com>
+Link: https://lore.kernel.org/r/TYUPR06MB62178DC3473F9E1A537DCD02D2362@TYUPR06MB6217.apcprd06.prod.outlook.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/u_serial.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/gadget/function/u_serial.c
++++ b/drivers/usb/gadget/function/u_serial.c
+@@ -579,9 +579,12 @@ static int gs_start_io(struct gs_port *p
+ * we didn't in gs_start_tx() */
+ tty_wakeup(port->port.tty);
+ } else {
+- gs_free_requests(ep, head, &port->read_allocated);
+- gs_free_requests(port->port_usb->in, &port->write_pool,
+- &port->write_allocated);
++ /* Free reqs only if we are still connected */
++ if (port->port_usb) {
++ gs_free_requests(ep, head, &port->read_allocated);
++ gs_free_requests(port->port_usb->in, &port->write_pool,
++ &port->write_allocated);
++ }
+ status = -EIO;
+ }
+
--- /dev/null
+From 645d56e4cc74e953284809d096532c1955918a28 Mon Sep 17 00:00:00 2001
+From: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+Date: Thu, 21 Nov 2024 11:34:29 +0900
+Subject: usb: typec: anx7411: fix fwnode_handle reference leak
+
+From: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+
+commit 645d56e4cc74e953284809d096532c1955918a28 upstream.
+
+An fwnode_handle and usb_role_switch are obtained with an incremented
+refcount in anx7411_typec_port_probe(), however the refcounts are not
+decremented in the error path. The fwnode_handle is also not decremented
+in the .remove() function. Therefore, call fwnode_handle_put() and
+usb_role_switch_put() accordingly.
+
+Fixes: fe6d8a9c8e64 ("usb: typec: anx7411: Add Analogix PD ANX7411 support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20241121023429.962848-1-joe@pf.is.s.u-tokyo.ac.jp
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/anx7411.c | 47 +++++++++++++++++++++++--------------
+ 1 file changed, 29 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/usb/typec/anx7411.c b/drivers/usb/typec/anx7411.c
+index d1e7c487ddfb..95607efb9f7e 100644
+--- a/drivers/usb/typec/anx7411.c
++++ b/drivers/usb/typec/anx7411.c
+@@ -1021,6 +1021,16 @@ static void anx7411_port_unregister_altmodes(struct typec_altmode **adev)
+ }
+ }
+
++static void anx7411_port_unregister(struct typec_params *typecp)
++{
++ fwnode_handle_put(typecp->caps.fwnode);
++ anx7411_port_unregister_altmodes(typecp->port_amode);
++ if (typecp->port)
++ typec_unregister_port(typecp->port);
++ if (typecp->role_sw)
++ usb_role_switch_put(typecp->role_sw);
++}
++
+ static int anx7411_usb_mux_set(struct typec_mux_dev *mux,
+ struct typec_mux_state *state)
+ {
+@@ -1154,34 +1164,34 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx,
+ ret = fwnode_property_read_string(fwnode, "power-role", &buf);
+ if (ret) {
+ dev_err(dev, "power-role not found: %d\n", ret);
+- return ret;
++ goto put_fwnode;
+ }
+
+ ret = typec_find_port_power_role(buf);
+ if (ret < 0)
+- return ret;
++ goto put_fwnode;
+ cap->type = ret;
+
+ ret = fwnode_property_read_string(fwnode, "data-role", &buf);
+ if (ret) {
+ dev_err(dev, "data-role not found: %d\n", ret);
+- return ret;
++ goto put_fwnode;
+ }
+
+ ret = typec_find_port_data_role(buf);
+ if (ret < 0)
+- return ret;
++ goto put_fwnode;
+ cap->data = ret;
+
+ ret = fwnode_property_read_string(fwnode, "try-power-role", &buf);
+ if (ret) {
+ dev_err(dev, "try-power-role not found: %d\n", ret);
+- return ret;
++ goto put_fwnode;
+ }
+
+ ret = typec_find_power_role(buf);
+ if (ret < 0)
+- return ret;
++ goto put_fwnode;
+ cap->prefer_role = ret;
+
+ /* Get source pdos */
+@@ -1193,7 +1203,7 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx,
+ typecp->src_pdo_nr);
+ if (ret < 0) {
+ dev_err(dev, "source cap validate failed: %d\n", ret);
+- return -EINVAL;
++ goto put_fwnode;
+ }
+
+ typecp->caps_flags |= HAS_SOURCE_CAP;
+@@ -1207,7 +1217,7 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx,
+ typecp->sink_pdo_nr);
+ if (ret < 0) {
+ dev_err(dev, "sink cap validate failed: %d\n", ret);
+- return -EINVAL;
++ goto put_fwnode;
+ }
+
+ for (i = 0; i < typecp->sink_pdo_nr; i++) {
+@@ -1251,13 +1261,21 @@ static int anx7411_typec_port_probe(struct anx7411_data *ctx,
+ ret = PTR_ERR(ctx->typec.port);
+ ctx->typec.port = NULL;
+ dev_err(dev, "Failed to register type c port %d\n", ret);
+- return ret;
++ goto put_usb_role_switch;
+ }
+
+ typec_port_register_altmodes(ctx->typec.port, NULL, ctx,
+ ctx->typec.port_amode,
+ MAX_ALTMODE);
+ return 0;
++
++put_usb_role_switch:
++ if (ctx->typec.role_sw)
++ usb_role_switch_put(ctx->typec.role_sw);
++put_fwnode:
++ fwnode_handle_put(fwnode);
++
++ return ret;
+ }
+
+ static int anx7411_typec_check_connection(struct anx7411_data *ctx)
+@@ -1523,8 +1541,7 @@ free_wq:
+ destroy_workqueue(plat->workqueue);
+
+ free_typec_port:
+- typec_unregister_port(plat->typec.port);
+- anx7411_port_unregister_altmodes(plat->typec.port_amode);
++ anx7411_port_unregister(&plat->typec);
+
+ free_typec_switch:
+ anx7411_unregister_switch(plat);
+@@ -1548,17 +1565,11 @@ static void anx7411_i2c_remove(struct i2c_client *client)
+
+ i2c_unregister_device(plat->spi_client);
+
+- if (plat->typec.role_sw)
+- usb_role_switch_put(plat->typec.role_sw);
+-
+ anx7411_unregister_mux(plat);
+
+ anx7411_unregister_switch(plat);
+
+- if (plat->typec.port)
+- typec_unregister_port(plat->typec.port);
+-
+- anx7411_port_unregister_altmodes(plat->typec.port_amode);
++ anx7411_port_unregister(&plat->typec);
+ }
+
+ static const struct i2c_device_id anx7411_id[] = {
+--
+2.47.1
+
--- /dev/null
+From ef42b906df5c57d0719b69419df9dfd25f25c161 Mon Sep 17 00:00:00 2001
+From: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+Date: Tue, 26 Nov 2024 10:49:09 +0900
+Subject: usb: typec: anx7411: fix OF node reference leaks in anx7411_typec_switch_probe()
+
+From: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+
+commit ef42b906df5c57d0719b69419df9dfd25f25c161 upstream.
+
+The refcounts of the OF nodes obtained by of_get_child_by_name() calls
+in anx7411_typec_switch_probe() are not decremented. Replace them with
+device_get_named_child_node() calls and store the return values to the
+newly created fwnode_handle fields in anx7411_data, and call
+fwnode_handle_put() on them in the error path and in the unregister
+functions.
+
+Fixes: e45d7337dc0e ("usb: typec: anx7411: Use of_get_child_by_name() instead of of_find_node_by_name()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20241126014909.3687917-1-joe@pf.is.s.u-tokyo.ac.jp
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/anx7411.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/typec/anx7411.c
++++ b/drivers/usb/typec/anx7411.c
+@@ -290,6 +290,8 @@ struct anx7411_data {
+ struct power_supply *psy;
+ struct power_supply_desc psy_desc;
+ struct device *dev;
++ struct fwnode_handle *switch_node;
++ struct fwnode_handle *mux_node;
+ };
+
+ static u8 snk_identity[] = {
+@@ -1099,6 +1101,7 @@ static void anx7411_unregister_mux(struc
+ if (ctx->typec.typec_mux) {
+ typec_mux_unregister(ctx->typec.typec_mux);
+ ctx->typec.typec_mux = NULL;
++ fwnode_handle_put(ctx->mux_node);
+ }
+ }
+
+@@ -1107,6 +1110,7 @@ static void anx7411_unregister_switch(st
+ if (ctx->typec.typec_switch) {
+ typec_switch_unregister(ctx->typec.typec_switch);
+ ctx->typec.typec_switch = NULL;
++ fwnode_handle_put(ctx->switch_node);
+ }
+ }
+
+@@ -1114,28 +1118,29 @@ static int anx7411_typec_switch_probe(st
+ struct device *dev)
+ {
+ int ret;
+- struct device_node *node;
+
+- node = of_get_child_by_name(dev->of_node, "orientation_switch");
+- if (!node)
++ ctx->switch_node = device_get_named_child_node(dev, "orientation_switch");
++ if (!ctx->switch_node)
+ return 0;
+
+- ret = anx7411_register_switch(ctx, dev, &node->fwnode);
++ ret = anx7411_register_switch(ctx, dev, ctx->switch_node);
+ if (ret) {
+ dev_err(dev, "failed register switch");
++ fwnode_handle_put(ctx->switch_node);
+ return ret;
+ }
+
+- node = of_get_child_by_name(dev->of_node, "mode_switch");
+- if (!node) {
++ ctx->mux_node = device_get_named_child_node(dev, "mode_switch");
++ if (!ctx->mux_node) {
+ dev_err(dev, "no typec mux exist");
+ ret = -ENODEV;
+ goto unregister_switch;
+ }
+
+- ret = anx7411_register_mux(ctx, dev, &node->fwnode);
++ ret = anx7411_register_mux(ctx, dev, ctx->mux_node);
+ if (ret) {
+ dev_err(dev, "failed register mode switch");
++ fwnode_handle_put(ctx->mux_node);
+ ret = -ENODEV;
+ goto unregister_switch;
+ }
--- /dev/null
+From e37b383df91ba9bde9c6a31bf3ea9072561c5126 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C5=81ukasz=20Bartosik?= <ukaszb@chromium.org>
+Date: Tue, 3 Dec 2024 10:23:18 +0000
+Subject: usb: typec: ucsi: Fix completion notifications
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Łukasz Bartosik <ukaszb@chromium.org>
+
+commit e37b383df91ba9bde9c6a31bf3ea9072561c5126 upstream.
+
+OPM PPM LPM
+ | 1.send cmd | |
+ |-------------------------->| |
+ | |-- |
+ | | | 2.set busy bit in CCI |
+ | |<- |
+ | 3.notify the OPM | |
+ |<--------------------------| |
+ | | 4.send cmd to be executed |
+ | |-------------------------->|
+ | | |
+ | | 5.cmd completed |
+ | |<--------------------------|
+ | | |
+ | |-- |
+ | | | 6.set cmd completed |
+ | |<- bit in CCI |
+ | | |
+ | 7.notify the OPM | |
+ |<--------------------------| |
+ | | |
+ | 8.handle notification | |
+ | from point 3, read CCI | |
+ |<--------------------------| |
+ | | |
+
+When the PPM receives command from the OPM (p.1) it sets the busy bit
+in the CCI (p.2), sends notification to the OPM (p.3) and forwards the
+command to be executed by the LPM (p.4). When the PPM receives command
+completion from the LPM (p.5) it sets command completion bit in the CCI
+(p.6) and sends notification to the OPM (p.7). If command execution by
+the LPM is fast enough then when the OPM starts handling the notification
+from p.3 in p.8 and reads the CCI value it will see command completion bit
+set and will call complete(). Then complete() might be called again when
+the OPM handles notification from p.7.
+
+This fix replaces test_bit() with test_and_clear_bit()
+in ucsi_notify_common() in order to call complete() only
+once per request.
+
+This fix also reinitializes completion variable in
+ucsi_sync_control_common() before a command is sent.
+
+Fixes: 584e8df58942 ("usb: typec: ucsi: extract common code for command handling")
+Cc: stable@vger.kernel.org
+Signed-off-by: Łukasz Bartosik <ukaszb@chromium.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Link: https://lore.kernel.org/r/20241203102318.3386345-1-ukaszb@chromium.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/ucsi/ucsi.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index c435c0835744..7a65a7672e18 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -46,11 +46,11 @@ void ucsi_notify_common(struct ucsi *ucsi, u32 cci)
+ ucsi_connector_change(ucsi, UCSI_CCI_CONNECTOR(cci));
+
+ if (cci & UCSI_CCI_ACK_COMPLETE &&
+- test_bit(ACK_PENDING, &ucsi->flags))
++ test_and_clear_bit(ACK_PENDING, &ucsi->flags))
+ complete(&ucsi->complete);
+
+ if (cci & UCSI_CCI_COMMAND_COMPLETE &&
+- test_bit(COMMAND_PENDING, &ucsi->flags))
++ test_and_clear_bit(COMMAND_PENDING, &ucsi->flags))
+ complete(&ucsi->complete);
+ }
+ EXPORT_SYMBOL_GPL(ucsi_notify_common);
+@@ -65,6 +65,8 @@ int ucsi_sync_control_common(struct ucsi *ucsi, u64 command)
+ else
+ set_bit(COMMAND_PENDING, &ucsi->flags);
+
++ reinit_completion(&ucsi->complete);
++
+ ret = ucsi->ops->async_control(ucsi, command);
+ if (ret)
+ goto out_clear_bit;
+--
+2.47.1
+
--- /dev/null
+From 7ce31f20a0771d71779c3b0ec9cdf474cc3c8e9a Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Mon, 2 Dec 2024 10:57:27 -0800
+Subject: xfs: don't drop errno values when we fail to ficlone the entire range
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit 7ce31f20a0771d71779c3b0ec9cdf474cc3c8e9a upstream.
+
+Way back when we first implemented FICLONE for XFS, life was simple --
+either the the entire remapping completed, or something happened and we
+had to return an errno explaining what happened. Neither of those
+ioctls support returning partial results, so it's all or nothing.
+
+Then things got complicated when copy_file_range came along, because it
+actually can return the number of bytes copied, so commit 3f68c1f562f1e4
+tried to make it so that we could return a partial result if the
+REMAP_FILE_CAN_SHORTEN flag is set. This is also how FIDEDUPERANGE can
+indicate that the kernel performed a partial deduplication.
+
+Unfortunately, the logic is wrong if an error stops the remapping and
+CAN_SHORTEN is not set. Because those callers cannot return partial
+results, it is an error for ->remap_file_range to return a positive
+quantity that is less than the @len passed in. Implementations really
+should be returning a negative errno in this case, because that's what
+btrfs (which introduced FICLONE{,RANGE}) did.
+
+Therefore, ->remap_range implementations cannot silently drop an errno
+that they might have when the number of bytes remapped is less than the
+number of bytes requested and CAN_SHORTEN is not set.
+
+Found by running generic/562 on a 64k fsblock filesystem and wondering
+why it reported corrupt files.
+
+Cc: <stable@vger.kernel.org> # v4.20
+Fixes: 3fc9f5e409319e ("xfs: remove xfs_reflink_remap_range")
+Really-Fixes: 3f68c1f562f1e4 ("xfs: support returning partial reflink results")
+Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_file.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/fs/xfs/xfs_file.c
++++ b/fs/xfs/xfs_file.c
+@@ -1228,6 +1228,14 @@ out_unlock:
+ xfs_iunlock2_remapping(src, dest);
+ if (ret)
+ trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_);
++ /*
++ * If the caller did not set CAN_SHORTEN, then it is not prepared to
++ * handle partial results -- either the whole remap succeeds, or we
++ * must say why it did not. In this case, any error should be returned
++ * to the caller.
++ */
++ if (ret && remapped < len && !(remap_flags & REMAP_FILE_CAN_SHORTEN))
++ return ret;
+ return remapped > 0 ? remapped : ret;
+ }
+
--- /dev/null
+From af9f02457f461b23307fe826a37be61ba6e32c92 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Mon, 2 Dec 2024 10:57:30 -0800
+Subject: xfs: fix null bno_hint handling in xfs_rtallocate_rtg
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit af9f02457f461b23307fe826a37be61ba6e32c92 upstream.
+
+xfs_bmap_rtalloc initializes the bno_hint variable to NULLRTBLOCK (aka
+NULLFSBLOCK). If the allocation request is for a file range that's
+adjacent to an existing mapping, it will then change bno_hint to the
+blkno hint in the bmalloca structure.
+
+In other words, bno_hint is either a rt block number, or it's all 1s.
+Unfortunately, commit ec12f97f1b8a8f didn't take the NULLRTBLOCK state
+into account, which means that it tries to translate that into a
+realtime extent number. We then end up with an obnoxiously high rtx
+number and pointlessly feed that to the near allocator. This often
+fails and falls back to the by-size allocator. Seeing as we had no
+locality hint anyway, this is a waste of time.
+
+Fix the code to detect a lack of bno_hint correctly. This was detected
+by running xfs/009 with metadir enabled and a 28k rt extent size.
+
+Cc: <stable@vger.kernel.org> # v6.12
+Fixes: ec12f97f1b8a8f ("xfs: make the rtalloc start hint a xfs_rtblock_t")
+Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_rtalloc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/xfs/xfs_rtalloc.c
++++ b/fs/xfs/xfs_rtalloc.c
+@@ -1295,7 +1295,7 @@ xfs_rtallocate(
+ * For an allocation to an empty file at offset 0, pick an extent that
+ * will space things out in the rt area.
+ */
+- if (bno_hint)
++ if (bno_hint != NULLFSBLOCK)
+ start = xfs_rtb_to_rtx(args.mp, bno_hint);
+ else if (initial_user_data)
+ start = xfs_rtpick_extent(args.mp, tp, maxlen);
--- /dev/null
+From bd27c7bcdca25ce8067ebb94ded6ac1bd7b47317 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Mon, 2 Dec 2024 10:57:26 -0800
+Subject: xfs: return a 64-bit block count from xfs_btree_count_blocks
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit bd27c7bcdca25ce8067ebb94ded6ac1bd7b47317 upstream.
+
+With the nrext64 feature enabled, it's possible for a data fork to have
+2^48 extent mappings. Even with a 64k fsblock size, that maps out to
+a bmbt containing more than 2^32 blocks. Therefore, this predicate must
+return a u64 count to avoid an integer wraparound that will cause scrub
+to do the wrong thing.
+
+It's unlikely that any such filesystem currently exists, because the
+incore bmbt would consume more than 64GB of kernel memory on its own,
+and so far nobody except me has driven a filesystem that far, judging
+from the lack of complaints.
+
+Cc: <stable@vger.kernel.org> # v5.19
+Fixes: df9ad5cc7a5240 ("xfs: Introduce macros to represent new maximum extent counts for data/attr forks")
+Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/libxfs/xfs_btree.c | 4 ++--
+ fs/xfs/libxfs/xfs_btree.h | 2 +-
+ fs/xfs/libxfs/xfs_ialloc_btree.c | 4 +++-
+ fs/xfs/scrub/agheader.c | 6 +++---
+ fs/xfs/scrub/agheader_repair.c | 6 +++---
+ fs/xfs/scrub/fscounters.c | 2 +-
+ fs/xfs/scrub/ialloc.c | 4 ++--
+ fs/xfs/scrub/refcount.c | 2 +-
+ fs/xfs/xfs_bmap_util.c | 2 +-
+ 9 files changed, 17 insertions(+), 15 deletions(-)
+
+--- a/fs/xfs/libxfs/xfs_btree.c
++++ b/fs/xfs/libxfs/xfs_btree.c
+@@ -5173,7 +5173,7 @@ xfs_btree_count_blocks_helper(
+ int level,
+ void *data)
+ {
+- xfs_extlen_t *blocks = data;
++ xfs_filblks_t *blocks = data;
+ (*blocks)++;
+
+ return 0;
+@@ -5183,7 +5183,7 @@ xfs_btree_count_blocks_helper(
+ int
+ xfs_btree_count_blocks(
+ struct xfs_btree_cur *cur,
+- xfs_extlen_t *blocks)
++ xfs_filblks_t *blocks)
+ {
+ *blocks = 0;
+ return xfs_btree_visit_blocks(cur, xfs_btree_count_blocks_helper,
+--- a/fs/xfs/libxfs/xfs_btree.h
++++ b/fs/xfs/libxfs/xfs_btree.h
+@@ -485,7 +485,7 @@ typedef int (*xfs_btree_visit_blocks_fn)
+ int xfs_btree_visit_blocks(struct xfs_btree_cur *cur,
+ xfs_btree_visit_blocks_fn fn, unsigned int flags, void *data);
+
+-int xfs_btree_count_blocks(struct xfs_btree_cur *cur, xfs_extlen_t *blocks);
++int xfs_btree_count_blocks(struct xfs_btree_cur *cur, xfs_filblks_t *blocks);
+
+ union xfs_btree_rec *xfs_btree_rec_addr(struct xfs_btree_cur *cur, int n,
+ struct xfs_btree_block *block);
+--- a/fs/xfs/libxfs/xfs_ialloc_btree.c
++++ b/fs/xfs/libxfs/xfs_ialloc_btree.c
+@@ -743,6 +743,7 @@ xfs_finobt_count_blocks(
+ {
+ struct xfs_buf *agbp = NULL;
+ struct xfs_btree_cur *cur;
++ xfs_filblks_t blocks;
+ int error;
+
+ error = xfs_ialloc_read_agi(pag, tp, 0, &agbp);
+@@ -750,9 +751,10 @@ xfs_finobt_count_blocks(
+ return error;
+
+ cur = xfs_finobt_init_cursor(pag, tp, agbp);
+- error = xfs_btree_count_blocks(cur, tree_blocks);
++ error = xfs_btree_count_blocks(cur, &blocks);
+ xfs_btree_del_cursor(cur, error);
+ xfs_trans_brelse(tp, agbp);
++ *tree_blocks = blocks;
+
+ return error;
+ }
+--- a/fs/xfs/scrub/agheader.c
++++ b/fs/xfs/scrub/agheader.c
+@@ -434,7 +434,7 @@ xchk_agf_xref_btreeblks(
+ {
+ struct xfs_agf *agf = sc->sa.agf_bp->b_addr;
+ struct xfs_mount *mp = sc->mp;
+- xfs_agblock_t blocks;
++ xfs_filblks_t blocks;
+ xfs_agblock_t btreeblks;
+ int error;
+
+@@ -483,7 +483,7 @@ xchk_agf_xref_refcblks(
+ struct xfs_scrub *sc)
+ {
+ struct xfs_agf *agf = sc->sa.agf_bp->b_addr;
+- xfs_agblock_t blocks;
++ xfs_filblks_t blocks;
+ int error;
+
+ if (!sc->sa.refc_cur)
+@@ -816,7 +816,7 @@ xchk_agi_xref_fiblocks(
+ struct xfs_scrub *sc)
+ {
+ struct xfs_agi *agi = sc->sa.agi_bp->b_addr;
+- xfs_agblock_t blocks;
++ xfs_filblks_t blocks;
+ int error = 0;
+
+ if (!xfs_has_inobtcounts(sc->mp))
+--- a/fs/xfs/scrub/agheader_repair.c
++++ b/fs/xfs/scrub/agheader_repair.c
+@@ -256,7 +256,7 @@ xrep_agf_calc_from_btrees(
+ struct xfs_agf *agf = agf_bp->b_addr;
+ struct xfs_mount *mp = sc->mp;
+ xfs_agblock_t btreeblks;
+- xfs_agblock_t blocks;
++ xfs_filblks_t blocks;
+ int error;
+
+ /* Update the AGF counters from the bnobt. */
+@@ -946,7 +946,7 @@ xrep_agi_calc_from_btrees(
+ if (error)
+ goto err;
+ if (xfs_has_inobtcounts(mp)) {
+- xfs_agblock_t blocks;
++ xfs_filblks_t blocks;
+
+ error = xfs_btree_count_blocks(cur, &blocks);
+ if (error)
+@@ -959,7 +959,7 @@ xrep_agi_calc_from_btrees(
+ agi->agi_freecount = cpu_to_be32(freecount);
+
+ if (xfs_has_finobt(mp) && xfs_has_inobtcounts(mp)) {
+- xfs_agblock_t blocks;
++ xfs_filblks_t blocks;
+
+ cur = xfs_finobt_init_cursor(sc->sa.pag, sc->tp, agi_bp);
+ error = xfs_btree_count_blocks(cur, &blocks);
+--- a/fs/xfs/scrub/fscounters.c
++++ b/fs/xfs/scrub/fscounters.c
+@@ -261,7 +261,7 @@ xchk_fscount_btreeblks(
+ struct xchk_fscounters *fsc,
+ xfs_agnumber_t agno)
+ {
+- xfs_extlen_t blocks;
++ xfs_filblks_t blocks;
+ int error;
+
+ error = xchk_ag_init_existing(sc, agno, &sc->sa);
+--- a/fs/xfs/scrub/ialloc.c
++++ b/fs/xfs/scrub/ialloc.c
+@@ -652,8 +652,8 @@ xchk_iallocbt_xref_rmap_btreeblks(
+ struct xfs_scrub *sc)
+ {
+ xfs_filblks_t blocks;
+- xfs_extlen_t inobt_blocks = 0;
+- xfs_extlen_t finobt_blocks = 0;
++ xfs_filblks_t inobt_blocks = 0;
++ xfs_filblks_t finobt_blocks = 0;
+ int error;
+
+ if (!sc->sa.ino_cur || !sc->sa.rmap_cur ||
+--- a/fs/xfs/scrub/refcount.c
++++ b/fs/xfs/scrub/refcount.c
+@@ -490,7 +490,7 @@ xchk_refcount_xref_rmap(
+ struct xfs_scrub *sc,
+ xfs_filblks_t cow_blocks)
+ {
+- xfs_extlen_t refcbt_blocks = 0;
++ xfs_filblks_t refcbt_blocks = 0;
+ xfs_filblks_t blocks;
+ int error;
+
+--- a/fs/xfs/xfs_bmap_util.c
++++ b/fs/xfs/xfs_bmap_util.c
+@@ -111,7 +111,7 @@ xfs_bmap_count_blocks(
+ struct xfs_mount *mp = ip->i_mount;
+ struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);
+ struct xfs_btree_cur *cur;
+- xfs_extlen_t btblocks = 0;
++ xfs_filblks_t btblocks = 0;
+ int error;
+
+ *nextents = 0;
--- /dev/null
+From 6f4669708a69fd21f0299c2d5c4780a6ce358ab5 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Mon, 2 Dec 2024 10:57:28 -0800
+Subject: xfs: set XFS_SICK_INO_SYMLINK_ZAPPED explicitly when zapping a symlink
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit 6f4669708a69fd21f0299c2d5c4780a6ce358ab5 upstream.
+
+If we need to reset a symlink target to the "durr it's busted" string,
+then we clear the zapped flag as well. However, this should be using
+the provided helper so that we don't set the zapped state on an
+otherwise ok symlink.
+
+Cc: <stable@vger.kernel.org> # v6.10
+Fixes: 2651923d8d8db0 ("xfs: online repair of symbolic links")
+Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/scrub/symlink_repair.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/xfs/scrub/symlink_repair.c b/fs/xfs/scrub/symlink_repair.c
+index d015a86ef460..953ce7be78dc 100644
+--- a/fs/xfs/scrub/symlink_repair.c
++++ b/fs/xfs/scrub/symlink_repair.c
+@@ -36,6 +36,7 @@
+ #include "scrub/tempfile.h"
+ #include "scrub/tempexch.h"
+ #include "scrub/reap.h"
++#include "scrub/health.h"
+
+ /*
+ * Symbolic Link Repair
+@@ -233,7 +234,7 @@ xrep_symlink_salvage(
+ * target zapped flag.
+ */
+ if (buflen == 0) {
+- sc->sick_mask |= XFS_SICK_INO_SYMLINK_ZAPPED;
++ xchk_mark_healthy_if_clean(sc, XFS_SICK_INO_SYMLINK_ZAPPED);
+ sprintf(target_buf, DUMMY_TARGET);
+ }
+
+--
+2.47.1
+
--- /dev/null
+From 6d7b4bc1c3e00b1a25b7a05141a64337b4629337 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Mon, 2 Dec 2024 10:57:31 -0800
+Subject: xfs: update btree keys correctly when _insrec splits an inode root block
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit 6d7b4bc1c3e00b1a25b7a05141a64337b4629337 upstream.
+
+In commit 2c813ad66a72, I partially fixed a bug wherein xfs_btree_insrec
+would erroneously try to update the parent's key for a block that had
+been split if we decided to insert the new record into the new block.
+The solution was to detect this situation and update the in-core key
+value that we pass up to the caller so that the caller will (eventually)
+add the new block to the parent level of the tree with the correct key.
+
+However, I missed a subtlety about the way inode-rooted btrees work. If
+the full block was a maximally sized inode root block, we'll solve that
+fullness by moving the root block's records to a new block, resizing the
+root block, and updating the root to point to the new block. We don't
+pass a pointer to the new block to the caller because that work has
+already been done. The new record will /always/ land in the new block,
+so in this case we need to use xfs_btree_update_keys to update the keys.
+
+This bug can theoretically manifest itself in the very rare case that we
+split a bmbt root block and the new record lands in the very first slot
+of the new block, though I've never managed to trigger it in practice.
+However, it is very easy to reproduce by running generic/522 with the
+realtime rmapbt patchset if rtinherit=1.
+
+Cc: <stable@vger.kernel.org> # v4.8
+Fixes: 2c813ad66a7218 ("xfs: support btrees with overlapping intervals for keys")
+Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/libxfs/xfs_btree.c | 29 +++++++++++++++++++++++------
+ 1 file changed, 23 insertions(+), 6 deletions(-)
+
+--- a/fs/xfs/libxfs/xfs_btree.c
++++ b/fs/xfs/libxfs/xfs_btree.c
+@@ -3569,14 +3569,31 @@ xfs_btree_insrec(
+ xfs_btree_log_block(cur, bp, XFS_BB_NUMRECS);
+
+ /*
+- * If we just inserted into a new tree block, we have to
+- * recalculate nkey here because nkey is out of date.
++ * Update btree keys to reflect the newly added record or keyptr.
++ * There are three cases here to be aware of. Normally, all we have to
++ * do is walk towards the root, updating keys as necessary.
+ *
+- * Otherwise we're just updating an existing block (having shoved
+- * some records into the new tree block), so use the regular key
+- * update mechanism.
++ * If the caller had us target a full block for the insertion, we dealt
++ * with that by calling the _make_block_unfull function. If the
++ * "make unfull" function splits the block, it'll hand us back the key
++ * and pointer of the new block. We haven't yet added the new block to
++ * the next level up, so if we decide to add the new record to the new
++ * block (bp->b_bn != old_bn), we have to update the caller's pointer
++ * so that the caller adds the new block with the correct key.
++ *
++ * However, there is a third possibility-- if the selected block is the
++ * root block of an inode-rooted btree and cannot be expanded further,
++ * the "make unfull" function moves the root block contents to a new
++ * block and updates the root block to point to the new block. In this
++ * case, no block pointer is passed back because the block has already
++ * been added to the btree. In this case, we need to use the regular
++ * key update function, just like the first case. This is critical for
++ * overlapping btrees, because the high key must be updated to reflect
++ * the entire tree, not just the subtree accessible through the first
++ * child of the root (which is now two levels down from the root).
+ */
+- if (bp && xfs_buf_daddr(bp) != old_bn) {
++ if (!xfs_btree_ptr_is_null(cur, &nptr) &&
++ bp && xfs_buf_daddr(bp) != old_bn) {
+ xfs_btree_get_keys(cur, block, lkey);
+ } else if (xfs_btree_needs_key_update(cur, optr)) {
+ error = xfs_btree_update_keys(cur, level);