From: Sasha Levin Date: Sun, 31 Mar 2024 13:26:24 +0000 (-0400) Subject: Fixes for 6.7 X-Git-Tag: v6.7.12~89 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e1be854f105c885b00b80c4964a7ac5057ace03;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.7 Signed-off-by: Sasha Levin --- diff --git a/queue-6.7/drm-amd-display-set-odm_combine_policy-based-on-cont.patch b/queue-6.7/drm-amd-display-set-odm_combine_policy-based-on-cont.patch new file mode 100644 index 00000000000..27322498b22 --- /dev/null +++ b/queue-6.7/drm-amd-display-set-odm_combine_policy-based-on-cont.patch @@ -0,0 +1,161 @@ +From 6af4debf6b17e843bdfa9a46c447cb66d1710ead Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Jan 2024 18:12:15 -0500 +Subject: drm/amd/display: set odm_combine_policy based on context in dcn32 + resource + +From: Wenjing Liu + +[ Upstream commit 0a5fd7811a17af708cefdaab93af86838353002d ] + +[why] +When populating dml pipes, odm combine policy should be assigned based +on the pipe topology of the context passed in. DML pipes could be +repopulated multiple times during single validate bandwidth attempt. We +need to make sure that whenever we repopulate the dml pipes it is always +aligned with the updated context. There is a case where DML pipes get +repopulated during FPO optimization after ODM combine policy is changed. +Since in the current code we reinitlaize ODM combine policy, even though +the current context has ODM combine enabled, we overwrite it despite the +pipes are already split. This causes DML to think that MPC combine is +used so we mistakenly enable MPC combine because we apply pipe split +with ODM combine policy reset. This issue doesn't impact non windowed +MPO with ODM case because the legacy policy has restricted use cases. We +don't encounter the case where both ODM and FPO optimizations are +enabled together. So we decide to leave it as is because it is about to +be replaced anyway. + +Cc: stable@vger.kernel.org # 6.6+ +Reviewed-by: Chaitanya Dhere +Reviewed-by: Alvin Lee +Acked-by: Hamza Mahfooz +Signed-off-by: Wenjing Liu +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../drm/amd/display/dc/dcn32/dcn32_resource.c | 16 ++++++++++++++- + .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 15 ++++++++++---- + drivers/gpu/drm/amd/display/dc/inc/resource.h | 20 ++++++++----------- + 3 files changed, 34 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +index cc468bdcb3de2..f663de1cdcdca 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +@@ -1925,7 +1925,21 @@ int dcn32_populate_dml_pipes_from_context( + dcn32_zero_pipe_dcc_fraction(pipes, pipe_cnt); + DC_FP_END(); + pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch; +- pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal; ++ if (dc->config.enable_windowed_mpo_odm && ++ dc->debug.enable_single_display_2to1_odm_policy) { ++ switch (resource_get_odm_slice_count(pipe)) { ++ case 2: ++ pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1; ++ break; ++ case 4: ++ pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_4to1; ++ break; ++ default: ++ pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal; ++ } ++ } else { ++ pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal; ++ } + pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256; // according to spreadsheet + pipes[pipe_cnt].pipe.src.unbounded_req_mode = false; + pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_19; +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +index 5b6d9643b02dc..b315ca6f1cee8 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +@@ -1265,7 +1265,7 @@ static bool update_pipes_with_split_flags(struct dc *dc, struct dc_state *contex + return updated; + } + +-static bool should_allow_odm_power_optimization(struct dc *dc, ++static bool should_apply_odm_power_optimization(struct dc *dc, + struct dc_state *context, struct vba_vars_st *v, int *split, + bool *merge) + { +@@ -1369,9 +1369,12 @@ static void try_odm_power_optimization_and_revalidate( + { + int i; + unsigned int new_vlevel; ++ unsigned int cur_policy[MAX_PIPES]; + +- for (i = 0; i < pipe_cnt; i++) ++ for (i = 0; i < pipe_cnt; i++) { ++ cur_policy[i] = pipes[i].pipe.dest.odm_combine_policy; + pipes[i].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1; ++ } + + new_vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt); + +@@ -1380,6 +1383,9 @@ static void try_odm_power_optimization_and_revalidate( + memset(merge, 0, MAX_PIPES * sizeof(bool)); + *vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, new_vlevel, split, merge); + context->bw_ctx.dml.vba.VoltageLevel = *vlevel; ++ } else { ++ for (i = 0; i < pipe_cnt; i++) ++ pipes[i].pipe.dest.odm_combine_policy = cur_policy[i]; + } + } + +@@ -1550,7 +1556,7 @@ static void dcn32_full_validate_bw_helper(struct dc *dc, + } + } + +- if (should_allow_odm_power_optimization(dc, context, vba, split, merge)) ++ if (should_apply_odm_power_optimization(dc, context, vba, split, merge)) + try_odm_power_optimization_and_revalidate( + dc, context, pipes, split, merge, vlevel, *pipe_cnt); + +@@ -2178,7 +2184,8 @@ bool dcn32_internal_validate_bw(struct dc *dc, + int i; + + pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate); +- dcn32_update_dml_pipes_odm_policy_based_on_context(dc, context, pipes); ++ if (!dc->config.enable_windowed_mpo_odm) ++ dcn32_update_dml_pipes_odm_policy_based_on_context(dc, context, pipes); + + /* repopulate_pipes = 1 means the pipes were either split or merged. In this case + * we have to re-calculate the DET allocation and run through DML once more to +diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h +index 06ca8bfb91e7d..3d7244393807a 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h +@@ -427,22 +427,18 @@ struct pipe_ctx *resource_get_primary_dpp_pipe(const struct pipe_ctx *dpp_pipe); + int resource_get_mpc_slice_index(const struct pipe_ctx *dpp_pipe); + + /* +- * Get number of MPC "cuts" of the plane associated with the pipe. MPC slice +- * count is equal to MPC splits + 1. For example if a plane is cut 3 times, it +- * will have 4 pieces of slice. +- * return - 0 if pipe is not used for a plane with MPCC combine. otherwise +- * the number of MPC "cuts" for the plane. ++ * Get the number of MPC slices associated with the pipe. ++ * The function returns 0 if the pipe is not associated with an MPC combine ++ * pipe topology. + */ +-int resource_get_mpc_slice_count(const struct pipe_ctx *opp_head); ++int resource_get_mpc_slice_count(const struct pipe_ctx *pipe); + + /* +- * Get number of ODM "cuts" of the timing associated with the pipe. ODM slice +- * count is equal to ODM splits + 1. For example if a timing is cut 3 times, it +- * will have 4 pieces of slice. +- * return - 0 if pipe is not used for ODM combine. otherwise +- * the number of ODM "cuts" for the timing. ++ * Get the number of ODM slices associated with the pipe. ++ * The function returns 0 if the pipe is not associated with an ODM combine ++ * pipe topology. + */ +-int resource_get_odm_slice_count(const struct pipe_ctx *otg_master); ++int resource_get_odm_slice_count(const struct pipe_ctx *pipe); + + /* Get the ODM slice index counting from 0 from left most slice */ + int resource_get_odm_slice_index(const struct pipe_ctx *opp_head); +-- +2.43.0 + diff --git a/queue-6.7/drm-amdgpu-display-address-kdoc-for-is_psr_su-in-fil.patch b/queue-6.7/drm-amdgpu-display-address-kdoc-for-is_psr_su-in-fil.patch new file mode 100644 index 00000000000..5967aa10973 --- /dev/null +++ b/queue-6.7/drm-amdgpu-display-address-kdoc-for-is_psr_su-in-fil.patch @@ -0,0 +1,51 @@ +From 336b347ab3f9209845f0d7aa6fdab8d27702ae8c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 18:25:40 +0530 +Subject: drm/amdgpu/display: Address kdoc for 'is_psr_su' in + 'fill_dc_dirty_rects' + +From: Srinivasan Shanmugam + +[ Upstream commit 3651306ae4c7f3f54caa9feb826a93cc69ccebbf ] + +The is_psr_su parameter is a boolean flag indicating whether the Panel +Self Refresh Selective Update (PSR SU) feature is enabled which is a +power-saving feature that allows only the updated regions of the screen +to be refreshed, reducing the amount of data that needs to be sent to +the display. + +Fixes the below with gcc W=1: +drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:5257: warning: Function parameter or member 'is_psr_su' not described in 'fill_dc_dirty_rects' + +Fixes: d16df040c8da ("drm/amdgpu: make damage clips support configurable") +Cc: stable@vger.kernel.org +Cc: Hamza Mahfooz +Cc: Mario Limonciello +Cc: Rodrigo Siqueira +Cc: Aurabindo Pillai +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 342e41c78fb34..dafe9562a7370 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -5129,6 +5129,10 @@ static inline void fill_dc_dirty_rect(struct drm_plane *plane, + * @new_plane_state: New state of @plane + * @crtc_state: New state of CRTC connected to the @plane + * @flip_addrs: DC flip tracking struct, which also tracts dirty rects ++ * @is_psr_su: Flag indicating whether Panel Self Refresh Selective Update (PSR SU) is enabled. ++ * If PSR SU is enabled and damage clips are available, only the regions of the screen ++ * that have changed will be updated. If PSR SU is not enabled, ++ * or if damage clips are not available, the entire screen will be updated. + * @dirty_regions_changed: dirty regions changed + * + * For PSR SU, DC informs the DMUB uController of dirty rectangle regions +-- +2.43.0 + diff --git a/queue-6.7/drm-amdgpu-make-damage-clips-support-configurable.patch b/queue-6.7/drm-amdgpu-make-damage-clips-support-configurable.patch new file mode 100644 index 00000000000..d066ff4e44d --- /dev/null +++ b/queue-6.7/drm-amdgpu-make-damage-clips-support-configurable.patch @@ -0,0 +1,103 @@ +From 6b7addaf573fcfd3711bcb41fbe33b23597274c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Feb 2024 16:23:29 -0500 +Subject: drm/amdgpu: make damage clips support configurable + +From: Hamza Mahfooz + +[ Upstream commit fc184dbe9fd99ad2dfb197b6fe18768bae1774b1 ] + +We have observed that there are quite a number of PSR-SU panels on the +market that are unable to keep up with what user space throws at them, +resulting in hangs and random black screens. So, make damage clips +support configurable and disable it by default for PSR-SU displays. + +Cc: stable@vger.kernel.org +Reviewed-by: Mario Limonciello +Signed-off-by: Hamza Mahfooz +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 13 +++++++++++++ + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 +++++++ + 3 files changed, 21 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index 31d4b5a2c5e83..13c62a26aa19c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -198,6 +198,7 @@ extern uint amdgpu_dc_debug_mask; + extern uint amdgpu_dc_visual_confirm; + extern uint amdgpu_dm_abm_level; + extern int amdgpu_backlight; ++extern int amdgpu_damage_clips; + extern struct amdgpu_mgpu_info mgpu_info; + extern int amdgpu_ras_enable; + extern uint amdgpu_ras_mask; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index 10c4a8cfa18a0..855ab596323c7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -209,6 +209,7 @@ int amdgpu_umsch_mm; + int amdgpu_seamless = -1; /* auto */ + uint amdgpu_debug_mask; + int amdgpu_agp = -1; /* auto */ ++int amdgpu_damage_clips = -1; /* auto */ + + static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work); + +@@ -857,6 +858,18 @@ int amdgpu_backlight = -1; + MODULE_PARM_DESC(backlight, "Backlight control (0 = pwm, 1 = aux, -1 auto (default))"); + module_param_named(backlight, amdgpu_backlight, bint, 0444); + ++/** ++ * DOC: damageclips (int) ++ * Enable or disable damage clips support. If damage clips support is disabled, ++ * we will force full frame updates, irrespective of what user space sends to ++ * us. ++ * ++ * Defaults to -1 (where it is enabled unless a PSR-SU display is detected). ++ */ ++MODULE_PARM_DESC(damageclips, ++ "Damage clips support (0 = disable, 1 = enable, -1 auto (default))"); ++module_param_named(damageclips, amdgpu_damage_clips, int, 0444); ++ + /** + * DOC: tmz (int) + * Trusted Memory Zone (TMZ) is a method to protect data being written +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index f5dceb4eb99a3..342e41c78fb34 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -5147,6 +5147,7 @@ static void fill_dc_dirty_rects(struct drm_plane *plane, + struct drm_plane_state *new_plane_state, + struct drm_crtc_state *crtc_state, + struct dc_flip_addrs *flip_addrs, ++ bool is_psr_su, + bool *dirty_regions_changed) + { + struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state); +@@ -5171,6 +5172,10 @@ static void fill_dc_dirty_rects(struct drm_plane *plane, + num_clips = drm_plane_get_damage_clips_count(new_plane_state); + clips = drm_plane_get_damage_clips(new_plane_state); + ++ if (num_clips && (!amdgpu_damage_clips || (amdgpu_damage_clips < 0 && ++ is_psr_su))) ++ goto ffu; ++ + if (!dm_crtc_state->mpo_requested) { + if (!num_clips || num_clips > DC_MAX_DIRTY_RECTS) + goto ffu; +@@ -8216,6 +8221,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + fill_dc_dirty_rects(plane, old_plane_state, + new_plane_state, new_crtc_state, + &bundle->flip_addrs[planes_count], ++ acrtc_state->stream->link->psr_settings.psr_version == ++ DC_PSR_VERSION_SU_1, + &dirty_rects_changed); + + /* +-- +2.43.0 + diff --git a/queue-6.7/series b/queue-6.7/series index 11cd1af6a9c..a2ec82fc3f4 100644 --- a/queue-6.7/series +++ b/queue-6.7/series @@ -381,3 +381,7 @@ revert-usb-phy-generic-get-the-vbus-supply.patch usb-cdc-wdm-close-race-between-read-and-workqueue.patch usb-misc-ljca-fix-double-free-in-error-handling-path.patch usb-uas-return-enodev-when-submit-urbs-fail-with-device-not-attached.patch +drm-amd-display-set-odm_combine_policy-based-on-cont.patch +drm-amdgpu-make-damage-clips-support-configurable.patch +drm-amdgpu-display-address-kdoc-for-is_psr_su-in-fil.patch +vfio-pds-make-sure-migration-file-isn-t-accessed-aft.patch diff --git a/queue-6.7/vfio-pds-make-sure-migration-file-isn-t-accessed-aft.patch b/queue-6.7/vfio-pds-make-sure-migration-file-isn-t-accessed-aft.patch new file mode 100644 index 00000000000..031d577cf9a --- /dev/null +++ b/queue-6.7/vfio-pds-make-sure-migration-file-isn-t-accessed-aft.patch @@ -0,0 +1,110 @@ +From 8da00a760f7e25ef222ec07dc9030bb0fe7555b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Mar 2024 10:21:48 -0800 +Subject: vfio/pds: Make sure migration file isn't accessed after reset + +From: Brett Creeley + +[ Upstream commit 457f7308254756b6e4b8fc3876cb770dcf0e7cc7 ] + +It's possible the migration file is accessed after reset when it has +been cleaned up, especially when it's initiated by the device. This is +because the driver doesn't rip out the filep when cleaning up it only +frees the related page structures and sets its local struct +pds_vfio_lm_file pointer to NULL. This can cause a NULL pointer +dereference, which is shown in the example below during a restore after +a device initiated reset: + +BUG: kernel NULL pointer dereference, address: 000000000000000c +PF: supervisor read access in kernel mode +PF: error_code(0x0000) - not-present page +PGD 0 P4D 0 +Oops: 0000 [#1] PREEMPT SMP NOPTI +RIP: 0010:pds_vfio_get_file_page+0x5d/0xf0 [pds_vfio_pci] +[...] +Call Trace: + + pds_vfio_restore_write+0xf6/0x160 [pds_vfio_pci] + vfs_write+0xc9/0x3f0 + ? __fget_light+0xc9/0x110 + ksys_write+0xb5/0xf0 + __x64_sys_write+0x1a/0x20 + do_syscall_64+0x38/0x90 + entry_SYSCALL_64_after_hwframe+0x63/0xcd +[...] + +Add a disabled flag to the driver's struct pds_vfio_lm_file that gets +set during cleanup. Then make sure to check the flag when the migration +file is accessed via its file_operations. By default this flag will be +false as the memory for struct pds_vfio_lm_file is kzalloc'd, which means +the struct pds_vfio_lm_file is enabled and accessible. Also, since the +file_operations and driver's migration file cleanup happen under the +protection of the same pds_vfio_lm_file.lock, using this flag is thread +safe. + +Fixes: 8512ed256334 ("vfio/pds: Always clear the save/restore FDs on reset") +Reviewed-by: Shannon Nelson +Signed-off-by: Brett Creeley +Link: https://lore.kernel.org/r/20240308182149.22036-2-brett.creeley@amd.com +Signed-off-by: Alex Williamson +Signed-off-by: Sasha Levin +--- + drivers/vfio/pci/pds/lm.c | 13 +++++++++++++ + drivers/vfio/pci/pds/lm.h | 1 + + 2 files changed, 14 insertions(+) + +diff --git a/drivers/vfio/pci/pds/lm.c b/drivers/vfio/pci/pds/lm.c +index 79fe2e66bb498..6b94cc0bf45b4 100644 +--- a/drivers/vfio/pci/pds/lm.c ++++ b/drivers/vfio/pci/pds/lm.c +@@ -92,8 +92,10 @@ static void pds_vfio_put_lm_file(struct pds_vfio_lm_file *lm_file) + { + mutex_lock(&lm_file->lock); + ++ lm_file->disabled = true; + lm_file->size = 0; + lm_file->alloc_size = 0; ++ lm_file->filep->f_pos = 0; + + /* Free scatter list of file pages */ + sg_free_table(&lm_file->sg_table); +@@ -183,6 +185,12 @@ static ssize_t pds_vfio_save_read(struct file *filp, char __user *buf, + pos = &filp->f_pos; + + mutex_lock(&lm_file->lock); ++ ++ if (lm_file->disabled) { ++ done = -ENODEV; ++ goto out_unlock; ++ } ++ + if (*pos > lm_file->size) { + done = -EINVAL; + goto out_unlock; +@@ -283,6 +291,11 @@ static ssize_t pds_vfio_restore_write(struct file *filp, const char __user *buf, + + mutex_lock(&lm_file->lock); + ++ if (lm_file->disabled) { ++ done = -ENODEV; ++ goto out_unlock; ++ } ++ + while (len) { + size_t page_offset; + struct page *page; +diff --git a/drivers/vfio/pci/pds/lm.h b/drivers/vfio/pci/pds/lm.h +index 13be893198b74..9511b1afc6a11 100644 +--- a/drivers/vfio/pci/pds/lm.h ++++ b/drivers/vfio/pci/pds/lm.h +@@ -27,6 +27,7 @@ struct pds_vfio_lm_file { + struct scatterlist *last_offset_sg; /* Iterator */ + unsigned int sg_last_entry; + unsigned long last_offset; ++ bool disabled; + }; + + struct pds_vfio_pci_device; +-- +2.43.0 +