From: Daniel Miess daniel.miess@amd.com
[ Upstream commit f2303026a5b6327247ba61152d00199b2d1be294 ]
[Why & How] Enable root clock optimization for PHYSYMCLK and only disable it when it's actively being used
v2: Fix array-index-out-of-bounds in dcn35_calc_blocks_to_gate
Reviewed-by: Roman Li roman.li@amd.com Reviewed-by: Charlene Liu charlene.liu@amd.com Acked-by: Wayne Lin wayne.lin@amd.com Signed-off-by: Daniel Miess daniel.miess@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c | 45 ------------------- .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 32 +++++++++++++ .../amd/display/dc/hwss/dcn35/dcn35_hwseq.h | 2 + .../amd/display/dc/hwss/dcn35/dcn35_init.c | 1 + .../amd/display/dc/hwss/dcn351/dcn351_init.c | 1 + .../display/dc/hwss/hw_sequencer_private.h | 4 ++ 7 files changed, 41 insertions(+), 45 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 3c33c3bcbe2cb..fe0025f2167fa 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -701,6 +701,7 @@ enum pg_hw_pipe_resources { PG_OPTC, PG_DPSTREAM, PG_HDMISTREAM, + PG_PHYSYMCLK, PG_HW_PIPE_RESOURCES_NUM_ELEMENT };
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c index 58dd3c5bbff09..024dcf3057a05 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c @@ -451,32 +451,22 @@ static void dccg35_set_physymclk_root_clock_gating( case 0: REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYA_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); break; case 1: REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYB_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); break; case 2: REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYC_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); break; case 3: REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYD_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); break; case 4: REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYE_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); break; default: BREAK_TO_DEBUGGER(); @@ -499,16 +489,10 @@ static void dccg35_set_physymclk( REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, PHYASYMCLK_EN, 1, PHYASYMCLK_SRC_SEL, clk_src); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYA_REFCLK_ROOT_GATE_DISABLE, 0); } else { REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, PHYASYMCLK_EN, 0, PHYASYMCLK_SRC_SEL, 0); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYA_REFCLK_ROOT_GATE_DISABLE, 1); } break; case 1: @@ -516,16 +500,10 @@ static void dccg35_set_physymclk( REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, PHYBSYMCLK_EN, 1, PHYBSYMCLK_SRC_SEL, clk_src); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYB_REFCLK_ROOT_GATE_DISABLE, 0); } else { REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, PHYBSYMCLK_EN, 0, PHYBSYMCLK_SRC_SEL, 0); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYB_REFCLK_ROOT_GATE_DISABLE, 1); } break; case 2: @@ -533,16 +511,10 @@ static void dccg35_set_physymclk( REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, PHYCSYMCLK_EN, 1, PHYCSYMCLK_SRC_SEL, clk_src); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYC_REFCLK_ROOT_GATE_DISABLE, 0); } else { REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, PHYCSYMCLK_EN, 0, PHYCSYMCLK_SRC_SEL, 0); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYC_REFCLK_ROOT_GATE_DISABLE, 1); } break; case 3: @@ -550,16 +522,10 @@ static void dccg35_set_physymclk( REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, PHYDSYMCLK_EN, 1, PHYDSYMCLK_SRC_SEL, clk_src); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYD_REFCLK_ROOT_GATE_DISABLE, 0); } else { REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, PHYDSYMCLK_EN, 0, PHYDSYMCLK_SRC_SEL, 0); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYD_REFCLK_ROOT_GATE_DISABLE, 1); } break; case 4: @@ -567,16 +533,10 @@ static void dccg35_set_physymclk( REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, PHYESYMCLK_EN, 1, PHYESYMCLK_SRC_SEL, clk_src); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYE_REFCLK_ROOT_GATE_DISABLE, 0); } else { REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, PHYESYMCLK_EN, 0, PHYESYMCLK_SRC_SEL, 0); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYE_REFCLK_ROOT_GATE_DISABLE, 1); } break; default: @@ -714,11 +674,6 @@ void dccg35_init(struct dccg *dccg) dccg35_set_dpstreamclk_root_clock_gating(dccg, otg_inst, false); }
- if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) - for (otg_inst = 0; otg_inst < 5; otg_inst++) - dccg35_set_physymclk_root_clock_gating(dccg, otg_inst, - false); - if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) for (otg_inst = 0; otg_inst < 4; otg_inst++) dccg35_set_dppclk_root_clock_gating(dccg, otg_inst, 0); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c index dcced89c07b38..5f60da72c6f58 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c @@ -506,6 +506,17 @@ void dcn35_dpstream_root_clock_control(struct dce_hwseq *hws, unsigned int dp_hp } }
+void dcn35_physymclk_root_clock_control(struct dce_hwseq *hws, unsigned int phy_inst, bool clock_on) +{ + if (!hws->ctx->dc->debug.root_clock_optimization.bits.physymclk) + return; + + if (hws->ctx->dc->res_pool->dccg->funcs->set_physymclk_root_clock_gating) { + hws->ctx->dc->res_pool->dccg->funcs->set_physymclk_root_clock_gating( + hws->ctx->dc->res_pool->dccg, phy_inst, clock_on); + } +} + void dcn35_dsc_pg_control( struct dce_hwseq *hws, unsigned int dsc_inst, @@ -1041,6 +1052,13 @@ void dcn35_calc_blocks_to_gate(struct dc *dc, struct dc_state *context, if (pipe_ctx->stream_res.hpo_dp_stream_enc) update_state->pg_pipe_res_update[PG_DPSTREAM][pipe_ctx->stream_res.hpo_dp_stream_enc->inst] = false; } + + for (i = 0; i < dc->link_count; i++) { + update_state->pg_pipe_res_update[PG_PHYSYMCLK][dc->links[i]->link_enc_hw_inst] = true; + if (dc->links[i]->type != dc_connection_none) + update_state->pg_pipe_res_update[PG_PHYSYMCLK][dc->links[i]->link_enc_hw_inst] = false; + } + /*domain24 controls all the otg, mpc, opp, as long as one otg is still up, avoid enabling OTG PG*/ for (i = 0; i < dc->res_pool->timing_generator_count; i++) { struct timing_generator *tg = dc->res_pool->timing_generators[i]; @@ -1138,6 +1156,10 @@ void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context, } }
+ for (i = 0; i < dc->link_count; i++) + if (dc->links[i]->type != dc_connection_none) + update_state->pg_pipe_res_update[PG_PHYSYMCLK][dc->links[i]->link_enc_hw_inst] = true; + for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++) { if (context->res_ctx.is_hpo_dp_stream_enc_acquired[i] && dc->res_pool->hpo_dp_stream_enc[i]) { @@ -1288,6 +1310,11 @@ void dcn35_root_clock_control(struct dc *dc, dc->hwseq->funcs.dpstream_root_clock_control(dc->hwseq, i, power_on); }
+ for (i = 0; i < dc->res_pool->dig_link_enc_count; i++) + if (update_state->pg_pipe_res_update[PG_PHYSYMCLK][i]) + if (dc->hwseq->funcs.physymclk_root_clock_control) + dc->hwseq->funcs.physymclk_root_clock_control(dc->hwseq, i, power_on); + } for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) { if (update_state->pg_pipe_res_update[PG_DSC][i]) { @@ -1313,6 +1340,11 @@ void dcn35_root_clock_control(struct dc *dc, dc->hwseq->funcs.dpstream_root_clock_control(dc->hwseq, i, power_on); }
+ for (i = 0; i < dc->res_pool->dig_link_enc_count; i++) + if (update_state->pg_pipe_res_update[PG_PHYSYMCLK][i]) + if (dc->hwseq->funcs.physymclk_root_clock_control) + dc->hwseq->funcs.physymclk_root_clock_control(dc->hwseq, i, power_on); + } }
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h index f0ea7d1511ae6..e27b3609020ff 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h @@ -39,6 +39,8 @@ void dcn35_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst,
void dcn35_dpstream_root_clock_control(struct dce_hwseq *hws, unsigned int dp_hpo_inst, bool clock_on);
+void dcn35_physymclk_root_clock_control(struct dce_hwseq *hws, unsigned int phy_inst, bool clock_on); + void dcn35_enable_power_gating_plane(struct dce_hwseq *hws, bool enable);
void dcn35_set_dmu_fgcg(struct dce_hwseq *hws, bool enable); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c index 199781233fd5f..987e09d9246e4 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c @@ -148,6 +148,7 @@ static const struct hwseq_private_funcs dcn35_private_funcs = { .enable_power_gating_plane = dcn35_enable_power_gating_plane, .dpp_root_clock_control = dcn35_dpp_root_clock_control, .dpstream_root_clock_control = dcn35_dpstream_root_clock_control, + .physymclk_root_clock_control = dcn35_physymclk_root_clock_control, .program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree, .update_odm = dcn35_update_odm, .set_hdr_multiplier = dcn10_set_hdr_multiplier, diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c index a53092cd619b1..2e0d23ae8fee5 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c @@ -147,6 +147,7 @@ static const struct hwseq_private_funcs dcn351_private_funcs = { .enable_power_gating_plane = dcn35_enable_power_gating_plane, .dpp_root_clock_control = dcn35_dpp_root_clock_control, .dpstream_root_clock_control = dcn35_dpstream_root_clock_control, + .physymclk_root_clock_control = dcn35_physymclk_root_clock_control, .program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree, .update_odm = dcn35_update_odm, .set_hdr_multiplier = dcn10_set_hdr_multiplier, diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h index 341219cf41442..9553a7d34c3e9 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h @@ -124,6 +124,10 @@ struct hwseq_private_funcs { struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on); + void (*physymclk_root_clock_control)( + struct dce_hwseq *hws, + unsigned int phy_inst, + bool clock_on); void (*dpp_pg_control)(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on);
From: Alvin Lee alvin.lee2@amd.com
[ Upstream commit 984debc133efa05e62f5aa1a7a1dd8ca0ef041f4 ]
[Description] Assign linear_pitch_alignment so we don't cause a divide by 0 error in VM environments
Reviewed-by: Sohaib Nadeem sohaib.nadeem@amd.com Acked-by: Wayne Lin wayne.lin@amd.com Signed-off-by: Alvin Lee alvin.lee2@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 236876d95185b..da237f718dbdd 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1421,6 +1421,7 @@ struct dc *dc_create(const struct dc_init_data *init_params) return NULL;
if (init_params->dce_environment == DCE_ENV_VIRTUAL_HW) { + dc->caps.linear_pitch_alignment = 64; if (!dc_construct_ctx(dc, init_params)) goto destruct_dc; } else {
From: Tim Huang Tim.Huang@amd.com
[ Upstream commit ebbc2ada5c636a6a63d8316a3408753768f5aa9f ]
Clear overflowed array index read warning by cast operation.
Signed-off-by: Tim Huang Tim.Huang@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 06f0a6534a94f..15c2406564700 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -473,8 +473,9 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf, size_t size, loff_t *pos) { struct amdgpu_ring *ring = file_inode(f)->i_private; - int r, i; uint32_t value, result, early[3]; + loff_t i; + int r;
if (*pos & 3 || size & 3) return -EINVAL;
From: Ma Jun Jun.Ma2@amd.com
[ Upstream commit 579f0c21baec9e7506b6bb3f60f0a9b6d07693b4 ]
Check the return value of smum_send_msg_to_smc, otherwise we might use an uninitialized variable "now"
Signed-off-by: Ma Jun Jun.Ma2@amd.com Reviewed-by: Tim Huang Tim.Huang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c index 02ba68d7c6546..0b181bc8931c8 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c @@ -1036,7 +1036,9 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
switch (type) { case PP_SCLK: - smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &now); + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &now); + if (ret) + return ret;
/* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */ if (now == data->gfx_max_freq_limit/100) @@ -1057,7 +1059,9 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, i == 2 ? "*" : ""); break; case PP_MCLK: - smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &now); + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &now); + if (ret) + return ret;
for (i = 0; i < mclk_table->count; i++) size += sprintf(buf + size, "%d: %uMhz %s\n",
From: Jesse Zhang jesse.zhang@amd.com
[ Upstream commit 17e3bea65cdc453695b2fe4ff26d25d17f5339e9 ]
Check the return of pp_atomfwctrl_get_Voltage_table_v4 as it may fail to initialize max_vid_step V2: change the check condition (Tim Huang)
Signed-off-by: Jesse Zhang Jesse.Zhang@amd.com Reviewed-by: Tim Huang Tim.Huang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c index 9f5bd998c6bff..1a79210a7572c 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -2571,8 +2571,11 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr) } }
- pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_VDDC, + result = pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2, &voltage_table); + PP_ASSERT_WITH_CODE(!result, + "Failed to get voltage table!", + return result); pp_table->MaxVidStep = voltage_table.max_vid_step;
pp_table->GfxDpmVoltageMode =
From: Jesse Zhang jesse.zhang@amd.com
[ Upstream commit c8c19ebf7c0b202a6a2d37a52ca112432723db5f ]
Avoid using the negative values for clk_idex as an index into an array pptable->DpmDescriptor.
V2: fix clk_index return check (Tim Huang)
Signed-off-by: Jesse Zhang Jesse.Zhang@amd.com Reviewed-by: Tim Huang Tim.Huang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index 5a68d365967f7..c06e0d6e30177 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -1219,19 +1219,22 @@ static int navi10_get_current_clk_freq_by_table(struct smu_context *smu, value); }
-static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type) +static int navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type) { PPTable_t *pptable = smu->smu_table.driver_pptable; DpmDescriptor_t *dpm_desc = NULL; - uint32_t clk_index = 0; + int clk_index = 0;
clk_index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_CLK, clk_type); + if (clk_index < 0) + return clk_index; + dpm_desc = &pptable->DpmDescriptor[clk_index];
/* 0 - Fine grained DPM, 1 - Discrete DPM */ - return dpm_desc->SnapToDiscrete == 0; + return dpm_desc->SnapToDiscrete == 0 ? 1 : 0; }
static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_CAP cap) @@ -1287,7 +1290,11 @@ static int navi10_emit_clk_levels(struct smu_context *smu, if (ret) return ret;
- if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) { + ret = navi10_is_support_fine_grained_dpm(smu, clk_type); + if (ret < 0) + return ret; + + if (!ret) { for (i = 0; i < count; i++) { ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value); @@ -1496,7 +1503,11 @@ static int navi10_print_clk_levels(struct smu_context *smu, if (ret) return size;
- if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) { + ret = navi10_is_support_fine_grained_dpm(smu, clk_type); + if (ret < 0) + return ret; + + if (!ret) { for (i = 0; i < count; i++) { ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value); if (ret) @@ -1665,7 +1676,11 @@ static int navi10_force_clk_levels(struct smu_context *smu, case SMU_UCLK: case SMU_FCLK: /* There is only 2 levels for fine grained DPM */ - if (navi10_is_support_fine_grained_dpm(smu, clk_type)) { + ret = navi10_is_support_fine_grained_dpm(smu, clk_type); + if (ret < 0) + return ret; + + if (ret) { soft_max_level = (soft_max_level >= 1 ? 1 : 0); soft_min_level = (soft_min_level >= 1 ? 1 : 0); }
From: Jesse Zhang jesse.zhang@amd.com
[ Upstream commit 12c6967428a099bbba9dfd247bb4322a984fcc0b ]
using index i - 1U may beyond element index for mc_data[] when i = 0.
Signed-off-by: Jesse Zhang Jesse.Zhang@amd.com Reviewed-by: Tim Huang Tim.Huang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c index b1b4c09c34671..b56298d9da98f 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c @@ -73,8 +73,9 @@ static int atomctrl_retrieve_ac_timing( j++; } else if ((table->mc_reg_address[i].uc_pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) { - table->mc_reg_table_entry[num_ranges].mc_data[i] = - table->mc_reg_table_entry[num_ranges].mc_data[i-1]; + if (i) + table->mc_reg_table_entry[num_ranges].mc_data[i] = + table->mc_reg_table_entry[num_ranges].mc_data[i-1]; } } num_ranges++;
From: Tim Huang Tim.Huang@amd.com
[ Upstream commit 0fa4c25db8b791f79bc0d5a0cd58aff9ad85186b ]
Clear warning that field bp is uninitialized when calling amdgpu_virt_ras_add_bps.
Signed-off-by: Tim Huang Tim.Huang@amd.com Reviewed-by: Yang Wang kevinyang.wang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index 54ab51a4ada77..b5fc0e1ad4357 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -395,6 +395,8 @@ static void amdgpu_virt_add_bad_page(struct amdgpu_device *adev, else vram_usage_va = adev->mman.drv_vram_usage_va;
+ memset(&bp, 0, sizeof(bp)); + if (bp_block_size) { bp_cnt = bp_block_size / sizeof(uint64_t); for (bp_idx = 0; bp_idx < bp_cnt; bp_idx++) {
From: Alex Hung alex.hung@amd.com
[ Upstream commit 687fe329f18ab0ab0496b20ed2cb003d4879d931 ]
[WHY & HOW] tg_inst will be a negative if timing_generator_count equals 0, which should be checked before used.
This fixes 2 OVERRUN issues reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 15819416a2f36..693d05a98c6fb 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -3492,7 +3492,7 @@ static bool acquire_otg_master_pipe_for_stream( if (pool->dpps[pipe_idx]) pipe_ctx->plane_res.mpcc_inst = pool->dpps[pipe_idx]->inst;
- if (pipe_idx >= pool->timing_generator_count) { + if (pipe_idx >= pool->timing_generator_count && pool->timing_generator_count != 0) { int tg_inst = pool->timing_generator_count - 1;
pipe_ctx->stream_res.tg = pool->timing_generators[tg_inst];
From: Alex Hung alex.hung@amd.com
[ Upstream commit 2a5626eeb3b5eec7a36886f9556113dd93ec8ed6 ]
[WHY & HOW] GPIO_ID_UNKNOWN (-1) is not a valid value for array index and therefore should be checked in advance.
This fixes 5 OVERRUN issues reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c index 663c17f52779c..d19d5c1770222 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c @@ -239,6 +239,9 @@ static bool is_pin_busy( enum gpio_id id, uint32_t en) { + if (id == GPIO_ID_UNKNOWN) + return false; + return service->busyness[id][en]; }
@@ -247,6 +250,9 @@ static void set_pin_busy( enum gpio_id id, uint32_t en) { + if (id == GPIO_ID_UNKNOWN) + return; + service->busyness[id][en] = true; }
@@ -255,6 +261,9 @@ static void set_pin_free( enum gpio_id id, uint32_t en) { + if (id == GPIO_ID_UNKNOWN) + return; + service->busyness[id][en] = false; }
@@ -263,7 +272,7 @@ enum gpio_result dal_gpio_service_lock( enum gpio_id id, uint32_t en) { - if (!service->busyness[id]) { + if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) { ASSERT_CRITICAL(false); return GPIO_RESULT_OPEN_FAILED; } @@ -277,7 +286,7 @@ enum gpio_result dal_gpio_service_unlock( enum gpio_id id, uint32_t en) { - if (!service->busyness[id]) { + if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) { ASSERT_CRITICAL(false); return GPIO_RESULT_OPEN_FAILED; }
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit 6e41709eb1d9207d88e46026baf9cc850206b374 ]
[WHY] Coverity reports OVERRUN issues within amdgpu_dm interrupt registers. Do not check index value before access array. Do not check NULL pointer.
[HOW] Add index value check for array. Add check for pointer from amdgpu_dm_irq_register_interrupt.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 169 +++++++++++++----- 1 file changed, 128 insertions(+), 41 deletions(-)
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 3cdcadd41be1a..e9aac7f7cfdce 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3561,7 +3561,7 @@ static void handle_hpd_rx_irq(void *param) mutex_unlock(&aconnector->hpd_lock); }
-static void register_hpd_handlers(struct amdgpu_device *adev) +static int register_hpd_handlers(struct amdgpu_device *adev) { struct drm_device *dev = adev_to_drm(adev); struct drm_connector *connector; @@ -3573,11 +3573,17 @@ static void register_hpd_handlers(struct amdgpu_device *adev) int_params.current_polarity = INTERRUPT_POLARITY_DEFAULT;
if (dc_is_dmub_outbox_supported(adev->dm.dc)) { - if (!register_dmub_notify_callback(adev, DMUB_NOTIFICATION_HPD, dmub_hpd_callback, true)) + if (!register_dmub_notify_callback(adev, DMUB_NOTIFICATION_HPD, + dmub_hpd_callback, true)) { DRM_ERROR("amdgpu: fail to register dmub hpd callback"); + return -EINVAL; + }
- if (!register_dmub_notify_callback(adev, DMUB_NOTIFICATION_HPD_IRQ, dmub_hpd_callback, true)) + if (!register_dmub_notify_callback(adev, DMUB_NOTIFICATION_HPD_IRQ, + dmub_hpd_callback, true)) { DRM_ERROR("amdgpu: fail to register dmub hpd callback"); + return -EINVAL; + } }
list_for_each_entry(connector, @@ -3593,9 +3599,16 @@ static void register_hpd_handlers(struct amdgpu_device *adev) int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT; int_params.irq_source = dc_link->irq_source_hpd;
- amdgpu_dm_irq_register_interrupt(adev, &int_params, - handle_hpd_irq, - (void *) aconnector); + if (int_params.irq_source == DC_IRQ_SOURCE_INVALID || + int_params.irq_source < DC_IRQ_SOURCE_HPD1 || + int_params.irq_source > DC_IRQ_SOURCE_HPD6) { + DRM_ERROR("Failed to register hpd irq!\n"); + return -EINVAL; + } + + if (!amdgpu_dm_irq_register_interrupt(adev, &int_params, + handle_hpd_irq, (void *) aconnector)) + return -ENOMEM; }
if (dc_link->irq_source_hpd_rx != DC_IRQ_SOURCE_INVALID) { @@ -3604,11 +3617,19 @@ static void register_hpd_handlers(struct amdgpu_device *adev) int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT; int_params.irq_source = dc_link->irq_source_hpd_rx;
- amdgpu_dm_irq_register_interrupt(adev, &int_params, - handle_hpd_rx_irq, - (void *) aconnector); + if (int_params.irq_source == DC_IRQ_SOURCE_INVALID || + int_params.irq_source < DC_IRQ_SOURCE_HPD1RX || + int_params.irq_source > DC_IRQ_SOURCE_HPD6RX) { + DRM_ERROR("Failed to register hpd rx irq!\n"); + return -EINVAL; + } + + if (!amdgpu_dm_irq_register_interrupt(adev, &int_params, + handle_hpd_rx_irq, (void *) aconnector)) + return -ENOMEM; } } + return 0; }
#if defined(CONFIG_DRM_AMD_DC_SI) @@ -3649,13 +3670,21 @@ static int dce60_register_irq_handlers(struct amdgpu_device *adev) int_params.irq_source = dc_interrupt_to_irq_source(dc, i + 1, 0);
+ if (int_params.irq_source == DC_IRQ_SOURCE_INVALID || + int_params.irq_source < DC_IRQ_SOURCE_VBLANK1 || + int_params.irq_source > DC_IRQ_SOURCE_VBLANK6) { + DRM_ERROR("Failed to register vblank irq!\n"); + return -EINVAL; + } + c_irq_params = &adev->dm.vblank_params[int_params.irq_source - DC_IRQ_SOURCE_VBLANK1];
c_irq_params->adev = adev; c_irq_params->irq_src = int_params.irq_source;
- amdgpu_dm_irq_register_interrupt(adev, &int_params, - dm_crtc_high_irq, c_irq_params); + if (!amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_crtc_high_irq, c_irq_params)) + return -ENOMEM; }
/* Use GRPH_PFLIP interrupt */ @@ -3671,14 +3700,21 @@ static int dce60_register_irq_handlers(struct amdgpu_device *adev) int_params.irq_source = dc_interrupt_to_irq_source(dc, i, 0);
+ if (int_params.irq_source == DC_IRQ_SOURCE_INVALID || + int_params.irq_source < DC_IRQ_SOURCE_PFLIP_FIRST || + int_params.irq_source > DC_IRQ_SOURCE_PFLIP_LAST) { + DRM_ERROR("Failed to register pflip irq!\n"); + return -EINVAL; + } + c_irq_params = &adev->dm.pflip_params[int_params.irq_source - DC_IRQ_SOURCE_PFLIP_FIRST];
c_irq_params->adev = adev; c_irq_params->irq_src = int_params.irq_source;
- amdgpu_dm_irq_register_interrupt(adev, &int_params, - dm_pflip_high_irq, c_irq_params); - + if (!amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_pflip_high_irq, c_irq_params)) + return -ENOMEM; }
/* HPD */ @@ -3689,9 +3725,9 @@ static int dce60_register_irq_handlers(struct amdgpu_device *adev) return r; }
- register_hpd_handlers(adev); + r = register_hpd_handlers(adev);
- return 0; + return r; } #endif
@@ -3735,13 +3771,21 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) int_params.irq_source = dc_interrupt_to_irq_source(dc, i, 0);
+ if (int_params.irq_source == DC_IRQ_SOURCE_INVALID || + int_params.irq_source < DC_IRQ_SOURCE_VBLANK1 || + int_params.irq_source > DC_IRQ_SOURCE_VBLANK6) { + DRM_ERROR("Failed to register vblank irq!\n"); + return -EINVAL; + } + c_irq_params = &adev->dm.vblank_params[int_params.irq_source - DC_IRQ_SOURCE_VBLANK1];
c_irq_params->adev = adev; c_irq_params->irq_src = int_params.irq_source;
- amdgpu_dm_irq_register_interrupt(adev, &int_params, - dm_crtc_high_irq, c_irq_params); + if (!amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_crtc_high_irq, c_irq_params)) + return -ENOMEM; }
/* Use VUPDATE interrupt */ @@ -3756,13 +3800,21 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) int_params.irq_source = dc_interrupt_to_irq_source(dc, i, 0);
+ if (int_params.irq_source == DC_IRQ_SOURCE_INVALID || + int_params.irq_source < DC_IRQ_SOURCE_VUPDATE1 || + int_params.irq_source > DC_IRQ_SOURCE_VUPDATE6) { + DRM_ERROR("Failed to register vupdate irq!\n"); + return -EINVAL; + } + c_irq_params = &adev->dm.vupdate_params[int_params.irq_source - DC_IRQ_SOURCE_VUPDATE1];
c_irq_params->adev = adev; c_irq_params->irq_src = int_params.irq_source;
- amdgpu_dm_irq_register_interrupt(adev, &int_params, - dm_vupdate_high_irq, c_irq_params); + if (!amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_vupdate_high_irq, c_irq_params)) + return -ENOMEM; }
/* Use GRPH_PFLIP interrupt */ @@ -3778,14 +3830,21 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) int_params.irq_source = dc_interrupt_to_irq_source(dc, i, 0);
+ if (int_params.irq_source == DC_IRQ_SOURCE_INVALID || + int_params.irq_source < DC_IRQ_SOURCE_PFLIP_FIRST || + int_params.irq_source > DC_IRQ_SOURCE_PFLIP_LAST) { + DRM_ERROR("Failed to register pflip irq!\n"); + return -EINVAL; + } + c_irq_params = &adev->dm.pflip_params[int_params.irq_source - DC_IRQ_SOURCE_PFLIP_FIRST];
c_irq_params->adev = adev; c_irq_params->irq_src = int_params.irq_source;
- amdgpu_dm_irq_register_interrupt(adev, &int_params, - dm_pflip_high_irq, c_irq_params); - + if (!amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_pflip_high_irq, c_irq_params)) + return -ENOMEM; }
/* HPD */ @@ -3796,9 +3855,9 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) return r; }
- register_hpd_handlers(adev); + r = register_hpd_handlers(adev);
- return 0; + return r; }
/* Register IRQ sources and initialize IRQ callbacks */ @@ -3850,13 +3909,21 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) int_params.irq_source = dc_interrupt_to_irq_source(dc, i, 0);
+ if (int_params.irq_source == DC_IRQ_SOURCE_INVALID || + int_params.irq_source < DC_IRQ_SOURCE_VBLANK1 || + int_params.irq_source > DC_IRQ_SOURCE_VBLANK6) { + DRM_ERROR("Failed to register vblank irq!\n"); + return -EINVAL; + } + c_irq_params = &adev->dm.vblank_params[int_params.irq_source - DC_IRQ_SOURCE_VBLANK1];
c_irq_params->adev = adev; c_irq_params->irq_src = int_params.irq_source;
- amdgpu_dm_irq_register_interrupt( - adev, &int_params, dm_crtc_high_irq, c_irq_params); + if (!amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_crtc_high_irq, c_irq_params)) + return -ENOMEM; }
/* Use otg vertical line interrupt */ @@ -3874,9 +3941,11 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) int_params.irq_source = dc_interrupt_to_irq_source(dc, vrtl_int_srcid[i], 0);
- if (int_params.irq_source == DC_IRQ_SOURCE_INVALID) { - DRM_ERROR("Failed to register vline0 irq %d!\n", vrtl_int_srcid[i]); - break; + if (int_params.irq_source == DC_IRQ_SOURCE_INVALID || + int_params.irq_source < DC_IRQ_SOURCE_DC1_VLINE0 || + int_params.irq_source > DC_IRQ_SOURCE_DC6_VLINE0) { + DRM_ERROR("Failed to register vline0 irq!\n"); + return -EINVAL; }
c_irq_params = &adev->dm.vline0_params[int_params.irq_source @@ -3885,8 +3954,10 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) c_irq_params->adev = adev; c_irq_params->irq_src = int_params.irq_source;
- amdgpu_dm_irq_register_interrupt(adev, &int_params, - dm_dcn_vertical_interrupt0_high_irq, c_irq_params); + if (!amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_dcn_vertical_interrupt0_high_irq, + c_irq_params)) + return -ENOMEM; } #endif
@@ -3909,13 +3980,21 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) int_params.irq_source = dc_interrupt_to_irq_source(dc, i, 0);
+ if (int_params.irq_source == DC_IRQ_SOURCE_INVALID || + int_params.irq_source < DC_IRQ_SOURCE_VUPDATE1 || + int_params.irq_source > DC_IRQ_SOURCE_VUPDATE6) { + DRM_ERROR("Failed to register vupdate irq!\n"); + return -EINVAL; + } + c_irq_params = &adev->dm.vupdate_params[int_params.irq_source - DC_IRQ_SOURCE_VUPDATE1];
c_irq_params->adev = adev; c_irq_params->irq_src = int_params.irq_source;
- amdgpu_dm_irq_register_interrupt(adev, &int_params, - dm_vupdate_high_irq, c_irq_params); + if (!amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_vupdate_high_irq, c_irq_params)) + return -ENOMEM; }
/* Use GRPH_PFLIP interrupt */ @@ -3932,14 +4011,21 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) int_params.irq_source = dc_interrupt_to_irq_source(dc, i, 0);
+ if (int_params.irq_source == DC_IRQ_SOURCE_INVALID || + int_params.irq_source < DC_IRQ_SOURCE_PFLIP_FIRST || + int_params.irq_source > DC_IRQ_SOURCE_PFLIP_LAST) { + DRM_ERROR("Failed to register pflip irq!\n"); + return -EINVAL; + } + c_irq_params = &adev->dm.pflip_params[int_params.irq_source - DC_IRQ_SOURCE_PFLIP_FIRST];
c_irq_params->adev = adev; c_irq_params->irq_src = int_params.irq_source;
- amdgpu_dm_irq_register_interrupt(adev, &int_params, - dm_pflip_high_irq, c_irq_params); - + if (!amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_pflip_high_irq, c_irq_params)) + return -ENOMEM; }
/* HPD */ @@ -3950,9 +4036,9 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) return r; }
- register_hpd_handlers(adev); + r = register_hpd_handlers(adev);
- return 0; + return r; } /* Register Outbox IRQ sources and initialize IRQ callbacks */ static int register_outbox_irq_handlers(struct amdgpu_device *adev) @@ -3983,8 +4069,9 @@ static int register_outbox_irq_handlers(struct amdgpu_device *adev) c_irq_params->adev = adev; c_irq_params->irq_src = int_params.irq_source;
- amdgpu_dm_irq_register_interrupt(adev, &int_params, - dm_dmub_outbox1_low_irq, c_irq_params); + if (!amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_dmub_outbox1_low_irq, c_irq_params)) + return -ENOMEM; }
return 0;
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit 84723eb6068c50610c5c0893980d230d7afa2105 ]
[Why] Coverity reports OVERRUN warning. Should abort amdgpu_dm initialize.
[How] Return failure to amdgpu_dm_init.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
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 e9aac7f7cfdce..9b440b26c6505 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4543,7 +4543,10 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
/* There is one primary plane per CRTC */ primary_planes = dm->dc->caps.max_streams; - ASSERT(primary_planes <= AMDGPU_MAX_PLANES); + if (primary_planes > AMDGPU_MAX_PLANES) { + DRM_ERROR("DM: Plane nums out of 6 planes\n"); + return -EINVAL; + }
/* * Initialize primary planes, implicit planes for legacy IOCTLS.
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit cf8b16857db702ceb8d52f9219a4613363e2b1cf ]
[Why] Coverity report OVERRUN warning. There are only max_links elements within dc->links. link count could up to AMDGPU_DM_MAX_DISPLAY_INDEX 31.
[How] Make sure link count less than max_links.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
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 9b440b26c6505..c893cf8f2d36e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4664,17 +4664,17 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) } }
+ if (link_cnt > MAX_LINKS) { + DRM_ERROR( + "KMS: Cannot support more than %d display indexes\n", + MAX_LINKS); + goto fail; + } + /* loops over all connectors on the board */ for (i = 0; i < link_cnt; i++) { struct dc_link *link = NULL;
- if (i > AMDGPU_DM_MAX_DISPLAY_INDEX) { - DRM_ERROR( - "KMS: Cannot support more than %d display indexes\n", - AMDGPU_DM_MAX_DISPLAY_INDEX); - continue; - } - link = dc_get_link_at_index(dm->dc, i);
if (link->connector_signal == SIGNAL_TYPE_VIRTUAL) {
From: Alex Hung alex.hung@amd.com
[ Upstream commit 3941a3aa4b653b69876d894d08f3fff1cc965267 ]
[WHY] fe_clk_en has size of 5 but sizeof(fe_clk_en) has byte size 20 which is lager than the array size.
[HOW] Divide byte size 20 by its element size.
This fixes 2 OVERRUN issues reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c index 024dcf3057a05..f2379709dd941 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c @@ -895,7 +895,7 @@ static uint8_t dccg35_get_other_enabled_symclk_fe(struct dccg *dccg, uint32_t st /* for DPMST, this backend could be used by multiple front end. only disable the backend if this stream_enc_ins is the last active stream enc connected to this back_end*/ uint8_t i; - for (i = 0; i != link_enc_inst && i < sizeof(fe_clk_en); i++) { + for (i = 0; i != link_enc_inst && i < ARRAY_SIZE(fe_clk_en); i++) { if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst) num_enabled_symclk_fe++; }
From: Alex Hung alex.hung@amd.com
[ Upstream commit 9ba2ea6337b4f159aecb177555a6a81da92d302e ]
aux_rd_interval has size of 7 and should be checked.
This fixes 3 OVERRUN and 1 INTEGER_OVERFLOW issues reported by Coverity.
Reviewed-by: Rodrigo Siqueira rodrigo.siqueira@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/dc/link/protocols/link_dp_training.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index 1818970b8eaf7..b8e704dbe9567 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -914,10 +914,10 @@ static enum dc_status configure_lttpr_mode_non_transparent( /* Driver does not need to train the first hop. Skip DPCD read and clear * AUX_RD_INTERVAL for DPTX-to-DPIA hop. */ - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) + if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && repeater_cnt > 0 && repeater_cnt < MAX_REPEATER_CNT) link->dpcd_caps.lttpr_caps.aux_rd_interval[--repeater_cnt] = 0;
- for (repeater_id = repeater_cnt; repeater_id > 0; repeater_id--) { + for (repeater_id = repeater_cnt; repeater_id > 0 && repeater_id < MAX_REPEATER_CNT; repeater_id--) { aux_interval_address = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 + ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (repeater_id - 1)); core_link_read_dpcd(
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit 5524fa301ba649f8cf00848f91468e0ba7e4f24c ]
[Why & How] ASSERT if return NULL from kcalloc.
Reviewed-by: Alex Hung alex.hung@amd.com Reviewed-by: Rodrigo Siqueira rodrigo.siqueira@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c index a72c898b64fab..584b9295a12af 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c @@ -165,6 +165,7 @@ static void dpcd_extend_address_range( *out_address = new_addr_range.start; *out_size = ADDRESS_RANGE_SIZE(new_addr_range.start, new_addr_range.end); *out_data = kcalloc(*out_size, sizeof(**out_data), GFP_KERNEL); + ASSERT(*out_data); } }
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit 4e70c0f5251c25885c31ee84a31f99a01f7cf50e ]
[Why] Coverity reports OVERRUN warning. Do not check if array index valid.
[How] Check msg_id valid and valid array index.
Reviewed-by: Alex Hung alex.hung@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/amd/display/modules/hdcp/hdcp_ddc.c | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c index 8e9caae7c9559..1b2df97226a3f 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c @@ -156,11 +156,16 @@ static enum mod_hdcp_status read(struct mod_hdcp *hdcp, uint32_t cur_size = 0; uint32_t data_offset = 0;
- if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID) { + if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID || + msg_id >= MOD_HDCP_MESSAGE_ID_MAX) return MOD_HDCP_STATUS_DDC_FAILURE; - }
if (is_dp_hdcp(hdcp)) { + int num_dpcd_addrs = sizeof(hdcp_dpcd_addrs) / + sizeof(hdcp_dpcd_addrs[0]); + if (msg_id >= num_dpcd_addrs) + return MOD_HDCP_STATUS_DDC_FAILURE; + while (buf_len > 0) { cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE); success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle, @@ -175,6 +180,11 @@ static enum mod_hdcp_status read(struct mod_hdcp *hdcp, data_offset += cur_size; } } else { + int num_i2c_offsets = sizeof(hdcp_i2c_offsets) / + sizeof(hdcp_i2c_offsets[0]); + if (msg_id >= num_i2c_offsets) + return MOD_HDCP_STATUS_DDC_FAILURE; + success = hdcp->config.ddc.funcs.read_i2c( hdcp->config.ddc.handle, HDCP_I2C_ADDR, @@ -219,11 +229,16 @@ static enum mod_hdcp_status write(struct mod_hdcp *hdcp, uint32_t cur_size = 0; uint32_t data_offset = 0;
- if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID) { + if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID || + msg_id >= MOD_HDCP_MESSAGE_ID_MAX) return MOD_HDCP_STATUS_DDC_FAILURE; - }
if (is_dp_hdcp(hdcp)) { + int num_dpcd_addrs = sizeof(hdcp_dpcd_addrs) / + sizeof(hdcp_dpcd_addrs[0]); + if (msg_id >= num_dpcd_addrs) + return MOD_HDCP_STATUS_DDC_FAILURE; + while (buf_len > 0) { cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE); success = hdcp->config.ddc.funcs.write_dpcd( @@ -239,6 +254,11 @@ static enum mod_hdcp_status write(struct mod_hdcp *hdcp, data_offset += cur_size; } } else { + int num_i2c_offsets = sizeof(hdcp_i2c_offsets) / + sizeof(hdcp_i2c_offsets[0]); + if (msg_id >= num_i2c_offsets) + return MOD_HDCP_STATUS_DDC_FAILURE; + hdcp->buf[0] = hdcp_i2c_offsets[msg_id]; memmove(&hdcp->buf[1], buf, buf_len); success = hdcp->config.ddc.funcs.write_i2c(
From: Alex Hung alex.hung@amd.com
[ Upstream commit b38a4815f79b87efb196cd5121579fc51e29a7fb ]
[WHY & HOW] num_valid_sets needs to be checked to avoid a negative index when accessing reader_wm_sets[num_valid_sets - 1].
This fixes an OVERRUN issue reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c index 5ef0879f6ad9c..aea4bb46856ef 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c @@ -484,7 +484,8 @@ static void build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_sm ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
/* Modify previous watermark range to cover up to max */ - ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; + if (num_valid_sets > 0) + ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; } num_valid_sets++; }
From: Alex Hung alex.hung@amd.com
[ Upstream commit efabdce3db9f3d306084c8946983f3d895810a6b ]
This prevents accessing to negative index of link_encoders array.
This fixes an OVERRUN issue reported by Coverity.
Reviewed-by: Rodrigo Siqueira rodrigo.siqueira@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/link/link_factory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index cf22b8f28ba6c..2c3f5d6622851 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -390,7 +390,7 @@ static void link_destruct(struct dc_link *link) * the dynamic assignment of link encoders to streams. Virtual links * are not assigned encoder resources on creation. */ - if (link->link_id.id != CONNECTOR_ID_VIRTUAL) { + if (link->link_id.id != CONNECTOR_ID_VIRTUAL && link->eng_id != ENGINE_ID_UNKNOWN) { link->dc->res_pool->link_encoders[link->eng_id - ENGINE_ID_DIGA] = NULL; link->dc->res_pool->dig_link_enc_count--; }
From: Alex Hung alex.hung@amd.com
[ Upstream commit fa71face755e27dc44bc296416ebdf2c67163316 ]
[WHY & HOW] HDCP_MESSAGE_ID_INVALID (-1) is not a valid msg_id nor is it a valid array index, and it needs checking before used.
This fixes 4 OVERRUN issues reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c b/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c index 99e17c164ce7b..1d3e8f0b915b6 100644 --- a/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c +++ b/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c @@ -128,13 +128,21 @@ static bool hdmi_14_process_transaction( const uint8_t hdcp_i2c_addr_link_primary = 0x3a; /* 0x74 >> 1*/ const uint8_t hdcp_i2c_addr_link_secondary = 0x3b; /* 0x76 >> 1*/ struct i2c_command i2c_command; - uint8_t offset = hdcp_i2c_offsets[message_info->msg_id]; + uint8_t offset; struct i2c_payload i2c_payloads[] = { - { true, 0, 1, &offset }, + { true, 0, 1, 0 }, /* actual hdcp payload, will be filled later, zeroed for now*/ { 0 } };
+ if (message_info->msg_id == HDCP_MESSAGE_ID_INVALID) { + DC_LOG_ERROR("%s: Invalid message_info msg_id - %d\n", __func__, message_info->msg_id); + return false; + } + + offset = hdcp_i2c_offsets[message_info->msg_id]; + i2c_payloads[0].data = &offset; + switch (message_info->link) { case HDCP_LINK_SECONDARY: i2c_payloads[0].address = hdcp_i2c_addr_link_secondary; @@ -308,6 +316,11 @@ static bool dp_11_process_transaction( struct dc_link *link, struct hdcp_protection_message *message_info) { + if (message_info->msg_id == HDCP_MESSAGE_ID_INVALID) { + DC_LOG_ERROR("%s: Invalid message_info msg_id - %d\n", __func__, message_info->msg_id); + return false; + } + return dpcd_access_helper( link, message_info->length,
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit 52cbcf980509e6190740dd1e2a1a437e8fb8101b ]
[Why] Coverity reports RESOURCE_LEAK warning. State memory is not released if dm_create_color_properties fail.
[How] Call kfree(state) before return.
Reviewed-by: Alex Hung alex.hung@amd.com Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
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 c893cf8f2d36e..fca6f7d4c28e2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4206,8 +4206,11 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) }
#ifdef AMD_PRIVATE_COLOR - if (amdgpu_dm_create_color_properties(adev)) + if (amdgpu_dm_create_color_properties(adev)) { + dc_state_release(state->context); + kfree(state); return -ENOMEM; + } #endif
r = amdgpu_dm_audio_init(adev);
From: Alex Hung alex.hung@amd.com
[ Upstream commit 8aa2864044b9d13e95fe224f32e808afbf79ecdf ]
[WHY & HOW] dc->links[] has max size of MAX_LINKS and NULL is return when trying to access with out-of-bound index.
This fixes 3 OVERRUN and 1 RESOURCE_LEAK issues reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index c6c35037bdb8b..dfdfe22d9e851 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -37,6 +37,9 @@ #include "dce/dce_i2c.h" struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index) { + if (link_index >= MAX_LINKS) + return NULL; + return dc->links[link_index]; }
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit 871cd9d881fa791d3f82885000713de07041c0ae ]
[Why] Coverity reports NULL_RETURN warning.
[How] Add otg_master NULL check.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 693d05a98c6fb..76a8e90da0d56 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -2279,6 +2279,9 @@ void resource_log_pipe_topology_update(struct dc *dc, struct dc_state *state) state->stream_status[stream_idx].mall_stream_config.paired_stream); otg_master = resource_get_otg_master_for_stream( &state->res_ctx, state->streams[phantom_stream_idx]); + if (!otg_master) + continue; + resource_log_pipe_for_stream(dc, state, otg_master, stream_idx); } }
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit 176abbcc71952e23009a6ed194fd203b99646884 ]
[Why] For substrcation, coverity reports integer overflow warning message when variable type is uint32_t.
[How] Change varaible type to int32_t.
Reviewed-by: Alex Hung alex.hung@amd.com Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/bios/bios_parser.c | 4 ++-- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c index bc16db69a6636..25fe1a1240298 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c @@ -2551,8 +2551,8 @@ static enum bp_result construct_integrated_info(
/* Sort voltage table from low to high*/ if (result == BP_RESULT_OK) { - uint32_t i; - uint32_t j; + int32_t i; + int32_t j;
for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { for (j = i; j > 0; --j) { diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index 9fe0020bcb9c2..c8c8587a059d9 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -2920,8 +2920,11 @@ static enum bp_result construct_integrated_info( struct atom_common_table_header *header; struct atom_data_revision revision;
- uint32_t i; - uint32_t j; + int32_t i; + int32_t j; + + if (!info) + return result;
if (info && DATA_TABLES(integratedsysteminfo)) { header = GET_IMAGE(struct atom_common_table_header,
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit c6077aa66fa230d12f37fef01161ef080d13b726 ]
[Why] For subtraction, coverity reports integer overflow warning message when variable type is uint32_t.
[How] Change variable type to int32_t.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c index d19d5c1770222..f344478e9bd47 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c @@ -56,7 +56,7 @@ struct gpio_service *dal_gpio_service_create( struct dc_context *ctx) { struct gpio_service *service; - uint32_t index_of_id; + int32_t index_of_id;
service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL);
@@ -112,7 +112,7 @@ struct gpio_service *dal_gpio_service_create( return service;
failure_2: - while (index_of_id) { + while (index_of_id > 0) { --index_of_id; kfree(service->busyness[index_of_id]); }
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit 674704a5dabe4a434645fdd11e35437f4e06dfc4 ]
[Why] Coverity reports RESOURCE_LEAK for some implemenations of clock_source_create. Do not release memory of clk_src if contructor fails.
[How] Free clk_src if contructor fails.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c | 1 + .../gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c | 1 + .../gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c | 4 ++-- .../gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 1 + .../gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 1 + 5 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c index 56ee45e12b461..a73d3c6ef4258 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c @@ -1538,6 +1538,7 @@ struct resource_pool *dce83_create_resource_pool( if (dce83_construct(num_virtual_links, dc, pool)) return &pool->base;
+ kfree(pool); BREAK_TO_DEBUGGER(); return NULL; } diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c index d4c3e2754f516..5d1801dce2730 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c @@ -1864,6 +1864,7 @@ static struct clock_source *dcn30_clock_source_create( return &clk_src->base; }
+ kfree(clk_src); BREAK_TO_DEBUGGER(); return NULL; } diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c index ff50f43e4c000..da73e842c55c8 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c @@ -1660,8 +1660,8 @@ static struct clock_source *dcn31_clock_source_create( return &clk_src->base; }
- BREAK_TO_DEBUGGER(); kfree(clk_src); + BREAK_TO_DEBUGGER(); return NULL; }
@@ -1821,8 +1821,8 @@ static struct clock_source *dcn30_clock_source_create( return &clk_src->base; }
- BREAK_TO_DEBUGGER(); kfree(clk_src); + BREAK_TO_DEBUGGER(); return NULL; }
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c index 2df8a742516c8..28c4599076989 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c @@ -1716,6 +1716,7 @@ static struct clock_source *dcn35_clock_source_create( return &clk_src->base; }
+ kfree(clk_src); BREAK_TO_DEBUGGER(); return NULL; } diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c index ddf9560ab7722..b7bd0f36125a4 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c @@ -1696,6 +1696,7 @@ static struct clock_source *dcn35_clock_source_create( return &clk_src->base; }
+ kfree(clk_src); BREAK_TO_DEBUGGER(); return NULL; }
From: Alex Hung alex.hung@amd.com
[ Upstream commit ae13c8a5cff92015b9a3eb7cee65ebc75859487f ]
[WHY & HOW] A read of acrtc_attach->base.state->event was not locked so moving it inside the spinlock.
This fixes a LOCK_EVASION issue reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
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 fca6f7d4c28e2..64fdce551e627 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8698,15 +8698,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->stream_update.vrr_infopacket = &acrtc_state->stream->vrr_infopacket; } - } else if (cursor_update && acrtc_state->active_planes > 0 && - acrtc_attach->base.state->event) { - drm_crtc_vblank_get(pcrtc); - + } else if (cursor_update && acrtc_state->active_planes > 0) { spin_lock_irqsave(&pcrtc->dev->event_lock, flags); - - acrtc_attach->event = acrtc_attach->base.state->event; - acrtc_attach->base.state->event = NULL; - + if (acrtc_attach->base.state->event) { + drm_crtc_vblank_get(pcrtc); + acrtc_attach->event = acrtc_attach->base.state->event; + acrtc_attach->base.state->event = NULL; + } spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags); }
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit 83c0c8361347cf43937348e8ca0a487679c003ae ]
[Why] For addtion (uint8_t) variable + constant 1, coverity generates message below: Truncation due to cast operation on "cur_idx + 1" from 32 to 8 bits.
Then Coverity assume result is 32 bits value be saved into 8 bits variable. When result is used as index to access array, Coverity suspects index invalid.
[How] Change varaible type to uint32_t.
Reviewed-by: Alex Hung alex.hung@amd.com Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index d487dfcd219b0..b26faed3bb206 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -534,7 +534,7 @@ static bool decide_fallback_link_setting_max_bw_policy( struct dc_link_settings *cur, enum link_training_result training_result) { - uint8_t cur_idx = 0, next_idx; + uint32_t cur_idx = 0, next_idx; bool found = false;
if (training_result == LINK_TRAINING_ABORT)
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit a54f7e866cc73a4cb71b8b24bb568ba35c8969df ]
[Why] Coverity reports Memory - illegal accesses.
[How] Skip inactive planes.
Reviewed-by: Alex Hung alex.hung@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index 9a3ded3111952..85453bbb4f9b1 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -1099,8 +1099,13 @@ void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
// Total Available Pipes Support Check for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { - total_pipes += mode_lib->vba.DPPPerPlane[k]; pipe_idx = get_pipe_idx(mode_lib, k); + if (pipe_idx == -1) { + ASSERT(0); + continue; // skip inactive planes + } + total_pipes += mode_lib->vba.DPPPerPlane[k]; + if (mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz > 0.0) mode_lib->vba.DPPCLK[k] = mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz; else
From: Hersen Wu hersenxs.wu@amd.com
[ Upstream commit 188fd1616ec43033cedbe343b6579e9921e2d898 ]
[Why] Coverity reports OVERRUN warning. soc.num_states could be 40. But array range of bw_params->clk_table.entries is 8.
[How] Assert if soc.num_states greater than 8.
Reviewed-by: Alex Hung alex.hung@amd.com Acked-by: Tom Chung chiahsuan.chung@amd.com Signed-off-by: Hersen Wu hersenxs.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c | 10 ++++++++++ drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c | 10 ++++++++++ drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 10 ++++++++++ drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c | 10 ++++++++++ 4 files changed, 40 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c index e2bcd205aa936..8da97a96b1ceb 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c @@ -304,6 +304,16 @@ void dcn302_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_p dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; }
+ /* bw_params->clk_table.entries[MAX_NUM_DPM_LVL]. + * MAX_NUM_DPM_LVL is 8. + * dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES]. + * DC__VOLTAGE_STATES is 40. + */ + if (num_states > MAX_NUM_DPM_LVL) { + ASSERT(0); + return; + } + dcn3_02_soc.num_states = num_states; for (i = 0; i < dcn3_02_soc.num_states; i++) { dcn3_02_soc.clock_limits[i].state = i; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c index 3f02bb806d421..e968870a4b810 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c @@ -310,6 +310,16 @@ void dcn303_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_p dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; }
+ /* bw_params->clk_table.entries[MAX_NUM_DPM_LVL]. + * MAX_NUM_DPM_LVL is 8. + * dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES]. + * DC__VOLTAGE_STATES is 40. + */ + if (num_states > MAX_NUM_DPM_LVL) { + ASSERT(0); + return; + } + dcn3_03_soc.num_states = num_states; for (i = 0; i < dcn3_03_soc.num_states; i++) { dcn3_03_soc.clock_limits[i].state = i; 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 f6fe0a64beacf..ebcf5ece209a4 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 @@ -3232,6 +3232,16 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; }
+ /* bw_params->clk_table.entries[MAX_NUM_DPM_LVL]. + * MAX_NUM_DPM_LVL is 8. + * dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES]. + * DC__VOLTAGE_STATES is 40. + */ + if (num_states > MAX_NUM_DPM_LVL) { + ASSERT(0); + return; + } + dcn3_2_soc.num_states = num_states; for (i = 0; i < dcn3_2_soc.num_states; i++) { dcn3_2_soc.clock_limits[i].state = i; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c index ff4d795c79664..4297402bdab39 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c @@ -803,6 +803,16 @@ void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_p dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; }
+ /* bw_params->clk_table.entries[MAX_NUM_DPM_LVL]. + * MAX_NUM_DPM_LVL is 8. + * dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES]. + * DC__VOLTAGE_STATES is 40. + */ + if (num_states > MAX_NUM_DPM_LVL) { + ASSERT(0); + return; + } + dcn3_21_soc.num_states = num_states; for (i = 0; i < dcn3_21_soc.num_states; i++) { dcn3_21_soc.clock_limits[i].state = i;
From: Asad Kamal asad.kamal@amd.com
[ Upstream commit 6cd2b872643bb29bba01a8ac739138db7bd79007 ]
Validate tbo resource pointer, skip if NULL
Signed-off-by: Asad Kamal asad.kamal@amd.com Reviewed-by: Christian König christian.koenig@amd.com Reviewed-by: Lijo Lazar lijo.lazar@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 33f791d92ddf3..b151effc55dab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5011,7 +5011,8 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev) shadow = vmbo->shadow;
/* No need to recover an evicted BO */ - if (shadow->tbo.resource->mem_type != TTM_PL_TT || + if (!shadow->tbo.resource || + shadow->tbo.resource->mem_type != TTM_PL_TT || shadow->tbo.resource->start == AMDGPU_BO_INVALID_OFFSET || shadow->parent->tbo.resource->mem_type != TTM_PL_VRAM) continue;
From: Ma Jun Jun.Ma2@amd.com
[ Upstream commit be1684930f5262a622d40ce7a6f1423530d87f89 ]
Check the ring type value to fix the out-of-bounds write warning
Signed-off-by: Ma Jun Jun.Ma2@amd.com Suggested-by: Christian König christian.koenig@amd.com Reviewed-by: Tim Huang Tim.Huang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 15c2406564700..ad49cecb20b8b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -352,7 +352,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, ring->max_dw = max_dw; ring->hw_prio = hw_prio;
- if (!ring->no_scheduler) { + if (!ring->no_scheduler && ring->funcs->type < AMDGPU_HW_IP_NUM) { hw_ip = ring->funcs->type; num_sched = &adev->gpu_sched[hw_ip][hw_prio].num_scheds; adev->gpu_sched[hw_ip][hw_prio].sched[(*num_sched)++] =
From: "Lin.Cao" lincao12@amd.com
[ Upstream commit 547033b593063eb85bfdf9b25a5f1b8fd1911be2 ]
In interrupt context, write dbg_ev_file will be run by work queue. It will cause write dbg_ev_file execution after debug_trap_disable, which will cause NULL pointer access. v2: cancel work "debug_event_workarea" before set dbg_ev_file as NULL.
Signed-off-by: Lin.Cao lincao12@amd.com Reviewed-by: Jonathan Kim jonathan.kim@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c index d889e3545120a..6c2f6a26c479c 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c @@ -103,7 +103,8 @@ void debug_event_write_work_handler(struct work_struct *work) struct kfd_process, debug_event_workarea);
- kernel_write(process->dbg_ev_file, &write_data, 1, &pos); + if (process->debug_trap_enabled && process->dbg_ev_file) + kernel_write(process->dbg_ev_file, &write_data, 1, &pos); }
/* update process/device/queue exception status, write to descriptor @@ -645,6 +646,7 @@ int kfd_dbg_trap_disable(struct kfd_process *target) else if (target->runtime_info.runtime_state != DEBUG_RUNTIME_STATE_DISABLED) target->runtime_info.runtime_state = DEBUG_RUNTIME_STATE_ENABLED;
+ cancel_work_sync(&target->debug_event_workarea); fput(target->dbg_ev_file); target->dbg_ev_file = NULL;
From: Ma Jun Jun.Ma2@amd.com
[ Upstream commit d768394fa99467bcf2703bde74ddc96eeb0b71fa ]
Check the fb_channel_number range to avoid the array out-of-bounds read error
Signed-off-by: Ma Jun Jun.Ma2@amd.com Reviewed-by: Tim Huang Tim.Huang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/df_v1_7.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/df_v1_7.c b/drivers/gpu/drm/amd/amdgpu/df_v1_7.c index 5dfab80ffff21..cd298556f7a60 100644 --- a/drivers/gpu/drm/amd/amdgpu/df_v1_7.c +++ b/drivers/gpu/drm/amd/amdgpu/df_v1_7.c @@ -70,6 +70,8 @@ static u32 df_v1_7_get_hbm_channel_number(struct amdgpu_device *adev) int fb_channel_number;
fb_channel_number = adev->df.funcs->get_fb_channel_number(adev); + if (fb_channel_number >= ARRAY_SIZE(df_v1_7_channel_number)) + fb_channel_number = 0;
return df_v1_7_channel_number[fb_channel_number]; }
Hi!
[ Upstream commit d768394fa99467bcf2703bde74ddc96eeb0b71fa ]
Check the fb_channel_number range to avoid the array out-of-bounds read error
We can still have array out-of-bounds, right? As soon as that function returns 0x8000 0000.
drivers/gpu/drm/amd/amdgpu/amdgpu_df.h: u32 (*get_fb_channel_number)(struct amdgpu_device *adev);
int fb_channel_number should really be u32.
Best regards, Pavel
+++ b/drivers/gpu/drm/amd/amdgpu/df_v1_7.c @@ -70,6 +70,8 @@ static u32 df_v1_7_get_hbm_channel_number(struct amdgpu_device *adev) int fb_channel_number; fb_channel_number = adev->df.funcs->get_fb_channel_number(adev);
- if (fb_channel_number >= ARRAY_SIZE(df_v1_7_channel_number))
fb_channel_number = 0;
return df_v1_7_channel_number[fb_channel_number]; }
From: Tim Huang Tim.Huang@amd.com
[ Upstream commit 8944acd0f9db33e17f387fdc75d33bb473d7936f ]
Clear warning that read ucode[] may out-of-bounds.
Signed-off-by: Tim Huang Tim.Huang@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index b8280be6225d9..c3d89088123db 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -213,6 +213,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, struct amdgpu_firmware_info *ucode;
id = fw_type_convert(cgs_device, type); + if (id >= AMDGPU_UCODE_ID_MAXIMUM) + return -EINVAL; + ucode = &adev->firmware.ucode[id]; if (ucode->fw == NULL) return -EINVAL;
From: Tim Huang Tim.Huang@amd.com
[ Upstream commit 51dfc0a4d609fe700750a62f41447f01b8c9ea50 ]
Clear warning that read mc_data[i-1] may out-of-bounds.
Signed-off-by: Tim Huang Tim.Huang@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index 52b12c1718eb0..7dc102f0bc1d3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c @@ -1484,6 +1484,8 @@ int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev, (u32)le32_to_cpu(*((u32 *)reg_data + j)); j++; } else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) { + if (i == 0) + continue; reg_table->mc_reg_table_entry[num_ranges].mc_data[i] = reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1]; }
From: Michael Chen michael.chen@amd.com
[ Upstream commit 10f624ef239bd136cdcc5bbc626157a57b938a31 ]
Currently oem_id is defined as uint8_t[6] and casted to uint64_t* in some use case. This would lead code scanner to complain about access beyond. Re-define it in union to enforce 8-byte size and alignment to avoid potential issue.
Signed-off-by: Michael Chen michael.chen@amd.com Reviewed-by: Felix Kuehling felix.kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_crat.h | 2 -- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 3 +-- drivers/gpu/drm/amd/amdkfd/kfd_topology.h | 5 ++++- 3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.h b/drivers/gpu/drm/amd/amdkfd/kfd_crat.h index 300634b9f6683..a8ca7ecb6d271 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.h @@ -42,8 +42,6 @@ #define CRAT_OEMTABLEID_LENGTH 8 #define CRAT_RESERVED_LENGTH 6
-#define CRAT_OEMID_64BIT_MASK ((1ULL << (CRAT_OEMID_LENGTH * 8)) - 1) - /* Compute Unit flags */ #define COMPUTE_UNIT_CPU (1 << 0) /* Create Virtual CRAT for CPU */ #define COMPUTE_UNIT_GPU (1 << 1) /* Create Virtual CRAT for GPU */ diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index bc9eb847ecfe7..1d271ecc386f0 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -958,8 +958,7 @@ static void kfd_update_system_properties(void) dev = list_last_entry(&topology_device_list, struct kfd_topology_device, list); if (dev) { - sys_props.platform_id = - (*((uint64_t *)dev->oem_id)) & CRAT_OEMID_64BIT_MASK; + sys_props.platform_id = dev->oem_id64; sys_props.platform_oem = *((uint64_t *)dev->oem_table_id); sys_props.platform_rev = dev->oem_revision; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h index 27386ce9a021d..2d1c9d771bef2 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h @@ -154,7 +154,10 @@ struct kfd_topology_device { struct attribute attr_gpuid; struct attribute attr_name; struct attribute attr_props; - uint8_t oem_id[CRAT_OEMID_LENGTH]; + union { + uint8_t oem_id[CRAT_OEMID_LENGTH]; + uint64_t oem_id64; + }; uint8_t oem_table_id[CRAT_OEMTABLEID_LENGTH]; uint32_t oem_revision; };
From: Jeff Johnson quic_jjohnson@quicinc.com
[ Upstream commit bb0b0a6b96e6de854cb1e349e17bd0e8bf421a59 ]
smatch flagged the following issue:
drivers/net/wireless/ath/ath12k/qmi.c:2619 ath12k_qmi_load_file_target_mem() error: uninitialized symbol 'ret'.
The reality is that 'ret' is initialized in every path through ath12k_qmi_load_file_target_mem() except one, the case where the input 'len' is 0, and hence the "while (remaining)" loop is never entered. But to make sure this case is also handled, add an initializer to the declaration of 'ret'.
No functional changes, compile tested only.
Signed-off-by: Jeff Johnson quic_jjohnson@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://msgid.link/20240504-qmi_load_file_target_mem-v1-1-069fc44c45eb@quici... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath12k/qmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c index 5484112859a66..6d1ebbba17d9b 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.c +++ b/drivers/net/wireless/ath/ath12k/qmi.c @@ -2538,7 +2538,7 @@ static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab, struct qmi_wlanfw_bdf_download_resp_msg_v01 resp = {}; struct qmi_txn txn; const u8 *temp = data; - int ret; + int ret = 0; u32 remaining = len;
req = kzalloc(sizeof(*req), GFP_KERNEL);
From: Jeff Johnson quic_jjohnson@quicinc.com
[ Upstream commit 199f149e97dc7be80e5eed4b232529c1d1aa8055 ]
smatch flagged the following issue:
drivers/net/wireless/ath/ath11k/qmi.c:2401 ath11k_qmi_load_file_target_mem() error: uninitialized symbol 'ret'.
The reality is that 'ret' is initialized in every path through ath11k_qmi_load_file_target_mem() except one, the case where the input 'len' is 0, and hence the "while (remaining)" loop is never entered. But to make sure this case is also handled, add an initializer to the declaration of 'ret'.
No functional changes, compile tested only.
Signed-off-by: Jeff Johnson quic_jjohnson@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://msgid.link/20240504-qmi_load_file_target_mem-v1-2-069fc44c45eb@quici... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/qmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index d4a243b64f6c3..aa160e6fe24f1 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -2293,7 +2293,7 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab, struct qmi_txn txn; const u8 *temp = data; void __iomem *bdf_addr = NULL; - int ret; + int ret = 0; u32 remaining = len;
req = kzalloc(sizeof(*req), GFP_KERNEL);
From: Jeff Johnson quic_jjohnson@quicinc.com
[ Upstream commit 3b9344740843d965e9e37fba30620b3b1c0afa4f ]
smatch flagged the following issue:
drivers/net/wireless/ath/ath12k/dp_rx.c:4065 ath12k_dp_rxdma_ring_sel_config_wcn7850() error: uninitialized symbol 'ret'.
In ath12k_dp_rxdma_ring_sel_config_wcn7850() if it were ever the case that ab->hw_params->num_rxdma_per_pdev was 0 then 'ret' would be uninitialized when it is returned. This should never be the case, but to be safe and to quiet smatch, add an initializer to the declaration of 'ret'.
No functional changes, compile tested only.
Signed-off-by: Jeff Johnson quic_jjohnson@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://msgid.link/20240504-ath12k_dp_rxdma_ring_sel_config_wcn7850-ret-v1-2... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath12k/dp_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 75df622f25d85..0f439d9b84fbf 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -4028,7 +4028,7 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) struct ath12k_dp *dp = &ab->dp; struct htt_rx_ring_tlv_filter tlv_filter = {0}; u32 ring_id; - int ret; + int ret = 0; u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; int i;
From: Ma Jun Jun.Ma2@amd.com
[ Upstream commit df0a9bd92fbbd3fcafcb2bce6463c9228a3e6868 ]
Check the input value for CUSTOM profile mode setting on legacy SOCs. Otherwise we may use uninitalized value of input[]
Signed-off-by: Ma Jun Jun.Ma2@amd.com Reviewed-by: Yang Wang kevinyang.wang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c index 1fcd4451001fa..8f851d2b59486 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -5640,7 +5640,7 @@ static int smu7_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint mode = input[size]; switch (mode) { case PP_SMC_POWER_PROFILE_CUSTOM: - if (size < 8 && size != 0) + if (size != 8 && size != 0) return -EINVAL; /* If only CUSTOM is passed in, use the saved values. Check * that we actually have a CUSTOM profile by ensuring that diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c index f9efb0bad8072..827669e01343b 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c @@ -4091,9 +4091,11 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui if (power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); - if (size == 0 && !data->is_custom_profile_set) + + if (size != 10 && size != 0) return -EINVAL; - if (size < 10 && size != 0) + + if (size == 0 && !data->is_custom_profile_set) return -EINVAL;
result = vega20_get_activity_monitor_coeff(hwmgr, @@ -4155,6 +4157,8 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui activity_monitor.Fclk_PD_Data_error_coeff = input[8]; activity_monitor.Fclk_PD_Data_error_rate_coeff = input[9]; break; + default: + return -EINVAL; }
result = vega20_set_activity_monitor_coeff(hwmgr,
From: Ma Jun Jun.Ma2@amd.com
[ Upstream commit adb9de4dd207fb1264ea70b9eacab9f70ee4707a ]
Check the input value for CUSTOM profile mode setting on smu 11, smu13 and smu14. Otherwise we use uninitialized value of input[]
Signed-off-by: Ma Jun Jun.Ma2@amd.com Reviewed-by: Yang Wang kevinyang.wang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 5 +++++ drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 4 ++++ drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 4 ++++ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 5 +++++ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 4 ++++ drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 5 +++++ 6 files changed, 27 insertions(+)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index 6d334a2aff672..623f6052f97ed 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -1416,6 +1416,9 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu,
if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) && (smu->smc_fw_version >= 0x360d00)) { + if (size != 10) + return -EINVAL; + ret = smu_cmn_update_table(smu, SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, @@ -1449,6 +1452,8 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu, activity_monitor.Mem_PD_Data_error_coeff = input[8]; activity_monitor.Mem_PD_Data_error_rate_coeff = input[9]; break; + default: + return -EINVAL; }
ret = smu_cmn_update_table(smu, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index c06e0d6e30177..01039cdd456b0 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -2021,6 +2021,8 @@ static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, u }
if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { + if (size != 10) + return -EINVAL;
ret = smu_cmn_update_table(smu, SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, @@ -2064,6 +2066,8 @@ static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, u activity_monitor.Mem_PD_Data_error_coeff = input[8]; activity_monitor.Mem_PD_Data_error_rate_coeff = input[9]; break; + default: + return -EINVAL; }
ret = smu_cmn_update_table(smu, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index e426f457a017f..d5a21d7836cc6 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -1722,6 +1722,8 @@ static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, long * }
if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { + if (size != 10) + return -EINVAL;
ret = smu_cmn_update_table(smu, SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, @@ -1765,6 +1767,8 @@ static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, long * activity_monitor->Mem_PD_Data_error_coeff = input[8]; activity_monitor->Mem_PD_Data_error_rate_coeff = input[9]; break; + default: + return -EINVAL; }
ret = smu_cmn_update_table(smu, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index 1e09d5f2d82fe..f7e756ca36dcd 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -2495,6 +2495,9 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, }
if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { + if (size != 9) + return -EINVAL; + ret = smu_cmn_update_table(smu, SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, @@ -2526,6 +2529,8 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, activity_monitor->Fclk_PD_Data_error_coeff = input[7]; activity_monitor->Fclk_PD_Data_error_rate_coeff = input[8]; break; + default: + return -EINVAL; }
ret = smu_cmn_update_table(smu, diff --git 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 index e996a0a4d33e1..4f98869e02848 100644 --- 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 @@ -2450,6 +2450,8 @@ static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *inp }
if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { + if (size != 8) + return -EINVAL;
ret = smu_cmn_update_table(smu, SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, @@ -2478,6 +2480,8 @@ static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *inp activity_monitor->Fclk_MinActiveFreq = input[6]; activity_monitor->Fclk_BoosterFreq = input[7]; break; + default: + return -EINVAL; }
ret = smu_cmn_update_table(smu, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c index 90703f4542aba..06b65159f7b4a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c @@ -1364,6 +1364,9 @@ static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu, }
if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { + if (size != 9) + return -EINVAL; + ret = smu_cmn_update_table(smu, SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, @@ -1395,6 +1398,8 @@ static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu, activity_monitor->Fclk_PD_Data_error_coeff = input[7]; activity_monitor->Fclk_PD_Data_error_rate_coeff = input[8]; break; + default: + return -EINVAL; }
ret = smu_cmn_update_table(smu,
From: "David (Ming Qiang) Wu" David.Wu3@amd.com
[ Upstream commit 10fe1a79cd1bff3048e13120e93c02f8ecd05e9d ]
We do not directly enable/disable VCN IRQ in vcn 5.0.0. And we do not handle the IRQ state as well. So the calls to disable IRQ and set state are removed. This effectively gets rid of the warining of "WARN_ON(!amdgpu_irq_enabled(adev, src, type))" in amdgpu_irq_put().
Signed-off-by: David (Ming Qiang) Wu David.Wu3@amd.com Acked-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c | 19 ------------------- 1 file changed, 19 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c index 851975b5ce298..9b87d6a49b398 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c @@ -229,8 +229,6 @@ static int vcn_v5_0_0_hw_fini(void *handle) for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { if (adev->vcn.harvest_config & (1 << i)) continue; - - amdgpu_irq_put(adev, &adev->vcn.inst[i].irq, 0); }
return 0; @@ -1226,22 +1224,6 @@ static int vcn_v5_0_0_set_powergating_state(void *handle, enum amd_powergating_s return ret; }
-/** - * vcn_v5_0_0_set_interrupt_state - set VCN block interrupt state - * - * @adev: amdgpu_device pointer - * @source: interrupt sources - * @type: interrupt types - * @state: interrupt states - * - * Set VCN block interrupt state - */ -static int vcn_v5_0_0_set_interrupt_state(struct amdgpu_device *adev, struct amdgpu_irq_src *source, - unsigned type, enum amdgpu_interrupt_state state) -{ - return 0; -} - /** * vcn_v5_0_0_process_interrupt - process VCN block interrupt * @@ -1287,7 +1269,6 @@ static int vcn_v5_0_0_process_interrupt(struct amdgpu_device *adev, struct amdgp }
static const struct amdgpu_irq_src_funcs vcn_v5_0_0_irq_funcs = { - .set = vcn_v5_0_0_set_interrupt_state, .process = vcn_v5_0_0_process_interrupt, };
From: Jesse Zhang jesse.zhang@amd.com
[ Upstream commit 1a00f2ac82d6bc6689388c7edcd2a4bd82664f3c ]
Checks the partition mode and returns an error for an invalid mode.
Signed-off-by: Jesse Zhang Jesse.Zhang@amd.com Suggested-by: Lijo Lazar lijo.lazar@amd.com Reviewed-by: Lijo Lazar lijo.lazar@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c index d4e2aed2efa33..2c9a0aa41e2d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c +++ b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c @@ -501,6 +501,12 @@ static int aqua_vanjaram_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr,
if (mode == AMDGPU_AUTO_COMPUTE_PARTITION_MODE) { mode = __aqua_vanjaram_get_auto_mode(xcp_mgr); + if (mode == AMDGPU_UNKNOWN_COMPUTE_PARTITION_MODE) { + dev_err(adev->dev, + "Invalid config, no compatible compute partition mode found, available memory partitions: %d", + adev->gmc.num_mem_partitions); + return -EINVAL; + } } else if (!__aqua_vanjaram_is_valid_mode(xcp_mgr, mode)) { dev_err(adev->dev, "Invalid compute partition mode requested, requested: %s, available memory partitions: %d",
From: Jesse Zhang jesse.zhang@amd.com
[ Upstream commit b1f7810b05d1950350ac2e06992982974343e441 ]
check the pointer hive before use.
Signed-off-by: Jesse Zhang Jesse.Zhang@amd.com Reviewed-by: Tim Huang Tim.Huang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index b151effc55dab..0829a264007c3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5726,7 +5726,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, * to put adev in the 1st position. */ INIT_LIST_HEAD(&device_list); - if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) { + if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1) && hive) { list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) { list_add_tail(&tmp_adev->reset_list, &device_list); if (adev->shutdown)
From: Jesse Zhang jesse.zhang@amd.com
[ Upstream commit 1940708ccf5aff76de4e0b399f99267c93a89193 ]
Check the amdgpu_hive_info *hive that maybe is NULL.
Signed-off-by: Jesse Zhang Jesse.Zhang@amd.com Reviewed-by: Tim Huang Tim.Huang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index cef9dd0a012b5..b3df27ce76634 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -1375,6 +1375,9 @@ static void psp_xgmi_reflect_topology_info(struct psp_context *psp, uint8_t dst_num_links = node_info.num_links;
hive = amdgpu_get_xgmi_hive(psp->adev); + if (WARN_ON(!hive)) + return; + list_for_each_entry(mirror_adev, &hive->device_list, gmc.xgmi.head) { struct psp_xgmi_topology_info *mirror_top_info; int j;
From: Jesse Zhang jesse.zhang@amd.com
[ Upstream commit d190b459b2a4304307c3468ed97477b808381011 ]
if ras_manager obj null, don't print NBIO err data
Signed-off-by: Jesse Zhang Jesse.Zhang@amd.com Suggested-by: Tim Huang Tim.Huang@amd.com Reviewed-by: Tim Huang Tim.Huang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c index 19986ff6a48d7..750ce281b97bd 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c @@ -387,7 +387,7 @@ static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device else WREG32_SOC15(NBIO, 0, mmBIF_DOORBELL_INT_CNTL, bif_doorbell_intr_cntl);
- if (!ras->disable_ras_err_cnt_harvest) { + if (ras && !ras->disable_ras_err_cnt_harvest && obj) { /* * clear error status after ras_controller_intr * according to hw team and count ue number
From: Nicholas Susanto nicholas.susanto@amd.com
[ Upstream commit 3aec7a5af4d6248b7462b7d1eb597f06d35f5ee0 ]
[Why]
Missing check for when there is new pipe configuration but both cur_pipe and new_pipe are both populated causing update_state of DSC for that instance not being updated correctly.
This causes some display mode changes to cause underflow since DSCCLK is still gated when the display requires DSC.
[How]
Added another condition in the new pipe addition branch that checks if there is a new pipe configuration and if it is not the same as cur_pipe. cur_pipe does not necessarily have to be NULL to go in this branch.
Reviewed-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Acked-by: Roman Li roman.li@amd.com Signed-off-by: Nicholas Susanto nicholas.susanto@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c index 5f60da72c6f58..68ac4dee79f79 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c @@ -1095,7 +1095,8 @@ void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context, continue;
if ((!cur_pipe->plane_state && new_pipe->plane_state) || - (!cur_pipe->stream && new_pipe->stream)) { + (!cur_pipe->stream && new_pipe->stream) || + (cur_pipe->stream != new_pipe->stream && new_pipe->stream)) { // New pipe addition for (j = 0; j < PG_HW_PIPE_RESOURCES_NUM_ELEMENT; j++) { if (j == PG_HUBP && new_pipe->plane_res.hubp)
From: Tao Zhou tao.zhou1@amd.com
[ Upstream commit 2aadb520bfacec12527effce3566f8df55e5d08e ]
Avoid overflow issue.
Signed-off-by: Tao Zhou tao.zhou1@amd.com Reviewed-by: Yang Wang kevinyang.wang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c | 6 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c index e71768661ca8d..09a34c7258e22 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c @@ -179,7 +179,7 @@ static int __amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr, * Returns the number of bytes read/written; -errno on error. */ static int amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr, - u8 *eeprom_buf, u16 buf_size, bool read) + u8 *eeprom_buf, u32 buf_size, bool read) { const struct i2c_adapter_quirks *quirks = i2c_adap->quirks; u16 limit; @@ -225,7 +225,7 @@ static int amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr,
int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap, u32 eeprom_addr, u8 *eeprom_buf, - u16 bytes) + u32 bytes) { return amdgpu_eeprom_xfer(i2c_adap, eeprom_addr, eeprom_buf, bytes, true); @@ -233,7 +233,7 @@ int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap,
int amdgpu_eeprom_write(struct i2c_adapter *i2c_adap, u32 eeprom_addr, u8 *eeprom_buf, - u16 bytes) + u32 bytes) { return amdgpu_eeprom_xfer(i2c_adap, eeprom_addr, eeprom_buf, bytes, false); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.h index 6935adb2be1f1..8083b8253ef43 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.h @@ -28,10 +28,10 @@
int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap, u32 eeprom_addr, u8 *eeprom_buf, - u16 bytes); + u32 bytes);
int amdgpu_eeprom_write(struct i2c_adapter *i2c_adap, u32 eeprom_addr, u8 *eeprom_buf, - u16 bytes); + u32 bytes);
#endif
From: Matthew Auld matthew.auld@intel.com
[ Upstream commit a0b834c8957a7d2848face008a12382a0ad11ffc ]
Not valid to touch mmio once the device is removed, so make sure we unmap on removal and not just when driver instance goes away. Also set the mmio pointers to NULL to hopefully catch such issues more easily.
Signed-off-by: Matthew Auld matthew.auld@intel.com Cc: Andrzej Hajda andrzej.hajda@intel.com Cc: Rodrigo Vivi rodrigo.vivi@intel.com Reviewed-by: Andrzej Hajda andrzej.hajda@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20240522102143.128069-32-matth... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xe/xe_mmio.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c index 334637511e750..2ebb2f0d6874e 100644 --- a/drivers/gpu/drm/xe/xe_mmio.c +++ b/drivers/gpu/drm/xe/xe_mmio.c @@ -386,13 +386,16 @@ void xe_mmio_probe_tiles(struct xe_device *xe) } }
-static void mmio_fini(struct drm_device *drm, void *arg) +static void mmio_fini(void *arg) { struct xe_device *xe = arg;
pci_iounmap(to_pci_dev(xe->drm.dev), xe->mmio.regs); if (xe->mem.vram.mapping) iounmap(xe->mem.vram.mapping); + + xe->mem.vram.mapping = NULL; + xe->mmio.regs = NULL; }
int xe_mmio_init(struct xe_device *xe) @@ -417,7 +420,7 @@ int xe_mmio_init(struct xe_device *xe) root_tile->mmio.size = SZ_16M; root_tile->mmio.regs = xe->mmio.regs;
- return drmm_add_action_or_reset(&xe->drm, mmio_fini, xe); + return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe); }
u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg)
From: Matthew Auld matthew.auld@intel.com
[ Upstream commit c7117419784f612d59ee565145f722e8b5541fe6 ]
Set our various mmio mappings to NULL. This should make it easier to catch something rogue trying to mess with mmio after device removal. For example, we might unmap everything and then start hitting some mmio address which has already been unmamped by us and then remapped by something else, causing all kinds of carnage.
Signed-off-by: Matthew Auld matthew.auld@intel.com Cc: Andrzej Hajda andrzej.hajda@intel.com Cc: Rodrigo Vivi rodrigo.vivi@intel.com Reviewed-by: Andrzej Hajda andrzej.hajda@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20240522102143.128069-33-matth... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xe/xe_device.c | 4 +++- drivers/gpu/drm/xe/xe_mmio.c | 35 ++++++++++++++++++++++++++++------ drivers/gpu/drm/xe/xe_mmio.h | 2 +- 3 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 5ef9b50a20d01..a1cbdafbff75e 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -551,7 +551,9 @@ int xe_device_probe(struct xe_device *xe) if (err) return err;
- xe_mmio_probe_tiles(xe); + err = xe_mmio_probe_tiles(xe); + if (err) + return err;
xe_ttm_sys_mgr_init(xe);
diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c index 2ebb2f0d6874e..9d8fafdf51453 100644 --- a/drivers/gpu/drm/xe/xe_mmio.c +++ b/drivers/gpu/drm/xe/xe_mmio.c @@ -254,6 +254,21 @@ static int xe_mmio_tile_vram_size(struct xe_tile *tile, u64 *vram_size, return xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); }
+static void vram_fini(void *arg) +{ + struct xe_device *xe = arg; + struct xe_tile *tile; + int id; + + if (xe->mem.vram.mapping) + iounmap(xe->mem.vram.mapping); + + xe->mem.vram.mapping = NULL; + + for_each_tile(tile, xe, id) + tile->mem.vram.mapping = NULL; +} + int xe_mmio_probe_vram(struct xe_device *xe) { struct xe_tile *tile; @@ -330,10 +345,20 @@ int xe_mmio_probe_vram(struct xe_device *xe) drm_info(&xe->drm, "Available VRAM: %pa, %pa\n", &xe->mem.vram.io_start, &available_size);
- return 0; + return devm_add_action_or_reset(xe->drm.dev, vram_fini, xe); }
-void xe_mmio_probe_tiles(struct xe_device *xe) +static void tiles_fini(void *arg) +{ + struct xe_device *xe = arg; + struct xe_tile *tile; + int id; + + for_each_tile(tile, xe, id) + tile->mmio.regs = NULL; +} + +int xe_mmio_probe_tiles(struct xe_device *xe) { size_t tile_mmio_size = SZ_16M, tile_mmio_ext_size = xe->info.tile_mmio_ext_size; u8 id, tile_count = xe->info.tile_count; @@ -384,6 +409,8 @@ void xe_mmio_probe_tiles(struct xe_device *xe) regs += tile_mmio_ext_size; } } + + return devm_add_action_or_reset(xe->drm.dev, tiles_fini, xe); }
static void mmio_fini(void *arg) @@ -391,10 +418,6 @@ static void mmio_fini(void *arg) struct xe_device *xe = arg;
pci_iounmap(to_pci_dev(xe->drm.dev), xe->mmio.regs); - if (xe->mem.vram.mapping) - iounmap(xe->mem.vram.mapping); - - xe->mem.vram.mapping = NULL; xe->mmio.regs = NULL; }
diff --git a/drivers/gpu/drm/xe/xe_mmio.h b/drivers/gpu/drm/xe/xe_mmio.h index a3cd7b3036c73..a929d090bb2f1 100644 --- a/drivers/gpu/drm/xe/xe_mmio.h +++ b/drivers/gpu/drm/xe/xe_mmio.h @@ -21,7 +21,7 @@ struct xe_device; #define LMEM_BAR 2
int xe_mmio_init(struct xe_device *xe); -void xe_mmio_probe_tiles(struct xe_device *xe); +int xe_mmio_probe_tiles(struct xe_device *xe);
u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg); u16 xe_mmio_read16(struct xe_gt *gt, struct xe_reg reg);
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 6ccfc7c49b6d99e3b857afb064e56a004b0a5e03 ]
In practice, iwl_trans_get_rxq_dma_data() will not fail, it only can do that if called with the wrong arguments. But it does have an error value and doesn't initialize the argument when it fails, so don't use the value then.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Miri Korenblit miriam.rachel.korenblit@intel.com Link: https://msgid.link/20240512072733.faf3a1b87589.I77c950173cb914676fbd28483e5e... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/fw/init.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c index 135bd48bfe9fa..d8b083be5b6b5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/init.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2019-2021 Intel Corporation + * Copyright (C) 2019-2021, 2024 Intel Corporation */ #include "iwl-drv.h" #include "runtime.h" @@ -135,7 +135,9 @@ int iwl_configure_rxq(struct iwl_fw_runtime *fwrt) struct iwl_trans_rxq_dma_data data;
cmd->data[i].q_num = i + 1; - iwl_trans_get_rxq_dma_data(fwrt->trans, i + 1, &data); + ret = iwl_trans_get_rxq_dma_data(fwrt->trans, i + 1, &data); + if (ret) + goto out;
cmd->data[i].fr_bd_cb = cpu_to_le64(data.fr_bd_cb); cmd->data[i].urbd_stts_wrptr = @@ -149,6 +151,7 @@ int iwl_configure_rxq(struct iwl_fw_runtime *fwrt)
ret = iwl_trans_send_cmd(fwrt->trans, &hcmd);
+out: kfree(cmd);
if (ret)
From: Rodrigo Vivi rodrigo.vivi@intel.com
[ Upstream commit 46edb0a3eb16cebc2db6f9b6f7c19813d52bfcc9 ]
Current callers of this function are already taking the result to a boolean and using in an if. It might be a problem because current function might return negative error codes on failure, without increasing the reference counter.
In this scenario we could end up with extra 'put' call ending in unbalanced scenarios.
Let's fix it, while aligning with the current xe_pm_get_if_in_use style.
Tested-by: Francois Dugast francois.dugast@intel.com Reviewed-by: Thomas Hellström thomas.hellstrom@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20240522170105.327472-1-rodrig... Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xe/xe_pm.c | 8 ++++---- drivers/gpu/drm/xe/xe_pm.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c index 37fbeda12d3bd..19eb12a91cf56 100644 --- a/drivers/gpu/drm/xe/xe_pm.c +++ b/drivers/gpu/drm/xe/xe_pm.c @@ -505,12 +505,12 @@ int xe_pm_runtime_get_ioctl(struct xe_device *xe) * xe_pm_runtime_get_if_active - Get a runtime_pm reference if device active * @xe: xe device instance * - * Returns: Any number greater than or equal to 0 for success, negative error - * code otherwise. + * Return: True if device is awake (regardless the previous number of references) + * and a new reference was taken, false otherwise. */ -int xe_pm_runtime_get_if_active(struct xe_device *xe) +bool xe_pm_runtime_get_if_active(struct xe_device *xe) { - return pm_runtime_get_if_active(xe->drm.dev); + return pm_runtime_get_if_active(xe->drm.dev) > 0; }
/** diff --git a/drivers/gpu/drm/xe/xe_pm.h b/drivers/gpu/drm/xe/xe_pm.h index 18b0613fe57b9..f694005db2782 100644 --- a/drivers/gpu/drm/xe/xe_pm.h +++ b/drivers/gpu/drm/xe/xe_pm.h @@ -29,7 +29,7 @@ int xe_pm_runtime_resume(struct xe_device *xe); void xe_pm_runtime_get(struct xe_device *xe); int xe_pm_runtime_get_ioctl(struct xe_device *xe); void xe_pm_runtime_put(struct xe_device *xe); -int xe_pm_runtime_get_if_active(struct xe_device *xe); +bool xe_pm_runtime_get_if_active(struct xe_device *xe); bool xe_pm_runtime_get_if_in_use(struct xe_device *xe); void xe_pm_runtime_get_noresume(struct xe_device *xe); bool xe_pm_runtime_resume_and_get(struct xe_device *xe);
From: Jagadeesh Kona quic_jkona@quicinc.com
[ Upstream commit 074cffb5020ddcaa5fafcc55655e5da6ebe8c831 ]
Conversion of target_freq to HZ in scmi_cpufreq_fast_switch() can lead to overflow if the multiplied result is greater than UINT_MAX, since type of target_freq is unsigned int. Avoid this overflow by assigning target_freq to unsigned long variable for converting it to HZ.
Signed-off-by: Jagadeesh Kona quic_jkona@quicinc.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/scmi-cpufreq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c index 3b4f6bfb2f4cf..b87fd127aa433 100644 --- a/drivers/cpufreq/scmi-cpufreq.c +++ b/drivers/cpufreq/scmi-cpufreq.c @@ -63,9 +63,9 @@ static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy, unsigned int target_freq) { struct scmi_data *priv = policy->driver_data; + unsigned long freq = target_freq;
- if (!perf_ops->freq_set(ph, priv->domain_id, - target_freq * 1000, true)) + if (!perf_ops->freq_set(ph, priv->domain_id, freq * 1000, true)) return target_freq;
return 0;
From: yunshui jiangyunshui@kylinos.cn
[ Upstream commit d9cbd8343b010016fcaabc361c37720dcafddcbe ]
syzbot/KCSAN reported that races happen when multiple CPUs updating dev->stats.tx_error concurrently. Adopt SMP safe DEV_STATS_INC() to update the dev->stats fields.
Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: yunshui jiangyunshui@kylinos.cn Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20240523033520.4029314-1-jiangyunshui@kylinos.cn Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/filter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c index 9933851c685e7..ed8b582c21b97 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -2279,12 +2279,12 @@ static int __bpf_redirect_neigh_v6(struct sk_buff *skb, struct net_device *dev,
err = bpf_out_neigh_v6(net, skb, dev, nh); if (unlikely(net_xmit_eval(err))) - dev->stats.tx_errors++; + DEV_STATS_INC(dev, tx_errors); else ret = NET_XMIT_SUCCESS; goto out_xmit; out_drop: - dev->stats.tx_errors++; + DEV_STATS_INC(dev, tx_errors); kfree_skb(skb); out_xmit: return ret; @@ -2385,12 +2385,12 @@ static int __bpf_redirect_neigh_v4(struct sk_buff *skb, struct net_device *dev,
err = bpf_out_neigh_v4(net, skb, dev, nh); if (unlikely(net_xmit_eval(err))) - dev->stats.tx_errors++; + DEV_STATS_INC(dev, tx_errors); else ret = NET_XMIT_SUCCESS; goto out_xmit; out_drop: - dev->stats.tx_errors++; + DEV_STATS_INC(dev, tx_errors); kfree_skb(skb); out_xmit: return ret;
From: Aleksandr Mishin amishin@t-argos.ru
[ Upstream commit a9927c2cac6e9831361e43a14d91277818154e6a ]
If IORESOURCE_BUS is not provided in Device Tree it will be fabricated in of_pci_parse_bus_range(), so NULL pointer dereference should not happen here.
But that's hard to verify, so check for NULL anyway.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Link: https://lore.kernel.org/linux-pci/20240503125705.46055-1-amishin@t-argos.ru Suggested-by: Bjorn Helgaas helgaas@kernel.org Signed-off-by: Aleksandr Mishin amishin@t-argos.ru Signed-off-by: Krzysztof Wilczyński kwilczynski@kernel.org [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-al.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c index 6dfdda59f3283..643115f74092d 100644 --- a/drivers/pci/controller/dwc/pcie-al.c +++ b/drivers/pci/controller/dwc/pcie-al.c @@ -242,18 +242,24 @@ static struct pci_ops al_child_pci_ops = { .write = pci_generic_config_write, };
-static void al_pcie_config_prepare(struct al_pcie *pcie) +static int al_pcie_config_prepare(struct al_pcie *pcie) { struct al_pcie_target_bus_cfg *target_bus_cfg; struct dw_pcie_rp *pp = &pcie->pci->pp; unsigned int ecam_bus_mask; + struct resource_entry *ft; u32 cfg_control_offset; + struct resource *bus; u8 subordinate_bus; u8 secondary_bus; u32 cfg_control; u32 reg; - struct resource *bus = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS)->res;
+ ft = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS); + if (!ft) + return -ENODEV; + + bus = ft->res; target_bus_cfg = &pcie->target_bus_cfg;
ecam_bus_mask = (pcie->ecam_size >> PCIE_ECAM_BUS_SHIFT) - 1; @@ -287,6 +293,8 @@ static void al_pcie_config_prepare(struct al_pcie *pcie) FIELD_PREP(CFG_CONTROL_SEC_BUS_MASK, secondary_bus);
al_pcie_controller_writel(pcie, cfg_control_offset, reg); + + return 0; }
static int al_pcie_host_init(struct dw_pcie_rp *pp) @@ -305,7 +313,9 @@ static int al_pcie_host_init(struct dw_pcie_rp *pp) if (rc) return rc;
- al_pcie_config_prepare(pcie); + rc = al_pcie_config_prepare(pcie); + if (rc) + return rc;
return 0; }
From: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com
[ Upstream commit 9dbd9962cfe56d210be5232349851420b5f9c8f6 ]
In scp_ipi_handler(), instead of zeroing out the entire shared buffer, which may be as large as 600 bytes, overwrite it with the received data, then zero out only the remaining bytes.
Signed-off-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20240520112724.139945-1-angelogioacchino.delregno@... Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/remoteproc/mtk_scp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c index b8498772dba17..b885a9a041e48 100644 --- a/drivers/remoteproc/mtk_scp.c +++ b/drivers/remoteproc/mtk_scp.c @@ -117,8 +117,8 @@ static void scp_ipi_handler(struct mtk_scp *scp) return; }
- memset(scp->share_buf, 0, scp_sizes->ipi_share_buffer_size); memcpy_fromio(scp->share_buf, &rcv_obj->share_buf, len); + memset(&scp->share_buf[len], 0, scp_sizes->ipi_share_buffer_size - len); handler(scp->share_buf, len, ipi_desc[id].priv); scp_ipi_unlock(scp, id);
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit d9b7531fe98a0c2a0387270557cf0a514c28dd28 ]
For active links, don't take information that may have been received in probe responses, as those are not protected. For inactive links, there may not be a choice.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Miri Korenblit miriam.rachel.korenblit@intel.com Link: https://msgid.link/20240527190228.6947dc462fa9.I2076961211d6785c8a15b4308e0e... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 14 ++++++++++++-- .../net/wireless/intel/iwlwifi/mvm/tests/links.c | 1 + 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c index 6ec9a8e21a34e..7b03d3ad60673 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -504,17 +504,27 @@ iwl_mvm_get_puncturing_factor(const struct ieee80211_bss_conf *link_conf) static unsigned int iwl_mvm_get_chan_load(struct ieee80211_bss_conf *link_conf) { + struct ieee80211_vif *vif = link_conf->vif; struct iwl_mvm_vif_link_info *mvm_link = iwl_mvm_vif_from_mac80211(link_conf->vif)->link[link_conf->link_id]; const struct element *bss_load_elem; const struct ieee80211_bss_load_elem *bss_load; enum nl80211_band band = link_conf->chanreq.oper.chan->band; + const struct cfg80211_bss_ies *ies; unsigned int chan_load; u32 chan_load_by_us;
rcu_read_lock(); - bss_load_elem = ieee80211_bss_get_elem(link_conf->bss, - WLAN_EID_QBSS_LOAD); + if (ieee80211_vif_link_active(vif, link_conf->link_id)) + ies = rcu_dereference(link_conf->bss->beacon_ies); + else + ies = rcu_dereference(link_conf->bss->ies); + + if (ies) + bss_load_elem = cfg80211_find_elem(WLAN_EID_QBSS_LOAD, + ies->data, ies->len); + else + bss_load_elem = NULL;
/* If there isn't BSS Load element, take the defaults */ if (!bss_load_elem || diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c b/drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c index f49e3c98b1ba4..991dc875a7ead 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c @@ -208,6 +208,7 @@ static void setup_link_conf(struct kunit *test) bss_load->channel_util = params->channel_util;
rcu_assign_pointer(bss.ies, ies); + rcu_assign_pointer(bss.beacon_ies, ies); }
static void test_link_grading(struct kunit *test)
From: Richard Maina quic_rmaina@quicinc.com
[ Upstream commit 7c327d56597d8de1680cf24e956b704270d3d84a ]
When a remoteproc crashes or goes down unexpectedly this can result in a state where locks held by the remoteproc will remain locked possibly resulting in deadlock. This new API hwspin_lock_bust() allows hwspinlock implementers to define a bust operation for freeing previously acquired hwspinlocks after verifying ownership of the acquired lock.
Signed-off-by: Richard Maina quic_rmaina@quicinc.com Reviewed-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Chris Lew quic_clew@quicinc.com Link: https://lore.kernel.org/r/20240529-hwspinlock-bust-v3-1-c8b924ffa5a2@quicinc... Signed-off-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/locking/hwspinlock.rst | 11 ++++++++++ drivers/hwspinlock/hwspinlock_core.c | 28 ++++++++++++++++++++++++ drivers/hwspinlock/hwspinlock_internal.h | 3 +++ include/linux/hwspinlock.h | 6 +++++ 4 files changed, 48 insertions(+)
diff --git a/Documentation/locking/hwspinlock.rst b/Documentation/locking/hwspinlock.rst index 6f03713b70039..2ffaa3cbd63f1 100644 --- a/Documentation/locking/hwspinlock.rst +++ b/Documentation/locking/hwspinlock.rst @@ -85,6 +85,17 @@ is already free).
Should be called from a process context (might sleep).
+:: + + int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id); + +After verifying the owner of the hwspinlock, release a previously acquired +hwspinlock; returns 0 on success, or an appropriate error code on failure +(e.g. -EOPNOTSUPP if the bust operation is not defined for the specific +hwspinlock). + +Should be called from a process context (might sleep). + ::
int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout); diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index 0c0a932c00f35..6505261e60686 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -305,6 +305,34 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) } EXPORT_SYMBOL_GPL(__hwspin_unlock);
+/** + * hwspin_lock_bust() - bust a specific hwspinlock + * @hwlock: a previously-acquired hwspinlock which we want to bust + * @id: identifier of the remote lock holder, if applicable + * + * This function will bust a hwspinlock that was previously acquired as + * long as the current owner of the lock matches the id given by the caller. + * + * Context: Process context. + * + * Returns: 0 on success, or -EINVAL if the hwspinlock does not exist, or + * the bust operation fails, and -EOPNOTSUPP if the bust operation is not + * defined for the hwspinlock. + */ +int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id) +{ + if (WARN_ON(!hwlock)) + return -EINVAL; + + if (!hwlock->bank->ops->bust) { + pr_err("bust operation not defined\n"); + return -EOPNOTSUPP; + } + + return hwlock->bank->ops->bust(hwlock, id); +} +EXPORT_SYMBOL_GPL(hwspin_lock_bust); + /** * of_hwspin_lock_simple_xlate - translate hwlock_spec to return a lock id * @hwlock_spec: hwlock specifier as found in the device tree diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/hwspinlock_internal.h index 29892767bb7a0..f298fc0ee5adb 100644 --- a/drivers/hwspinlock/hwspinlock_internal.h +++ b/drivers/hwspinlock/hwspinlock_internal.h @@ -21,6 +21,8 @@ struct hwspinlock_device; * @trylock: make a single attempt to take the lock. returns 0 on * failure and true on success. may _not_ sleep. * @unlock: release the lock. always succeed. may _not_ sleep. + * @bust: optional, platform-specific bust handler, called by hwspinlock + * core to bust a specific lock. * @relax: optional, platform-specific relax handler, called by hwspinlock * core while spinning on a lock, between two successive * invocations of @trylock. may _not_ sleep. @@ -28,6 +30,7 @@ struct hwspinlock_device; struct hwspinlock_ops { int (*trylock)(struct hwspinlock *lock); void (*unlock)(struct hwspinlock *lock); + int (*bust)(struct hwspinlock *lock, unsigned int id); void (*relax)(struct hwspinlock *lock); };
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h index bfe7c1f1ac6d1..f0231dbc47771 100644 --- a/include/linux/hwspinlock.h +++ b/include/linux/hwspinlock.h @@ -68,6 +68,7 @@ int __hwspin_lock_timeout(struct hwspinlock *, unsigned int, int, int __hwspin_trylock(struct hwspinlock *, int, unsigned long *); void __hwspin_unlock(struct hwspinlock *, int, unsigned long *); int of_hwspin_lock_get_id_byname(struct device_node *np, const char *name); +int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id); int devm_hwspin_lock_free(struct device *dev, struct hwspinlock *hwlock); struct hwspinlock *devm_hwspin_lock_request(struct device *dev); struct hwspinlock *devm_hwspin_lock_request_specific(struct device *dev, @@ -127,6 +128,11 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) { }
+static inline int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id) +{ + return 0; +} + static inline int of_hwspin_lock_get_id(struct device_node *np, int index) { return 0;
From: Chris Lew quic_clew@quicinc.com
[ Upstream commit 2e3f0d693875db698891ffe89a18121bda5b95b8 ]
Add qcom_smem_bust_hwspin_lock_by_host to enable remoteproc to bust the hwspin_lock owned by smem. In the event the remoteproc crashes unexpectedly, the remoteproc driver can invoke this API to try and bust the hwspin_lock and release the lock if still held by the remoteproc device.
Signed-off-by: Chris Lew quic_clew@quicinc.com Reviewed-by: Bjorn Andersson quic_bjorande@quicinc.com Link: https://lore.kernel.org/r/20240529-hwspinlock-bust-v3-3-c8b924ffa5a2@quicinc... Signed-off-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/smem.c | 26 ++++++++++++++++++++++++++ include/linux/soc/qcom/smem.h | 2 ++ 2 files changed, 28 insertions(+)
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 7191fa0c087f2..50039e983ebaa 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -359,6 +359,32 @@ static struct qcom_smem *__smem; /* Timeout (ms) for the trylock of remote spinlocks */ #define HWSPINLOCK_TIMEOUT 1000
+/* The qcom hwspinlock id is always plus one from the smem host id */ +#define SMEM_HOST_ID_TO_HWSPINLOCK_ID(__x) ((__x) + 1) + +/** + * qcom_smem_bust_hwspin_lock_by_host() - bust the smem hwspinlock for a host + * @host: remote processor id + * + * Busts the hwspin_lock for the given smem host id. This helper is intended + * for remoteproc drivers that manage remoteprocs with an equivalent smem + * driver instance in the remote firmware. Drivers can force a release of the + * smem hwspin_lock if the rproc unexpectedly goes into a bad state. + * + * Context: Process context. + * + * Returns: 0 on success, otherwise negative errno. + */ +int qcom_smem_bust_hwspin_lock_by_host(unsigned int host) +{ + /* This function is for remote procs, so ignore SMEM_HOST_APPS */ + if (host == SMEM_HOST_APPS || host >= SMEM_HOST_COUNT) + return -EINVAL; + + return hwspin_lock_bust(__smem->hwlock, SMEM_HOST_ID_TO_HWSPINLOCK_ID(host)); +} +EXPORT_SYMBOL_GPL(qcom_smem_bust_hwspin_lock_by_host); + /** * qcom_smem_is_available() - Check if SMEM is available * diff --git a/include/linux/soc/qcom/smem.h b/include/linux/soc/qcom/smem.h index a36a3b9d4929e..03187bc958518 100644 --- a/include/linux/soc/qcom/smem.h +++ b/include/linux/soc/qcom/smem.h @@ -14,4 +14,6 @@ phys_addr_t qcom_smem_virt_to_phys(void *p);
int qcom_smem_get_soc_id(u32 *id);
+int qcom_smem_bust_hwspin_lock_by_host(unsigned int host); + #endif
From: Richard Maina quic_rmaina@quicinc.com
[ Upstream commit 568b13b65078e2b557ccf47674a354cecd1db641 ]
When remoteproc goes down unexpectedly this results in a state where any acquired hwspinlocks will remain locked possibly resulting in deadlock. In order to ensure all locks are freed we include a call to qcom_smem_bust_hwspin_lock_by_host() during remoteproc shutdown.
For qcom_q6v5_pas remoteprocs, each remoteproc has an assigned smem host_id. Remoteproc can pass this id to smem to try and bust the lock on remoteproc stop.
This edge case only occurs with q6v5_pas watchdog crashes. The error fatal case has handling to clear the hwspinlock before the error fatal interrupt is triggered.
Signed-off-by: Richard Maina quic_rmaina@quicinc.com Reviewed-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Chris Lew quic_clew@quicinc.com Link: https://lore.kernel.org/r/20240529-hwspinlock-bust-v3-4-c8b924ffa5a2@quicinc... Signed-off-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/remoteproc/qcom_q6v5_pas.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 54d8005d40a34..8458bcfe9e19e 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -52,6 +52,7 @@ struct adsp_data { const char *ssr_name; const char *sysmon_name; int ssctl_id; + unsigned int smem_host_id;
int region_assign_idx; int region_assign_count; @@ -81,6 +82,7 @@ struct qcom_adsp { int lite_pas_id; unsigned int minidump_id; int crash_reason_smem; + unsigned int smem_host_id; bool decrypt_shutdown; const char *info_name;
@@ -399,6 +401,9 @@ static int adsp_stop(struct rproc *rproc) if (handover) qcom_pas_handover(&adsp->q6v5);
+ if (adsp->smem_host_id) + ret = qcom_smem_bust_hwspin_lock_by_host(adsp->smem_host_id); + return ret; }
@@ -727,6 +732,7 @@ static int adsp_probe(struct platform_device *pdev) adsp->pas_id = desc->pas_id; adsp->lite_pas_id = desc->lite_pas_id; adsp->info_name = desc->sysmon_name; + adsp->smem_host_id = desc->smem_host_id; adsp->decrypt_shutdown = desc->decrypt_shutdown; adsp->region_assign_idx = desc->region_assign_idx; adsp->region_assign_count = min_t(int, MAX_ASSIGN_COUNT, desc->region_assign_count); @@ -1196,6 +1202,7 @@ static const struct adsp_data sm8550_adsp_resource = { .ssr_name = "lpass", .sysmon_name = "adsp", .ssctl_id = 0x14, + .smem_host_id = 2, };
static const struct adsp_data sm8550_cdsp_resource = { @@ -1216,6 +1223,7 @@ static const struct adsp_data sm8550_cdsp_resource = { .ssr_name = "cdsp", .sysmon_name = "cdsp", .ssctl_id = 0x17, + .smem_host_id = 5, };
static const struct adsp_data sm8550_mpss_resource = { @@ -1236,6 +1244,7 @@ static const struct adsp_data sm8550_mpss_resource = { .ssr_name = "mpss", .sysmon_name = "modem", .ssctl_id = 0x12, + .smem_host_id = 1, .region_assign_idx = 2, .region_assign_count = 1, .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, @@ -1275,6 +1284,7 @@ static const struct adsp_data sm8650_cdsp_resource = { .ssr_name = "cdsp", .sysmon_name = "cdsp", .ssctl_id = 0x17, + .smem_host_id = 5, .region_assign_idx = 2, .region_assign_count = 1, .region_assign_shared = true, @@ -1299,6 +1309,7 @@ static const struct adsp_data sm8650_mpss_resource = { .ssr_name = "mpss", .sysmon_name = "modem", .ssctl_id = 0x12, + .smem_host_id = 1, .region_assign_idx = 2, .region_assign_count = 3, .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
From: Kent Gibson warthog618@gmail.com
[ Upstream commit 35d848e7a1cbba2649ed98cf58e0cdc7ee560c7a ]
The initialisation of the linereq events kfifo relies on the struct being zeroed and a subsequent call to kfifo_alloc(). The call to kfifo_alloc() is deferred until edge detection is first enabled for the linereq. If the kfifo is inadvertently accessed before the call to kfifo_alloc(), as was the case in a recently discovered bug, it behaves as a FIFO of size 1 with an element size of 0, so writes and reads to the kfifo appear successful but copy no actual data.
As a defensive measure, initialise the kfifo with INIT_KFIFO() when the events kfifo is constructed. This initialises the kfifo element size and zeroes its data pointer, so any inadvertant access prior to the kfifo_alloc() call will trigger an oops.
Signed-off-by: Kent Gibson warthog618@gmail.com Link: https://lore.kernel.org/r/20240529131953.195777-2-warthog618@gmail.com Signed-off-by: Bartosz Golaszewski bartosz.golaszewski@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpio/gpiolib-cdev.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 5639abce6ec57..62a6af8e53d0e 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -1780,6 +1780,7 @@ static int linereq_create(struct gpio_device *gdev, void __user *ip)
mutex_init(&lr->config_mutex); init_waitqueue_head(&lr->wait); + INIT_KFIFO(lr->events); lr->event_buffer_size = ulr.event_buffer_size; if (lr->event_buffer_size == 0) lr->event_buffer_size = ulr.num_lines * 16;
From: Ken Sloat ksloat@designlinxhs.com
[ Upstream commit 56f45266df67aa0f5b2a6881c8c4d16dbfff6b7d ]
This timer HW supports 8, 16 and 32-bit timer widths. This driver currently uses a u32 to store the max possible value of the timer. However, statements perform addition of 2 in xilinx_pwm_apply() when calculating the period_cycles and duty_cycles values. Since priv->max is a u32, this will result in an overflow to 1 which will not only be incorrect but fail on range comparison. This results in making it impossible to set the PWM in this timer mode.
There are two obvious solutions to the current problem: 1. Cast each instance where overflow occurs to u64. 2. Change priv->max from a u32 to a u64.
Solution #1 requires more code modifications, and leaves opportunity to introduce similar overflows if other math statements are added in the future. These may also go undetected if running in non 32-bit timer modes.
Solution #2 is the much smaller and cleaner approach and thus the chosen method in this patch.
This was tested on a Zynq UltraScale+ with multiple instances of the PWM IP.
Signed-off-by: Ken Sloat ksloat@designlinxhs.com Reviewed-by: Michal Simek michal.simek@amd.com Reviewed-by: Sean Anderson sean.anderson@seco.com Link: https://lore.kernel.org/r/SJ0P222MB0107490C5371B848EF04351CA1E19@SJ0P222MB01... Signed-off-by: Michal Simek michal.simek@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/clocksource/timer-xilinx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/clocksource/timer-xilinx.h b/include/clocksource/timer-xilinx.h index c0f56fe6d22ae..d116f18de899c 100644 --- a/include/clocksource/timer-xilinx.h +++ b/include/clocksource/timer-xilinx.h @@ -41,7 +41,7 @@ struct regmap; struct xilinx_timer_priv { struct regmap *map; struct clk *clk; - u32 max; + u64 max; };
/**
From: Jesse Zhang jesse.zhang@amd.com
[ Upstream commit c09d2eff81a997c169e0cacacd6b60c5e3aa33f2 ]
Potentially overflowing expression mall_size_per_umc * adev->gmc.num_umc with type unsigned int (32 bits, unsigned) is evaluated using 32-bit arithmetic,and then used in a context that expects an expression of type u64 (64 bits, unsigned).
Signed-off-by: Jesse Zhang Jesse.Zhang@amd.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index 0e31bdb4b7cb6..71db111e20f80 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -1595,7 +1595,7 @@ static int amdgpu_discovery_get_mall_info(struct amdgpu_device *adev) break; case 2: mall_size_per_umc = le32_to_cpu(mall_info->v2.mall_size_per_umc); - adev->gmc.mall_size = mall_size_per_umc * adev->gmc.num_umc; + adev->gmc.mall_size = (uint64_t)mall_size_per_umc * adev->gmc.num_umc; break; default: dev_err(adev->dev,
From: Casey Schaufler casey@schaufler-ca.com
[ Upstream commit 2fe209d0ad2e2729f7e22b9b31a86cc3ff0db550 ]
Currently, Smack mirrors the label of incoming tcp/ipv4 connections: when a label 'foo' connects to a label 'bar' with tcp/ipv4, 'foo' always gets 'foo' in returned ipv4 packets. So, 1) returned packets are incorrectly labeled ('foo' instead of 'bar') 2) 'bar' can write to 'foo' without being authorized to write.
Here is a scenario how to see this:
* Take two machines, let's call them C and S, with active Smack in the default state (no settings, no rules, no labeled hosts, only builtin labels)
* At S, add Smack rule 'foo bar w' (labels 'foo' and 'bar' are instantiated at S at this moment)
* At S, at label 'bar', launch a program that listens for incoming tcp/ipv4 connections
* From C, at label 'foo', connect to the listener at S. (label 'foo' is instantiated at C at this moment) Connection succeedes and works.
* Send some data in both directions. * Collect network traffic of this connection.
All packets in both directions are labeled with the CIPSO of the label 'foo'. Hence, label 'bar' writes to 'foo' without being authorized, and even without ever being known at C.
If anybody cares: exactly the same happens with DCCP.
This behavior 1st manifested in release 2.6.29.4 (see Fixes below) and it looks unintentional. At least, no explanation was provided.
I changed returned packes label into the 'bar', to bring it into line with the Smack documentation claims.
Signed-off-by: Konstantin Andreev andreev@swemel.ru Signed-off-by: Casey Schaufler casey@schaufler-ca.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/smack/smack_lsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index f5cbec1e6a923..8478ed8596542 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4431,7 +4431,7 @@ static int smack_inet_conn_request(const struct sock *sk, struct sk_buff *skb, rcu_read_unlock();
if (hskp == NULL) - rc = netlbl_req_setattr(req, &skp->smk_netlabel); + rc = netlbl_req_setattr(req, &ssp->smk_out->smk_netlabel); else netlbl_req_delattr(req);
From: Marek Vasut marex@denx.de
[ Upstream commit 162e48cb1d84c2c966b649b8ac5c9d4f75f6d44f ]
Make sure the connector is fully initialized before signalling any HPD events via drm_kms_helper_hotplug_event(), otherwise this may lead to NULL pointer dereference.
Signed-off-by: Marek Vasut marex@denx.de Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20240531203333.277476-1-marex@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358767.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 166f9a3e9622d..332f0aa50fee4 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -2135,7 +2135,7 @@ static irqreturn_t tc_irq_handler(int irq, void *arg) dev_err(tc->dev, "syserr %x\n", stat); }
- if (tc->hpd_pin >= 0 && tc->bridge.dev) { + if (tc->hpd_pin >= 0 && tc->bridge.dev && tc->aux.drm_dev) { /* * H is triggered when the GPIO goes high. *
From: Himal Prasad Ghimiray himal.prasad.ghimiray@intel.com
[ Upstream commit 35feb8dbbca627d118ccc1f2111841788c142703 ]
Assert domain is not XE_FORCEWAKE_ALL.
v2 - use domain != XE_FORCEWAKE_ALL (Michal)
v3 - Fix commit description.
Cc: Michal Wajdeczko michal.wajdeczko@intel.com Cc: Rodrigo Vivi rodrigo.vivi@intel.com Cc: Lucas De Marchi lucas.demarchi@intel.com Cc: Badal Nilawar badal.nilawar@intel.com Signed-off-by: Himal Prasad Ghimiray himal.prasad.ghimiray@intel.com Reviewed-by: Michal Wajdeczko michal.wajdeczko@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20240607125741.1407331-2-himal... Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xe/xe_force_wake.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_force_wake.h b/drivers/gpu/drm/xe/xe_force_wake.h index 83cb157da7cc6..23b36d13f18a6 100644 --- a/drivers/gpu/drm/xe/xe_force_wake.h +++ b/drivers/gpu/drm/xe/xe_force_wake.h @@ -24,7 +24,7 @@ static inline int xe_force_wake_ref(struct xe_force_wake *fw, enum xe_force_wake_domains domain) { - xe_gt_assert(fw->gt, domain); + xe_gt_assert(fw->gt, domain != XE_FORCEWAKE_ALL); return fw->domains[ffs(domain) - 1].ref; }
From: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com
[ Upstream commit a3a632ed87f0913779092c30bd0ea7dfd81601f3 ]
On RZ/V2H(P) SoC, the power registers for SD and ETH do not exist, resulting in invalid register offsets. Ensure that the register offsets are valid before any read/write operations are performed. If the power registers are not available, both SD and ETH will be set to '0'.
Signed-off-by: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Tested-by: Claudiu Beznea claudiu.beznea.uj@bp.renesas.com # on RZ/G3S Link: https://lore.kernel.org/r/20240530173857.164073-7-prabhakar.mahadev-lad.rj@b... Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/renesas/pinctrl-rzg2l.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index 60be78da9f529..389602e4d7ab3 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -2583,8 +2583,10 @@ static int rzg2l_pinctrl_suspend_noirq(struct device *dev) rzg2l_pinctrl_pm_setup_dedicated_regs(pctrl, true);
for (u8 i = 0; i < 2; i++) { - cache->sd_ch[i] = readb(pctrl->base + SD_CH(regs->sd_ch, i)); - cache->eth_poc[i] = readb(pctrl->base + ETH_POC(regs->eth_poc, i)); + if (regs->sd_ch) + cache->sd_ch[i] = readb(pctrl->base + SD_CH(regs->sd_ch, i)); + if (regs->eth_poc) + cache->eth_poc[i] = readb(pctrl->base + ETH_POC(regs->eth_poc, i)); }
cache->qspi = readb(pctrl->base + QSPI); @@ -2615,8 +2617,10 @@ static int rzg2l_pinctrl_resume_noirq(struct device *dev) writeb(cache->qspi, pctrl->base + QSPI); writeb(cache->eth_mode, pctrl->base + ETH_MODE); for (u8 i = 0; i < 2; i++) { - writeb(cache->sd_ch[i], pctrl->base + SD_CH(regs->sd_ch, i)); - writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i)); + if (regs->sd_ch) + writeb(cache->sd_ch[i], pctrl->base + SD_CH(regs->sd_ch, i)); + if (regs->eth_poc) + writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i)); }
rzg2l_pinctrl_pm_setup_pfc(pctrl);
From: "Rafael J. Wysocki" rafael.j.wysocki@intel.com
[ Upstream commit a52641bc6293a24f25956a597e7f32148b0e2bb8 ]
When accessing trip temperature and hysteresis without locking, it is better to use READ_ONCE() to prevent compiler optimizations possibly affecting the read from being applied.
Of course, for the READ_ONCE() to be effective, WRITE_ONCE() needs to be used when updating their values.
Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/thermal_sysfs.c | 6 +++--- drivers/thermal/thermal_trip.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index 88211ccdfbd62..5be6113e7c80f 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -150,7 +150,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1) return -EINVAL;
- return sprintf(buf, "%d\n", tz->trips[trip_id].trip.temperature); + return sprintf(buf, "%d\n", READ_ONCE(tz->trips[trip_id].trip.temperature)); }
static ssize_t @@ -174,7 +174,7 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, trip = &tz->trips[trip_id].trip;
if (hyst != trip->hysteresis) { - trip->hysteresis = hyst; + WRITE_ONCE(trip->hysteresis, hyst);
thermal_zone_trip_updated(tz, trip); } @@ -194,7 +194,7 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr, if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1) return -EINVAL;
- return sprintf(buf, "%d\n", tz->trips[trip_id].trip.hysteresis); + return sprintf(buf, "%d\n", READ_ONCE(tz->trips[trip_id].trip.hysteresis)); }
static ssize_t diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index 49e63db685172..b4e7411b2fe74 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -152,7 +152,7 @@ void thermal_zone_set_trip_temp(struct thermal_zone_device *tz, if (trip->temperature == temp) return;
- trip->temperature = temp; + WRITE_ONCE(trip->temperature, temp); thermal_notify_tz_trip_change(tz, trip);
if (temp == THERMAL_TEMP_INVALID) {
On Thu, Aug 1, 2024 at 2:15 AM Sasha Levin sashal@kernel.org wrote:
From: "Rafael J. Wysocki" rafael.j.wysocki@intel.com
[ Upstream commit a52641bc6293a24f25956a597e7f32148b0e2bb8 ]
When accessing trip temperature and hysteresis without locking, it is better to use READ_ONCE() to prevent compiler optimizations possibly affecting the read from being applied.
Of course, for the READ_ONCE() to be effective, WRITE_ONCE() needs to be used when updating their values.
Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org
This is more of a matter of annotation than practical issue. That's why I haven't even added a Fixes: tag to it.
Whether or not to take it into "stable" is up to you. It certainly is low-risk in any case.
drivers/thermal/thermal_sysfs.c | 6 +++--- drivers/thermal/thermal_trip.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index 88211ccdfbd62..5be6113e7c80f 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -150,7 +150,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1) return -EINVAL;
return sprintf(buf, "%d\n", tz->trips[trip_id].trip.temperature);
return sprintf(buf, "%d\n", READ_ONCE(tz->trips[trip_id].trip.temperature));
}
static ssize_t @@ -174,7 +174,7 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, trip = &tz->trips[trip_id].trip;
if (hyst != trip->hysteresis) {
trip->hysteresis = hyst;
WRITE_ONCE(trip->hysteresis, hyst); thermal_zone_trip_updated(tz, trip); }
@@ -194,7 +194,7 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr, if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1) return -EINVAL;
return sprintf(buf, "%d\n", tz->trips[trip_id].trip.hysteresis);
return sprintf(buf, "%d\n", READ_ONCE(tz->trips[trip_id].trip.hysteresis));
}
static ssize_t diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index 49e63db685172..b4e7411b2fe74 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -152,7 +152,7 @@ void thermal_zone_set_trip_temp(struct thermal_zone_device *tz, if (trip->temperature == temp) return;
trip->temperature = temp;
WRITE_ONCE(trip->temperature, temp); thermal_notify_tz_trip_change(tz, trip); if (temp == THERMAL_TEMP_INVALID) {
-- 2.43.0
From: Yazen Ghannam yazen.ghannam@amd.com
[ Upstream commit 5ac6293047cf5de6daca662347c19347e856c2a5 ]
Check the return value of amd_smn_read() before saving a value. This ensures invalid values aren't saved. The struct umc instance is initialized to 0 during memory allocation. Therefore, a bad read will keep the value as 0 providing the expected Read-as-Zero behavior.
Signed-off-by: Yazen Ghannam yazen.ghannam@amd.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Reviewed-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20240606-fix-smn-bad-read-v4-2-ffde21931c3f@amd.co... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/edac/amd64_edac.c | 51 ++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 14 deletions(-)
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index a17f3c0cdfa60..4300c4e7683c8 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1454,6 +1454,7 @@ static void umc_read_base_mask(struct amd64_pvt *pvt) u32 *base, *base_sec; u32 *mask, *mask_sec; int cs, umc; + u32 tmp;
for_each_umc(umc) { umc_base_reg = get_umc_base(umc) + UMCCH_BASE_ADDR; @@ -1466,13 +1467,17 @@ static void umc_read_base_mask(struct amd64_pvt *pvt) base_reg = umc_base_reg + (cs * 4); base_reg_sec = umc_base_reg_sec + (cs * 4);
- if (!amd_smn_read(pvt->mc_node_id, base_reg, base)) + if (!amd_smn_read(pvt->mc_node_id, base_reg, &tmp)) { + *base = tmp; edac_dbg(0, " DCSB%d[%d]=0x%08x reg: 0x%x\n", umc, cs, *base, base_reg); + }
- if (!amd_smn_read(pvt->mc_node_id, base_reg_sec, base_sec)) + if (!amd_smn_read(pvt->mc_node_id, base_reg_sec, &tmp)) { + *base_sec = tmp; edac_dbg(0, " DCSB_SEC%d[%d]=0x%08x reg: 0x%x\n", umc, cs, *base_sec, base_reg_sec); + } }
umc_mask_reg = get_umc_base(umc) + UMCCH_ADDR_MASK; @@ -1485,13 +1490,17 @@ static void umc_read_base_mask(struct amd64_pvt *pvt) mask_reg = umc_mask_reg + (cs * 4); mask_reg_sec = umc_mask_reg_sec + (cs * 4);
- if (!amd_smn_read(pvt->mc_node_id, mask_reg, mask)) + if (!amd_smn_read(pvt->mc_node_id, mask_reg, &tmp)) { + *mask = tmp; edac_dbg(0, " DCSM%d[%d]=0x%08x reg: 0x%x\n", umc, cs, *mask, mask_reg); + }
- if (!amd_smn_read(pvt->mc_node_id, mask_reg_sec, mask_sec)) + if (!amd_smn_read(pvt->mc_node_id, mask_reg_sec, &tmp)) { + *mask_sec = tmp; edac_dbg(0, " DCSM_SEC%d[%d]=0x%08x reg: 0x%x\n", umc, cs, *mask_sec, mask_reg_sec); + } } } } @@ -2910,7 +2919,7 @@ static void umc_read_mc_regs(struct amd64_pvt *pvt) { u8 nid = pvt->mc_node_id; struct amd64_umc *umc; - u32 i, umc_base; + u32 i, tmp, umc_base;
/* Read registers from each UMC */ for_each_umc(i) { @@ -2918,11 +2927,20 @@ static void umc_read_mc_regs(struct amd64_pvt *pvt) umc_base = get_umc_base(i); umc = &pvt->umc[i];
- amd_smn_read(nid, umc_base + get_umc_reg(pvt, UMCCH_DIMM_CFG), &umc->dimm_cfg); - amd_smn_read(nid, umc_base + UMCCH_UMC_CFG, &umc->umc_cfg); - amd_smn_read(nid, umc_base + UMCCH_SDP_CTRL, &umc->sdp_ctrl); - amd_smn_read(nid, umc_base + UMCCH_ECC_CTRL, &umc->ecc_ctrl); - amd_smn_read(nid, umc_base + UMCCH_UMC_CAP_HI, &umc->umc_cap_hi); + if (!amd_smn_read(nid, umc_base + get_umc_reg(pvt, UMCCH_DIMM_CFG), &tmp)) + umc->dimm_cfg = tmp; + + if (!amd_smn_read(nid, umc_base + UMCCH_UMC_CFG, &tmp)) + umc->umc_cfg = tmp; + + if (!amd_smn_read(nid, umc_base + UMCCH_SDP_CTRL, &tmp)) + umc->sdp_ctrl = tmp; + + if (!amd_smn_read(nid, umc_base + UMCCH_ECC_CTRL, &tmp)) + umc->ecc_ctrl = tmp; + + if (!amd_smn_read(nid, umc_base + UMCCH_UMC_CAP_HI, &tmp)) + umc->umc_cap_hi = tmp; } }
@@ -3651,16 +3669,21 @@ static void gpu_read_mc_regs(struct amd64_pvt *pvt) { u8 nid = pvt->mc_node_id; struct amd64_umc *umc; - u32 i, umc_base; + u32 i, tmp, umc_base;
/* Read registers from each UMC */ for_each_umc(i) { umc_base = gpu_get_umc_base(pvt, i, 0); umc = &pvt->umc[i];
- amd_smn_read(nid, umc_base + UMCCH_UMC_CFG, &umc->umc_cfg); - amd_smn_read(nid, umc_base + UMCCH_SDP_CTRL, &umc->sdp_ctrl); - amd_smn_read(nid, umc_base + UMCCH_ECC_CTRL, &umc->ecc_ctrl); + if (!amd_smn_read(nid, umc_base + UMCCH_UMC_CFG, &tmp)) + umc->umc_cfg = tmp; + + if (!amd_smn_read(nid, umc_base + UMCCH_SDP_CTRL, &tmp)) + umc->sdp_ctrl = tmp; + + if (!amd_smn_read(nid, umc_base + UMCCH_ECC_CTRL, &tmp)) + umc->ecc_ctrl = tmp; } }
From: Yazen Ghannam yazen.ghannam@amd.com
[ Upstream commit c2d79cc5455c891de6c93e1e0c73d806e299c54f ]
Check the return value of amd_smn_read() before saving a value. This ensures invalid values aren't saved or used.
There are three cases here with slightly different behavior:
1) read_tempreg_nb_zen(): This is a function pointer which does not include a return code. In this case, set the register value to 0 on failure. This enforces Read-as-Zero behavior.
2) k10temp_read_temp(): This function does have return codes, so return the error code from the failed register read. Continued operation is not necessary, since there is no valid data from the register. Furthermore, if the register value was set to 0, then the following operation would underflow.
3) k10temp_get_ccd_support(): This function reads the same register from multiple CCD instances in a loop. And a bitmask is formed if a specific bit is set in each register instance. The loop should continue on a failed register read, skipping the bit check.
Signed-off-by: Yazen Ghannam yazen.ghannam@amd.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Reviewed-by: Mario Limonciello mario.limonciello@amd.com Acked-by: Guenter Roeck linux@roeck-us.net Link: https://lore.kernel.org/r/20240606-fix-smn-bad-read-v4-3-ffde21931c3f@amd.co... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/k10temp.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 8092312c0a877..6cad35e7f1828 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -153,8 +153,9 @@ static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval) { - amd_smn_read(amd_pci_dev_to_node_id(pdev), - ZEN_REPORTED_TEMP_CTRL_BASE, regval); + if (amd_smn_read(amd_pci_dev_to_node_id(pdev), + ZEN_REPORTED_TEMP_CTRL_BASE, regval)) + *regval = 0; }
static long get_raw_temp(struct k10temp_data *data) @@ -205,6 +206,7 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel, long *val) { struct k10temp_data *data = dev_get_drvdata(dev); + int ret = -EOPNOTSUPP; u32 regval;
switch (attr) { @@ -221,13 +223,17 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel, *val = 0; break; case 2 ... 13: /* Tccd{1-12} */ - amd_smn_read(amd_pci_dev_to_node_id(data->pdev), - ZEN_CCD_TEMP(data->ccd_offset, channel - 2), - ®val); + ret = amd_smn_read(amd_pci_dev_to_node_id(data->pdev), + ZEN_CCD_TEMP(data->ccd_offset, channel - 2), + ®val); + + if (ret) + return ret; + *val = (regval & ZEN_CCD_TEMP_MASK) * 125 - 49000; break; default: - return -EOPNOTSUPP; + return ret; } break; case hwmon_temp_max: @@ -243,7 +249,7 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel, - ((regval >> 24) & 0xf)) * 500 + 52000; break; default: - return -EOPNOTSUPP; + return ret; } return 0; } @@ -381,8 +387,20 @@ static void k10temp_get_ccd_support(struct pci_dev *pdev, int i;
for (i = 0; i < limit; i++) { - amd_smn_read(amd_pci_dev_to_node_id(pdev), - ZEN_CCD_TEMP(data->ccd_offset, i), ®val); + /* + * Ignore inaccessible CCDs. + * + * Some systems will return a register value of 0, and the TEMP_VALID + * bit check below will naturally fail. + * + * Other systems will return a PCI_ERROR_RESPONSE (0xFFFFFFFF) for + * the register value. And this will incorrectly pass the TEMP_VALID + * bit check. + */ + if (amd_smn_read(amd_pci_dev_to_node_id(pdev), + ZEN_CCD_TEMP(data->ccd_offset, i), ®val)) + continue; + if (regval & ZEN_CCD_TEMP_VALID) data->show_temp |= BIT(TCCD_BIT(i)); }
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 7f12e26a194d0043441f870708093d9c2c3bad7d ]
Jiazi Li reported that they occasionally see hash table duplicates as evidenced by the WARN_ON() in rb_insert_bss() in this code. It isn't clear how that happens, nor have I been able to reproduce it, but if it does happen, the kernel crashes later, when it tries to unhash the entry that's now not hashed.
Try to make this situation more survivable by removing the BSS from the list(s) as well, that way it's fully leaked here (as had been the intent in the hash insert error path), and no longer reachable through the list(s) so it shouldn't be unhashed again later.
Link: https://lore.kernel.org/r/20231026013528.GA24122@Jiazi.Li Signed-off-by: Johannes Berg johannes.berg@intel.com Link: https://msgid.link/20240607181726.36835-2-johannes@sipsolutions.net Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/scan.c | 46 +++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 0222ede0feb60..39965cda04789 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -1604,7 +1604,7 @@ struct cfg80211_bss *__cfg80211_get_bss(struct wiphy *wiphy, } EXPORT_SYMBOL(__cfg80211_get_bss);
-static void rb_insert_bss(struct cfg80211_registered_device *rdev, +static bool rb_insert_bss(struct cfg80211_registered_device *rdev, struct cfg80211_internal_bss *bss) { struct rb_node **p = &rdev->bss_tree.rb_node; @@ -1620,7 +1620,7 @@ static void rb_insert_bss(struct cfg80211_registered_device *rdev,
if (WARN_ON(!cmp)) { /* will sort of leak this BSS */ - return; + return false; }
if (cmp < 0) @@ -1631,6 +1631,7 @@ static void rb_insert_bss(struct cfg80211_registered_device *rdev,
rb_link_node(&bss->rbn, parent, p); rb_insert_color(&bss->rbn, &rdev->bss_tree); + return true; }
static struct cfg80211_internal_bss * @@ -1657,6 +1658,34 @@ rb_find_bss(struct cfg80211_registered_device *rdev, return NULL; }
+static void cfg80211_insert_bss(struct cfg80211_registered_device *rdev, + struct cfg80211_internal_bss *bss) +{ + lockdep_assert_held(&rdev->bss_lock); + + if (!rb_insert_bss(rdev, bss)) + return; + list_add_tail(&bss->list, &rdev->bss_list); + rdev->bss_entries++; +} + +static void cfg80211_rehash_bss(struct cfg80211_registered_device *rdev, + struct cfg80211_internal_bss *bss) +{ + lockdep_assert_held(&rdev->bss_lock); + + rb_erase(&bss->rbn, &rdev->bss_tree); + if (!rb_insert_bss(rdev, bss)) { + list_del(&bss->list); + if (!list_empty(&bss->hidden_list)) + list_del_init(&bss->hidden_list); + if (!list_empty(&bss->pub.nontrans_list)) + list_del_init(&bss->pub.nontrans_list); + rdev->bss_entries--; + } + rdev->bss_generation++; +} + static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev, struct cfg80211_internal_bss *new) { @@ -1969,9 +1998,7 @@ __cfg80211_bss_update(struct cfg80211_registered_device *rdev, bss_ref_get(rdev, bss_from_pub(tmp->pub.transmitted_bss)); }
- list_add_tail(&new->list, &rdev->bss_list); - rdev->bss_entries++; - rb_insert_bss(rdev, new); + cfg80211_insert_bss(rdev, new); found = new; }
@@ -3349,19 +3376,14 @@ void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev, if (!WARN_ON(!__cfg80211_unlink_bss(rdev, new))) rdev->bss_generation++; } - - rb_erase(&cbss->rbn, &rdev->bss_tree); - rb_insert_bss(rdev, cbss); - rdev->bss_generation++; + cfg80211_rehash_bss(rdev, cbss);
list_for_each_entry_safe(nontrans_bss, tmp, &cbss->pub.nontrans_list, nontrans_list) { bss = bss_from_pub(nontrans_bss); bss->pub.channel = chan; - rb_erase(&bss->rbn, &rdev->bss_tree); - rb_insert_bss(rdev, bss); - rdev->bss_generation++; + cfg80211_rehash_bss(rdev, bss); }
done:
From: Julien Stephan jstephan@baylibre.com
[ Upstream commit c4ec8dedca961db056ec85cb7ca8c9f7e2e92252 ]
Some callbacks from iio_info structure are accessed without any check, so if a driver doesn't implement them trying to access the corresponding sysfs entries produce a kernel oops such as:
[ 2203.527791] Unable to handle kernel NULL pointer dereference at virtual address 00000000 when execute [...] [ 2203.783416] Call trace: [ 2203.783429] iio_read_channel_info_avail from dev_attr_show+0x18/0x48 [ 2203.789807] dev_attr_show from sysfs_kf_seq_show+0x90/0x120 [ 2203.794181] sysfs_kf_seq_show from seq_read_iter+0xd0/0x4e4 [ 2203.798555] seq_read_iter from vfs_read+0x238/0x2a0 [ 2203.802236] vfs_read from ksys_read+0xa4/0xd4 [ 2203.805385] ksys_read from ret_fast_syscall+0x0/0x54 [ 2203.809135] Exception stack(0xe0badfa8 to 0xe0badff0) [ 2203.812880] dfa0: 00000003 b6f10f80 00000003 b6eab000 00020000 00000000 [ 2203.819746] dfc0: 00000003 b6f10f80 7ff00000 00000003 00000003 00000000 00020000 00000000 [ 2203.826619] dfe0: b6e1bc88 bed80958 b6e1bc94 b6e1bcb0 [ 2203.830363] Code: bad PC value [ 2203.832695] ---[ end trace 0000000000000000 ]---
Reviewed-by: Nuno Sa nuno.sa@analog.com Signed-off-by: Julien Stephan jstephan@baylibre.com Link: https://lore.kernel.org/r/20240530-iio-core-fix-segfault-v3-1-8b7cd2a03773@b... Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/industrialio-core.c | 7 ++++++- drivers/iio/industrialio-event.c | 9 +++++++++ drivers/iio/inkern.c | 32 ++++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 11 deletions(-)
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index fa7cc051b4c49..2f185b3869495 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -758,9 +758,11 @@ static ssize_t iio_read_channel_info(struct device *dev, INDIO_MAX_RAW_ELEMENTS, vals, &val_len, this_attr->address); - else + else if (indio_dev->info->read_raw) ret = indio_dev->info->read_raw(indio_dev, this_attr->c, &vals[0], &vals[1], this_attr->address); + else + return -EINVAL;
if (ret < 0) return ret; @@ -842,6 +844,9 @@ static ssize_t iio_read_channel_info_avail(struct device *dev, int length; int type;
+ if (!indio_dev->info->read_avail) + return -EINVAL; + ret = indio_dev->info->read_avail(indio_dev, this_attr->c, &vals, &type, &length, this_attr->address); diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 910c1f14abd55..a64f8fbac597e 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -285,6 +285,9 @@ static ssize_t iio_ev_state_store(struct device *dev, if (ret < 0) return ret;
+ if (!indio_dev->info->write_event_config) + return -EINVAL; + ret = indio_dev->info->write_event_config(indio_dev, this_attr->c, iio_ev_attr_type(this_attr), iio_ev_attr_dir(this_attr), val); @@ -300,6 +303,9 @@ static ssize_t iio_ev_state_show(struct device *dev, struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int val;
+ if (!indio_dev->info->read_event_config) + return -EINVAL; + val = indio_dev->info->read_event_config(indio_dev, this_attr->c, iio_ev_attr_type(this_attr), iio_ev_attr_dir(this_attr)); @@ -318,6 +324,9 @@ static ssize_t iio_ev_value_show(struct device *dev, int val, val2, val_arr[2]; int ret;
+ if (!indio_dev->info->read_event_value) + return -EINVAL; + ret = indio_dev->info->read_event_value(indio_dev, this_attr->c, iio_ev_attr_type(this_attr), iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr), diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 485e6fc44a04c..39cf26d69d17a 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -543,6 +543,7 @@ EXPORT_SYMBOL_GPL(devm_iio_channel_get_all); static int iio_channel_read(struct iio_channel *chan, int *val, int *val2, enum iio_chan_info_enum info) { + const struct iio_info *iio_info = chan->indio_dev->info; int unused; int vals[INDIO_MAX_RAW_ELEMENTS]; int ret; @@ -554,15 +555,18 @@ static int iio_channel_read(struct iio_channel *chan, int *val, int *val2, if (!iio_channel_has_info(chan->channel, info)) return -EINVAL;
- if (chan->indio_dev->info->read_raw_multi) { - ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev, - chan->channel, INDIO_MAX_RAW_ELEMENTS, - vals, &val_len, info); + if (iio_info->read_raw_multi) { + ret = iio_info->read_raw_multi(chan->indio_dev, + chan->channel, + INDIO_MAX_RAW_ELEMENTS, + vals, &val_len, info); *val = vals[0]; *val2 = vals[1]; + } else if (iio_info->read_raw) { + ret = iio_info->read_raw(chan->indio_dev, + chan->channel, val, val2, info); } else { - ret = chan->indio_dev->info->read_raw(chan->indio_dev, - chan->channel, val, val2, info); + return -EINVAL; }
return ret; @@ -750,11 +754,15 @@ static int iio_channel_read_avail(struct iio_channel *chan, const int **vals, int *type, int *length, enum iio_chan_info_enum info) { + const struct iio_info *iio_info = chan->indio_dev->info; + if (!iio_channel_has_available(chan->channel, info)) return -EINVAL;
- return chan->indio_dev->info->read_avail(chan->indio_dev, chan->channel, - vals, type, length, info); + if (iio_info->read_avail) + return iio_info->read_avail(chan->indio_dev, chan->channel, + vals, type, length, info); + return -EINVAL; }
int iio_read_avail_channel_attribute(struct iio_channel *chan, @@ -917,8 +925,12 @@ EXPORT_SYMBOL_GPL(iio_get_channel_type); static int iio_channel_write(struct iio_channel *chan, int val, int val2, enum iio_chan_info_enum info) { - return chan->indio_dev->info->write_raw(chan->indio_dev, - chan->channel, val, val2, info); + const struct iio_info *iio_info = chan->indio_dev->info; + + if (iio_info->write_raw) + return iio_info->write_raw(chan->indio_dev, + chan->channel, val, val2, info); + return -EINVAL; }
int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2,
From: winstang winstang@amd.com
[ Upstream commit 26c56049cc4f1705b498df013949427692a4b0d5 ]
[Why] prevent invalid memory access
[How] check if dc and stream are NULL
Co-authored-by: winstang winstang@amd.com Reviewed-by: Alvin Lee alvin.lee2@amd.com Acked-by: Zaeem Mohamed zaeem.mohamed@amd.com Signed-off-by: winstang winstang@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 76a8e90da0d56..dffc663fd1a10 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -4656,6 +4656,9 @@ void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) { + if (dc == NULL || stream == NULL) + return DC_ERROR_UNEXPECTED; + struct dc_link *link = stream->link; struct timing_generator *tg = dc->res_pool->timing_generators[0]; enum dc_status res = DC_OK;
From: Wayne Lin wayne.lin@amd.com
[ Upstream commit ad28d7c3d989fc5689581664653879d664da76f0 ]
[Why & How] It actually exposes '6' types in enum dmub_notification_type. Not 5. Using smaller number to create array dmub_callback & dmub_thread_offload has potential to access item out of array bound. Fix it.
Reviewed-by: Jerry Zuo jerry.zuo@amd.com Acked-by: Zaeem Mohamed zaeem.mohamed@amd.com Signed-off-by: Wayne Lin wayne.lin@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 09519b7abf67b..5c9d32dff8538 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -50,7 +50,7 @@
#define AMDGPU_DM_MAX_NUM_EDP 2
-#define AMDGPU_DMUB_NOTIFICATION_MAX 5 +#define AMDGPU_DMUB_NOTIFICATION_MAX 6
#define HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_IEEE_REGISTRATION_ID 0x00001A #define AMD_VSDB_VERSION_3_FEATURECAP_REPLAYMODE 0x40
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit 466423c6dd8af23ebb3a69d43434d01aed0db356 ]
[Why] These registers should not be read from driver and triggering the security violation when DMCUB work times out and diagnostics are collected blocks Z8 entry.
[How] Remove the register read from DCN35.
Reviewed-by: Duncan Ma duncan.ma@amd.com Acked-by: Zaeem Mohamed zaeem.mohamed@amd.com Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c index 70e63aeb8f89b..a330827f900c3 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c @@ -459,7 +459,7 @@ uint32_t dmub_dcn35_get_current_time(struct dmub_srv *dmub) void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data) { uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset; - uint32_t is_traceport_enabled, is_cw0_enabled, is_cw6_enabled; + uint32_t is_traceport_enabled, is_cw6_enabled;
if (!dmub || !diag_data) return; @@ -510,9 +510,6 @@ void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); diag_data->is_traceport_en = is_traceport_enabled;
- REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled); - diag_data->is_cw0_enabled = is_cw0_enabled; - REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); diag_data->is_cw6_enabled = is_cw6_enabled;
From: Wenjing Liu wenjing.liu@amd.com
[ Upstream commit abf34ca465f5cd182b07701d3f3d369c0fc04723 ]
[why] We set preferred link settings for virtual signal. However we don't support virtual signal for UHBR link rate. If preferred is set to UHBR link rate, we will allow virtual signal with UHBR link rate which causes system crashes.
Reviewed-by: Dillon Varone dillon.varone@amd.com Acked-by: Zaeem Mohamed zaeem.mohamed@amd.com Signed-off-by: Wenjing Liu wenjing.liu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../dc/link/protocols/link_dp_capability.c | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index b26faed3bb206..a3df1b55e48b7 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -914,21 +914,17 @@ bool link_decide_link_settings(struct dc_stream_state *stream,
memset(link_setting, 0, sizeof(*link_setting));
- /* if preferred is specified through AMDDP, use it, if it's enough - * to drive the mode - */ - if (link->preferred_link_setting.lane_count != - LANE_COUNT_UNKNOWN && - link->preferred_link_setting.link_rate != - LINK_RATE_UNKNOWN) { + if (dc_is_dp_signal(stream->signal) && + link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN && + link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN) { + /* if preferred is specified through AMDDP, use it, if it's enough + * to drive the mode + */ *link_setting = link->preferred_link_setting; - return true; - } - - /* MST doesn't perform link training for now - * TODO: add MST specific link training routine - */ - if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { + } else if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { + /* MST doesn't perform link training for now + * TODO: add MST specific link training routine + */ decide_mst_link_settings(link, link_setting); } else if (link->connector_signal == SIGNAL_TYPE_EDP) { /* enable edp link optimization for DSC eDP case */
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit 7c70e60fbf4bff1123f0e8d5cb1ae71df6164d7f ]
[Why] DMCUB can intermittently take longer than expected to process commands.
Old ASIC policy was to continue while logging a diagnostic error - which works fine for ASIC without IPS, but with IPS this could lead to a race condition where we attempt to access DCN state while it's inaccessible, leading to a system hang when the NIU port is not disabled or register accesses that timeout and the display configuration in an undefined state.
[How] We need to investigate why these accesses take longer than expected, but for now we should disable the timeout on DCN35 to avoid this race condition. Since the waits happen only at lower interrupt levels the risk of taking too long at higher IRQ and causing a system watchdog timeout are minimal.
Reviewed-by: Ovidiu Bunea ovidiu.bunea@amd.com Acked-by: Zaeem Mohamed zaeem.mohamed@amd.com Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c index 28c4599076989..915d68cc04e9c 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c @@ -785,6 +785,7 @@ static const struct dc_debug_options debug_defaults_drv = { .ips2_entry_delay_us = 800, .disable_dmub_reallow_idle = false, .static_screen_wait_frames = 2, + .disable_timeout = true, };
static const struct dc_panel_config panel_config_defaults = {
From: Alex Hung alex.hung@amd.com
[ Upstream commit d6b54900c564e35989cf6813e4071504fa0a90e0 ]
[WHAT & HOW] dmub_rb_cmd's ramping_boundary has size of uint8_t and it is assigned 0xFFFF. Fix it by changing it to uint8_t with value of 0xFF.
This fixes 2 INTEGER_OVERFLOW issues reported by Coverity.
Reviewed-by: Rodrigo Siqueira rodrigo.siqueira@amd.com Acked-by: Zaeem Mohamed zaeem.mohamed@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c | 2 +- drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c index b851fc65f5b7c..5c2d6642633d9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c @@ -258,7 +258,7 @@ bool dmub_abm_set_pipe(struct abm *abm, { union dmub_rb_cmd cmd; struct dc_context *dc = abm->ctx; - uint32_t ramping_boundary = 0xFFFF; + uint8_t ramping_boundary = 0xFF;
memset(&cmd, 0, sizeof(cmd)); cmd.abm_set_pipe.header.type = DMUB_CMD__ABM; diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c index 804be977ea47b..3de65a9f0e6f2 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c @@ -142,7 +142,7 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, { union dmub_rb_cmd cmd; struct dc_context *dc = abm->ctx; - uint32_t ramping_boundary = 0xFFFF; + uint8_t ramping_boundary = 0xFF;
memset(&cmd, 0, sizeof(cmd)); cmd.abm_set_pipe.header.type = DMUB_CMD__ABM;
From: Alex Hung alex.hung@amd.com
[ Upstream commit 8b0ddf19cca2a352b2a7e01d99d3ba949a99c84c ]
BIOS images may fail to load and null checks are added before they are used.
This fixes 6 NULL_RETURNS issues reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Hamza Mahfooz hamza.mahfooz@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/bios/bios_parser.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c index 25fe1a1240298..3bacf470f7c5b 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c @@ -665,6 +665,9 @@ static enum bp_result get_ss_info_v3_1( ss_table_header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base, DATA_TABLES(ASIC_InternalSS_Info), struct_size(ss_table_header_include, asSpreadSpectrum, 1))); + if (!ss_table_header_include) + return BP_RESULT_UNSUPPORTED; + table_size = (le16_to_cpu(ss_table_header_include->sHeader.usStructureSize) - sizeof(ATOM_COMMON_TABLE_HEADER)) @@ -1034,6 +1037,8 @@ static enum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1( &bp->base, DATA_TABLES(ASIC_InternalSS_Info), struct_size(header, asSpreadSpectrum, 1))); + if (!header) + return result;
memset(info, 0, sizeof(struct spread_spectrum_info));
@@ -1107,6 +1112,8 @@ static enum bp_result get_ss_info_from_ss_info_table( get_atom_data_table_revision(header, &revision);
tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, DATA_TABLES(SS_Info)); + if (!tbl) + return result;
if (1 != revision.major || 2 > revision.minor) return result; @@ -1634,6 +1641,8 @@ static uint32_t get_ss_entry_number_from_ss_info_tbl(
tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, DATA_TABLES(SS_Info)); + if (!tbl) + return number;
if (1 != revision.major || 2 > revision.minor) return number; @@ -1716,6 +1725,8 @@ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_v2_1( &bp->base, DATA_TABLES(ASIC_InternalSS_Info), struct_size(header_include, asSpreadSpectrum, 1))); + if (!header_include) + return 0;
size = (le16_to_cpu(header_include->sHeader.usStructureSize) - sizeof(ATOM_COMMON_TABLE_HEADER)) @@ -1755,6 +1766,9 @@ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_V3_1( header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base, DATA_TABLES(ASIC_InternalSS_Info), struct_size(header_include, asSpreadSpectrum, 1))); + if (!header_include) + return number; + size = (le16_to_cpu(header_include->sHeader.usStructureSize) - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3);
From: Alex Hung alex.hung@amd.com
[ Upstream commit c4d31653c03b90e51515b1380115d1aedad925dd ]
Callers can pass null in filter (i.e. from returned from the function wbscl_get_filter_coeffs_16p) and a null check is added to ensure that is not the case.
This fixes 4 NULL_RETURNS issues reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Hamza Mahfooz hamza.mahfooz@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c index 994fb732a7cb7..a0d437f0ce2ba 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c @@ -690,6 +690,9 @@ static void wbscl_set_scaler_filter( int pair; uint16_t odd_coef, even_coef;
+ if (!filter) + return; + for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) { for (pair = 0; pair < tap_pairs; pair++) { even_coef = filter[phase * taps + 2 * pair];
From: Jens Axboe axboe@r7625.kernel.dk
[ Upstream commit 3474d1b93f897ab33ce160e759afd47d5f412de4 ]
The work flags can be set/accessed from different tasks, both the originator of the request, and the io-wq workers. While modifications aren't concurrent, it still makes KMSAN unhappy. There's no real downside to just making the flag reading/manipulation use proper atomics here.
Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/io_uring_types.h | 2 +- io_uring/io-wq.c | 19 ++++++++++--------- io_uring/io-wq.h | 2 +- io_uring/io_uring.c | 12 ++++++------ 4 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h index 7abdc09271245..abf5c6622af6d 100644 --- a/include/linux/io_uring_types.h +++ b/include/linux/io_uring_types.h @@ -50,7 +50,7 @@ struct io_wq_work_list {
struct io_wq_work { struct io_wq_work_node list; - unsigned flags; + atomic_t flags; /* place it here instead of io_kiocb as it fills padding and saves 4B */ int cancel_seq; }; diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c index 7d3316fe9bfc4..913c92249522e 100644 --- a/io_uring/io-wq.c +++ b/io_uring/io-wq.c @@ -159,7 +159,7 @@ static inline struct io_wq_acct *io_get_acct(struct io_wq *wq, bool bound) static inline struct io_wq_acct *io_work_get_acct(struct io_wq *wq, struct io_wq_work *work) { - return io_get_acct(wq, !(work->flags & IO_WQ_WORK_UNBOUND)); + return io_get_acct(wq, !(atomic_read(&work->flags) & IO_WQ_WORK_UNBOUND)); }
static inline struct io_wq_acct *io_wq_get_acct(struct io_worker *worker) @@ -451,7 +451,7 @@ static void __io_worker_idle(struct io_wq *wq, struct io_worker *worker)
static inline unsigned int io_get_work_hash(struct io_wq_work *work) { - return work->flags >> IO_WQ_HASH_SHIFT; + return atomic_read(&work->flags) >> IO_WQ_HASH_SHIFT; }
static bool io_wait_on_hash(struct io_wq *wq, unsigned int hash) @@ -592,8 +592,9 @@ static void io_worker_handle_work(struct io_wq_acct *acct,
next_hashed = wq_next_work(work);
- if (unlikely(do_kill) && (work->flags & IO_WQ_WORK_UNBOUND)) - work->flags |= IO_WQ_WORK_CANCEL; + if (do_kill && + (atomic_read(&work->flags) & IO_WQ_WORK_UNBOUND)) + atomic_or(IO_WQ_WORK_CANCEL, &work->flags); wq->do_work(work); io_assign_current_work(worker, NULL);
@@ -891,7 +892,7 @@ static bool io_wq_worker_wake(struct io_worker *worker, void *data) static void io_run_cancel(struct io_wq_work *work, struct io_wq *wq) { do { - work->flags |= IO_WQ_WORK_CANCEL; + atomic_or(IO_WQ_WORK_CANCEL, &work->flags); wq->do_work(work); work = wq->free_work(work); } while (work); @@ -926,7 +927,7 @@ static bool io_wq_work_match_item(struct io_wq_work *work, void *data) void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work) { struct io_wq_acct *acct = io_work_get_acct(wq, work); - unsigned long work_flags = work->flags; + unsigned int work_flags = atomic_read(&work->flags); struct io_cb_cancel_data match = { .fn = io_wq_work_match_item, .data = work, @@ -939,7 +940,7 @@ void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work) * been marked as one that should not get executed, cancel it here. */ if (test_bit(IO_WQ_BIT_EXIT, &wq->state) || - (work->flags & IO_WQ_WORK_CANCEL)) { + (work_flags & IO_WQ_WORK_CANCEL)) { io_run_cancel(work, wq); return; } @@ -982,7 +983,7 @@ void io_wq_hash_work(struct io_wq_work *work, void *val) unsigned int bit;
bit = hash_ptr(val, IO_WQ_HASH_ORDER); - work->flags |= (IO_WQ_WORK_HASHED | (bit << IO_WQ_HASH_SHIFT)); + atomic_or(IO_WQ_WORK_HASHED | (bit << IO_WQ_HASH_SHIFT), &work->flags); }
static bool __io_wq_worker_cancel(struct io_worker *worker, @@ -990,7 +991,7 @@ static bool __io_wq_worker_cancel(struct io_worker *worker, struct io_wq_work *work) { if (work && match->fn(work, match->data)) { - work->flags |= IO_WQ_WORK_CANCEL; + atomic_or(IO_WQ_WORK_CANCEL, &work->flags); __set_notify_signal(worker->task); return true; } diff --git a/io_uring/io-wq.h b/io_uring/io-wq.h index 2b2a6406dd8ee..b3b004a7b6252 100644 --- a/io_uring/io-wq.h +++ b/io_uring/io-wq.h @@ -56,7 +56,7 @@ bool io_wq_worker_stopped(void);
static inline bool io_wq_is_hashed(struct io_wq_work *work) { - return work->flags & IO_WQ_WORK_HASHED; + return atomic_read(&work->flags) & IO_WQ_WORK_HASHED; }
typedef bool (work_cancel_fn)(struct io_wq_work *, void *); diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index c326e2127dd4d..846c1cecdb0aa 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -461,9 +461,9 @@ static void io_prep_async_work(struct io_kiocb *req) }
req->work.list.next = NULL; - req->work.flags = 0; + atomic_set(&req->work.flags, 0); if (req->flags & REQ_F_FORCE_ASYNC) - req->work.flags |= IO_WQ_WORK_CONCURRENT; + atomic_or(IO_WQ_WORK_CONCURRENT, &req->work.flags);
if (req->file && !(req->flags & REQ_F_FIXED_FILE)) req->flags |= io_file_get_flags(req->file); @@ -479,7 +479,7 @@ static void io_prep_async_work(struct io_kiocb *req) io_wq_hash_work(&req->work, file_inode(req->file)); } else if (!req->file || !S_ISBLK(file_inode(req->file)->i_mode)) { if (def->unbound_nonreg_file) - req->work.flags |= IO_WQ_WORK_UNBOUND; + atomic_or(IO_WQ_WORK_UNBOUND, &req->work.flags); } }
@@ -519,7 +519,7 @@ static void io_queue_iowq(struct io_kiocb *req) * worker for it). */ if (WARN_ON_ONCE(!same_thread_group(req->task, current))) - req->work.flags |= IO_WQ_WORK_CANCEL; + atomic_or(IO_WQ_WORK_CANCEL, &req->work.flags);
trace_io_uring_queue_async_work(req, io_wq_is_hashed(&req->work)); io_wq_enqueue(tctx->io_wq, &req->work); @@ -1813,14 +1813,14 @@ void io_wq_submit_work(struct io_wq_work *work) io_arm_ltimeout(req);
/* either cancelled or io-wq is dying, so don't touch tctx->iowq */ - if (work->flags & IO_WQ_WORK_CANCEL) { + if (atomic_read(&work->flags) & IO_WQ_WORK_CANCEL) { fail: io_req_task_queue_fail(req, err); return; } if (!io_assign_file(req, def, issue_flags)) { err = -EBADF; - work->flags |= IO_WQ_WORK_CANCEL; + atomic_or(IO_WQ_WORK_CANCEL, &work->flags); goto fail; }
From: Willem de Bruijn willemb@google.com
[ Upstream commit dd89a81d850fa9a65f67b4527c0e420d15bf836c ]
Drop the WARN_ON_ONCE inn gue_gro_receive if the encapsulated type is not known or does not have a GRO handler.
Such a packet is easily constructed. Syzbot generates them and sets off this warning.
Remove the warning as it is expected and not actionable.
The warning was previously reduced from WARN_ON to WARN_ON_ONCE in commit 270136613bf7 ("fou: Do WARN_ON_ONCE in gue_gro_receive for bad proto callbacks").
Signed-off-by: Willem de Bruijn willemb@google.com Reviewed-by: Eric Dumazet edumazet@google.com Link: https://lore.kernel.org/r/20240614122552.1649044-1-willemdebruijn.kernel@gma... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/fou_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c index a8494f796dca3..0abbc413e0fe5 100644 --- a/net/ipv4/fou_core.c +++ b/net/ipv4/fou_core.c @@ -433,7 +433,7 @@ static struct sk_buff *gue_gro_receive(struct sock *sk,
offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; ops = rcu_dereference(offloads[proto]); - if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive)) + if (!ops || !ops->callbacks.gro_receive) goto out;
pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 10457f5042b4890a667e2f15a2e783490dda44d2 ]
So far the vmaster code has been tolerant about the input values and accepts any values by correcting internally. But now our own selftest starts complaining about this behavior, so let's be picky and change the behavior to return -EINVAL for invalid input values instead.
Reported-by: Paul Menzel pmenzel@molgen.mpg.de Closes: https://lore.kernel.org/r/1d44be36-9bb9-4d82-8953-5ae2a4f09405@molgen.mpg.de Reviewed-by: Jaroslav Kysela perex@perex.cz Signed-off-by: Takashi Iwai tiwai@suse.de Link: https://lore.kernel.org/20240616073454.16512-2-tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/core/vmaster.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index 04a57f7be6ea4..c657659b236c4 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c @@ -198,6 +198,12 @@ static int follower_put(struct snd_kcontrol *kcontrol, err = follower_init(follower); if (err < 0) return err; + for (ch = 0; ch < follower->info.count; ch++) { + if (ucontrol->value.integer.value[ch] < follower->info.min_val || + ucontrol->value.integer.value[ch] > follower->info.max_val) + return -EINVAL; + } + for (ch = 0; ch < follower->info.count; ch++) { if (follower->vals[ch] != ucontrol->value.integer.value[ch]) { changed = 1; @@ -365,6 +371,8 @@ static int master_put(struct snd_kcontrol *kcontrol, new_val = ucontrol->value.integer.value[0]; if (new_val == old_val) return 0; + if (new_val < master->info.min_val || new_val > master->info.max_val) + return -EINVAL;
err = sync_followers(master, old_val, new_val); if (err < 0)
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 50ed081284fe2bfd1f25e8b92f4f6a4990e73c0a ]
Although we have already a mechanism for sanity checks of input values for control writes, it's not applied unless the kconfig CONFIG_SND_CTL_INPUT_VALIDATION is set due to the performance reason. Nevertheless, it still makes sense to apply the same check for user elements despite of its cost, as that's the only way to filter out the invalid values; the user controls are handled solely in ALSA core code, and there is no corresponding driver, after all.
This patch adds the same input value validation for user control elements at its put callback. The kselftest will be happier with this change, as the incorrect values will be bailed out now with errors.
For other normal controls, the check is applied still only when CONFIG_SND_CTL_INPUT_VALIDATION is set.
Reported-by: Paul Menzel pmenzel@molgen.mpg.de Closes: https://lore.kernel.org/r/1d44be36-9bb9-4d82-8953-5ae2a4f09405@molgen.mpg.de Reviewed-by: Jaroslav Kysela perex@perex.cz Reviewed-by: Mark Brown broonie@kernel.org Reviewed-by: Takashi Sakamoto o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai tiwai@suse.de Link: https://lore.kernel.org/20240616073454.16512-4-tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/core/control.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sound/core/control.c b/sound/core/control.c index fb0c60044f7b3..1dd2337e29300 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -1480,12 +1480,16 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - int change; + int err, change; struct user_element *ue = kcontrol->private_data; unsigned int size = ue->elem_data_size; char *dst = ue->elem_data + snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
+ err = sanity_check_input_values(ue->card, ucontrol, &ue->info, false); + if (err < 0) + return err; + change = memcmp(&ucontrol->value, dst, size) != 0; if (change) memcpy(dst, &ucontrol->value, size);
From: Aaradhana Sahu quic_aarasahu@quicinc.com
[ Upstream commit 19b77e7c656a3e125319cc3ef347b397cf042bf6 ]
Smatch throws following errors
drivers/net/wireless/ath/ath12k/mac.c:1922 ath12k_peer_assoc_h_he() error: uninitialized symbol 'rx_mcs_80'. drivers/net/wireless/ath/ath12k/mac.c:1922 ath12k_peer_assoc_h_he() error: uninitialized symbol 'rx_mcs_160'. drivers/net/wireless/ath/ath12k/mac.c:1924 ath12k_peer_assoc_h_he() error: uninitialized symbol 'rx_mcs_80'.
In ath12k_peer_assoc_h_he() rx_mcs_80 and rx_mcs_160 variables remain uninitialized in the following conditions: 1. Whenever the value of mcs_80 become equal to IEEE80211_HE_MCS_NOT_SUPPORTED then rx_mcs_80 remains uninitialized. 2. Whenever phy capability is not supported 160 channel width and value of mcs_160 become equal to IEEE80211_HE_MCS_NOT_SUPPORTED then rx_mcs_160 remains uninitialized.
Initialize these variables during declaration.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.1.1-00188-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aaradhana Sahu quic_aarasahu@quicinc.com Acked-by: Jeff Johnson quic_jjohnson@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://patch.msgid.link/20240611031017.297927-3-quic_aarasahu@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath12k/mac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 805cb084484a4..678a08ab22f03 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1881,7 +1881,9 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar, { const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap; int i; - u8 ampdu_factor, rx_mcs_80, rx_mcs_160, max_nss; + u8 ampdu_factor, max_nss; + u8 rx_mcs_80 = IEEE80211_HE_MCS_NOT_SUPPORTED; + u8 rx_mcs_160 = IEEE80211_HE_MCS_NOT_SUPPORTED; u16 mcs_160_map, mcs_80_map; bool support_160; u16 v;
From: Ajith C quic_ajithc@quicinc.com
[ Upstream commit db163a463bb93cd3e37e1e7b10b9726fb6f95857 ]
Currently, if the access point receives an association request containing an Extended HE Capabilities Information Element with an invalid MCS-NSS, it triggers a firmware crash.
This issue arises when EHT-PHY capabilities shows support for a bandwidth and MCS-NSS set for that particular bandwidth is filled by zeros and due to this, driver obtains peer_nss as 0 and sending this value to firmware causes crash.
Address this issue by implementing a validation step for the peer_nss value before passing it to the firmware. If the value is greater than zero, proceed with forwarding it to the firmware. However, if the value is invalid, reject the association request to prevent potential firmware crashes.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Ajith C quic_ajithc@quicinc.com Acked-by: Jeff Johnson quic_jjohnson@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://patch.msgid.link/20240613053528.2541645-1-quic_ajithc@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath12k/mac.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 678a08ab22f03..f328b650059ad 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -3847,6 +3847,11 @@ static int ath12k_station_assoc(struct ath12k *ar,
ath12k_peer_assoc_prepare(ar, vif, sta, &peer_arg, reassoc);
+ if (peer_arg.peer_nss < 1) { + ath12k_warn(ar->ab, + "invalid peer NSS %d\n", peer_arg.peer_nss); + return -EINVAL; + } ret = ath12k_wmi_send_peer_assoc_cmd(ar, &peer_arg); if (ret) { ath12k_warn(ar->ab, "failed to run peer assoc for STA %pM vdev %i: %d\n",
From: Alex Hung alex.hung@amd.com
[ Upstream commit a7b38c7852093385d0605aa3c8a2efd6edd1edfd ]
CalculateSwathAndDETConfiguration_params_st's UnboundedRequestEnabled is a pointer (i.e. dml_bool_t *UnboundedRequestEnabled), and thus if (p->UnboundedRequestEnabled) checks its address, not bool value.
This fixes 1 REVERSE_INULL issue reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Acked-by: Hamza Mahfooz hamza.mahfooz@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c index 3e919f5c00ca2..fee1df342f122 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c @@ -4282,7 +4282,7 @@ static void CalculateSwathAndDETConfiguration(struct display_mode_lib_scratch_st }
*p->compbuf_reserved_space_64b = 2 * p->PixelChunkSizeInKByte * 1024 / 64; - if (p->UnboundedRequestEnabled) { + if (*p->UnboundedRequestEnabled) { *p->compbuf_reserved_space_64b = dml_max(*p->compbuf_reserved_space_64b, (dml_float_t)(p->ROBBufferSizeInKByte * 1024/64) - (dml_float_t)(RoundedUpSwathSizeBytesY[SurfaceDoingUnboundedRequest] * TTUFIFODEPTH / MAXIMUMCOMPRESSION/64));
From: Kees Cook keescook@chromium.org
[ Upstream commit d6f635bcaca8d38dfa47ee20658705f9eff156b5 ]
Since FineIBT performs checking at the destination, it is weaker against attacks that can construct arbitrary executable memory contents. As such, some system builders want to run with FineIBT disabled by default. Allow the "cfi=kcfi" boot param mode to be selectable through Kconfig via the newly introduced CONFIG_CFI_AUTO_DEFAULT.
Reviewed-by: Sami Tolvanen samitolvanen@google.com Reviewed-by: Nathan Chancellor nathan@kernel.org Tested-by: Nathan Chancellor nathan@kernel.org Link: https://lore.kernel.org/r/20240501000218.work.998-kees@kernel.org Signed-off-by: Kees Cook kees@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/Kconfig | 9 +++++++++ arch/x86/include/asm/cfi.h | 2 +- arch/x86/kernel/alternative.c | 8 ++++---- 3 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 1d7122a1883e8..56e301921d2a1 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2427,6 +2427,15 @@ config STRICT_SIGALTSTACK_SIZE
Say 'N' unless you want to really enforce this check.
+config CFI_AUTO_DEFAULT + bool "Attempt to use FineIBT by default at boot time" + depends on FINEIBT + default y + help + Attempt to use FineIBT by default at boot time. If enabled, + this is the same as booting with "cfi=auto". If disabled, + this is the same as booting with "cfi=kcfi". + source "kernel/livepatch/Kconfig"
endmenu diff --git a/arch/x86/include/asm/cfi.h b/arch/x86/include/asm/cfi.h index 7cd7525579051..31d19c815f992 100644 --- a/arch/x86/include/asm/cfi.h +++ b/arch/x86/include/asm/cfi.h @@ -93,7 +93,7 @@ * */ enum cfi_mode { - CFI_DEFAULT, /* FineIBT if hardware has IBT, otherwise kCFI */ + CFI_AUTO, /* FineIBT if hardware has IBT, otherwise kCFI */ CFI_OFF, /* Taditional / IBT depending on .config */ CFI_KCFI, /* Optionally CALL_PADDING, IBT, RETPOLINE */ CFI_FINEIBT, /* see arch/x86/kernel/alternative.c */ diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 89de612432728..7fcba437abaee 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -885,8 +885,8 @@ void __init_or_module apply_seal_endbr(s32 *start, s32 *end) { }
#endif /* CONFIG_X86_KERNEL_IBT */
-#ifdef CONFIG_FINEIBT -#define __CFI_DEFAULT CFI_DEFAULT +#ifdef CONFIG_CFI_AUTO_DEFAULT +#define __CFI_DEFAULT CFI_AUTO #elif defined(CONFIG_CFI_CLANG) #define __CFI_DEFAULT CFI_KCFI #else @@ -994,7 +994,7 @@ static __init int cfi_parse_cmdline(char *str) }
if (!strcmp(str, "auto")) { - cfi_mode = CFI_DEFAULT; + cfi_mode = CFI_AUTO; } else if (!strcmp(str, "off")) { cfi_mode = CFI_OFF; cfi_rand = false; @@ -1254,7 +1254,7 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline, "FineIBT preamble wrong size: %ld", fineibt_preamble_size)) return;
- if (cfi_mode == CFI_DEFAULT) { + if (cfi_mode == CFI_AUTO) { cfi_mode = CFI_KCFI; if (HAS_KERNEL_IBT && cpu_feature_enabled(X86_FEATURE_IBT)) cfi_mode = CFI_FINEIBT;
From: Alexey Dobriyan adobriyan@gmail.com
[ Upstream commit 2a97388a807b6ab5538aa8f8537b2463c6988bd2 ]
ELF loader uses "randomize_va_space" twice. It is sysctl and can change at any moment, so 2 loads could see 2 different values in theory with unpredictable consequences.
Issue exactly one load for consistent value across one exec.
Signed-off-by: Alexey Dobriyan adobriyan@gmail.com Link: https://lore.kernel.org/r/3329905c-7eb8-400a-8f0a-d87cff979b5b@p183 Signed-off-by: Kees Cook kees@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/binfmt_elf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index a43897b03ce94..777405719de85 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1003,7 +1003,8 @@ static int load_elf_binary(struct linux_binprm *bprm) if (elf_read_implies_exec(*elf_ex, executable_stack)) current->personality |= READ_IMPLIES_EXEC;
- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) + const int snapshot_randomize_va_space = READ_ONCE(randomize_va_space); + if (!(current->personality & ADDR_NO_RANDOMIZE) && snapshot_randomize_va_space) current->flags |= PF_RANDOMIZE;
setup_new_exec(bprm); @@ -1251,7 +1252,7 @@ static int load_elf_binary(struct linux_binprm *bprm) mm->end_data = end_data; mm->start_stack = bprm->p;
- if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) { + if ((current->flags & PF_RANDOMIZE) && (snapshot_randomize_va_space > 1)) { /* * For architectures with ELF randomization, when executing * a loader directly (i.e. no interpreter listed in ELF
From: Rakesh Ughreja rughreja@habana.ai
[ Upstream commit 3309887c6ff8ca2ac05a74e1ee5d1c44829f63f2 ]
Netowrk EDMAs uses more outstanding transfers so this needs to be programmed by EDMA firmware.
Signed-off-by: Rakesh Ughreja rughreja@habana.ai Reviewed-by: Ofir Bitton obitton@habana.ai Signed-off-by: Ofir Bitton obitton@habana.ai Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/accel/habanalabs/gaudi2/gaudi2_security.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/accel/habanalabs/gaudi2/gaudi2_security.c b/drivers/accel/habanalabs/gaudi2/gaudi2_security.c index 34bf80c5a44bf..307ccb912ccd6 100644 --- a/drivers/accel/habanalabs/gaudi2/gaudi2_security.c +++ b/drivers/accel/habanalabs/gaudi2/gaudi2_security.c @@ -479,6 +479,7 @@ static const u32 gaudi2_pb_dcr0_edma0_unsecured_regs[] = { mmDCORE0_EDMA0_CORE_CTX_TE_NUMROWS, mmDCORE0_EDMA0_CORE_CTX_IDX, mmDCORE0_EDMA0_CORE_CTX_IDX_INC, + mmDCORE0_EDMA0_CORE_WR_COMP_MAX_OUTSTAND, mmDCORE0_EDMA0_CORE_RD_LBW_RATE_LIM_CFG, mmDCORE0_EDMA0_QM_CQ_CFG0_0, mmDCORE0_EDMA0_QM_CQ_CFG0_1,
From: Brian Johannesmeyer bjohannesmeyer@gmail.com
[ Upstream commit bf6ab33d8487f5e2a0998ce75286eae65bb0a6d6 ]
When called with a 'from' that is not 4-byte-aligned, string_memcpy_fromio() calls the movs() macro to copy the first few bytes, so that 'from' becomes 4-byte-aligned before calling rep_movs(). This movs() macro modifies 'to', and the subsequent line modifies 'n'.
As a result, on unaligned accesses, kmsan_unpoison_memory() uses the updated (aligned) values of 'to' and 'n'. Hence, it does not unpoison the entire region.
Save the original values of 'to' and 'n', and pass those to kmsan_unpoison_memory(), so that the entire region is unpoisoned.
Signed-off-by: Brian Johannesmeyer bjohannesmeyer@gmail.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Reviewed-by: Alexander Potapenko glider@google.com Link: https://lore.kernel.org/r/20240523215029.4160518-1-bjohannesmeyer@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/lib/iomem.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/x86/lib/iomem.c b/arch/x86/lib/iomem.c index e0411a3774d49..5eecb45d05d5d 100644 --- a/arch/x86/lib/iomem.c +++ b/arch/x86/lib/iomem.c @@ -25,6 +25,9 @@ static __always_inline void rep_movs(void *to, const void *from, size_t n)
static void string_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n) { + const void *orig_to = to; + const size_t orig_n = n; + if (unlikely(!n)) return;
@@ -39,7 +42,7 @@ static void string_memcpy_fromio(void *to, const volatile void __iomem *from, si } rep_movs(to, (const void *)from, n); /* KMSAN must treat values read from devices as initialized. */ - kmsan_unpoison_memory(to, n); + kmsan_unpoison_memory(orig_to, orig_n); }
static void string_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
From: Andre Przywara andre.przywara@arm.com
[ Upstream commit 7b9331a3ae93adfae54c6a56d23513e1f7db5dcb ]
The Allwinner IOMMU is a strict 32-bit device, with its input addresses, the page table root pointer as well as both level's page tables and also the target addresses all required to be below 4GB. The Allwinner H6 SoC only supports 32-bit worth of physical addresses anyway, so this isn't a problem so far, but the H616 and later SoCs extend the PA space beyond 32 bit to accommodate more DRAM. To make sure we stay within the 32-bit PA range required by the IOMMU, force the memory for the page tables to come from below 4GB. by using allocations with the DMA32 flag. Also reject any attempt to map target addresses beyond 4GB, and print a warning to give users a hint while this fails.
Signed-off-by: Andre Przywara andre.przywara@arm.com Reviewed-by: Chen-Yu Tsai wens@csie.org Link: https://lore.kernel.org/r/20240616224056.29159-3-andre.przywara@arm.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/sun50i-iommu.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c index c519b991749d7..b5221579c9815 100644 --- a/drivers/iommu/sun50i-iommu.c +++ b/drivers/iommu/sun50i-iommu.c @@ -601,6 +601,14 @@ static int sun50i_iommu_map(struct iommu_domain *domain, unsigned long iova, u32 *page_table, *pte_addr; int ret = 0;
+ /* the IOMMU can only handle 32-bit addresses, both input and output */ + if ((uint64_t)paddr >> 32) { + ret = -EINVAL; + dev_warn_once(iommu->dev, + "attempt to map address beyond 4GB\n"); + goto out; + } + page_table = sun50i_dte_get_page_table(sun50i_domain, iova, gfp); if (IS_ERR(page_table)) { ret = PTR_ERR(page_table); @@ -681,7 +689,8 @@ sun50i_iommu_domain_alloc_paging(struct device *dev) if (!sun50i_domain) return NULL;
- sun50i_domain->dt = iommu_alloc_pages(GFP_KERNEL, get_order(DT_SIZE)); + sun50i_domain->dt = iommu_alloc_pages(GFP_KERNEL | GFP_DMA32, + get_order(DT_SIZE)); if (!sun50i_domain->dt) goto err_free_domain;
@@ -996,7 +1005,7 @@ static int sun50i_iommu_probe(struct platform_device *pdev)
iommu->pt_pool = kmem_cache_create(dev_name(&pdev->dev), PT_SIZE, PT_SIZE, - SLAB_HWCACHE_ALIGN, + SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA32, NULL); if (!iommu->pt_pool) return -ENOMEM;
From: Jan Kara jack@suse.cz
[ Upstream commit ebbe26fd54a9621994bc16b14f2ba8f84c089693 ]
Avoid mounting filesystems where the partition would overflow the 32-bits used for block number. Also refuse to mount filesystems where the partition length is so large we cannot safely index bits in a block bitmap.
Link: https://patch.msgid.link/20240620130403.14731-1-jack@suse.cz Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- fs/udf/super.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/fs/udf/super.c b/fs/udf/super.c index 9381a66c6ce58..8411db883cbce 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1110,12 +1110,19 @@ static int udf_fill_partdesc_info(struct super_block *sb, struct udf_part_map *map; struct udf_sb_info *sbi = UDF_SB(sb); struct partitionHeaderDesc *phd; + u32 sum; int err;
map = &sbi->s_partmaps[p_index];
map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */ map->s_partition_root = le32_to_cpu(p->partitionStartingLocation); + if (check_add_overflow(map->s_partition_root, map->s_partition_len, + &sum)) { + udf_err(sb, "Partition %d has invalid location %u + %u\n", + p_index, map->s_partition_root, map->s_partition_len); + return -EFSCORRUPTED; + }
if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY)) map->s_partition_flags |= UDF_PART_FLAG_READ_ONLY; @@ -1171,6 +1178,14 @@ static int udf_fill_partdesc_info(struct super_block *sb, bitmap->s_extPosition = le32_to_cpu( phd->unallocSpaceBitmap.extPosition); map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; + /* Check whether math over bitmap won't overflow. */ + if (check_add_overflow(map->s_partition_len, + sizeof(struct spaceBitmapDesc) << 3, + &sum)) { + udf_err(sb, "Partition %d is too long (%u)\n", p_index, + map->s_partition_len); + return -EFSCORRUPTED; + } udf_debug("unallocSpaceBitmap (part %d) @ %u\n", p_index, bitmap->s_extPosition); }
From: Björn Töpel bjorn@rivosinc.com
[ Upstream commit 37992b7f1097ba79ca75ba5a26ddcf0f54f91a08 ]
During memory hot remove, the ptdump functionality can end up touching stale data. Avoid any potential crashes (or worse), by holding the memory hotplug read-lock while traversing the page table.
This change is analogous to arm64's commit bf2b59f60ee1 ("arm64/mm: Hold memory hotplug lock while walking for kernel page table dump").
Reviewed-by: David Hildenbrand david@redhat.com Reviewed-by: Oscar Salvador osalvador@suse.de Signed-off-by: Björn Töpel bjorn@rivosinc.com Link: https://lore.kernel.org/r/20240605114100.315918-8-bjorn@kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/mm/ptdump.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c index 1289cc6d3700c..9d5f657a251b3 100644 --- a/arch/riscv/mm/ptdump.c +++ b/arch/riscv/mm/ptdump.c @@ -6,6 +6,7 @@ #include <linux/efi.h> #include <linux/init.h> #include <linux/debugfs.h> +#include <linux/memory_hotplug.h> #include <linux/seq_file.h> #include <linux/ptdump.h>
@@ -370,7 +371,9 @@ bool ptdump_check_wx(void)
static int ptdump_show(struct seq_file *m, void *v) { + get_online_mems(); ptdump_walk(m, m->private); + put_online_mems();
return 0; }
From: Shantanu Goel sgoel01@yahoo.com
[ Upstream commit 9d32685a251a754f1823d287df233716aa23bcb9 ]
Set the host status byte when a data completion error is encountered otherwise the upper layer may end up using the invalid zero'ed data. The following output was observed from scsi/sd.c prior to this fix.
[ 11.872824] sd 0:0:0:1: [sdf] tag#9 data cmplt err -75 uas-tag 1 inflight: [ 11.872826] sd 0:0:0:1: [sdf] tag#9 CDB: Read capacity(16) 9e 10 00 00 00 00 00 00 00 00 00 00 00 20 00 00 [ 11.872830] sd 0:0:0:1: [sdf] Sector size 0 reported, assuming 512.
Signed-off-by: Shantanu Goel sgoel01@yahoo.com Acked-by: Oliver Neukum oneukum@suse.com Link: https://lore.kernel.org/r/87msnx4ec6.fsf@yahoo.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/storage/uas.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index b610a2de4ae5d..a04b4cb1382d5 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -423,6 +423,7 @@ static void uas_data_cmplt(struct urb *urb) uas_log_cmd_state(cmnd, "data cmplt err", status); /* error: no data transfered */ scsi_set_resid(cmnd, sdb->length); + set_host_byte(cmnd, DID_ERROR); } else { scsi_set_resid(cmnd, sdb->length - urb->actual_length); }
From: Hawking Zhang Hawking.Zhang@amd.com
[ Upstream commit 9da0f7736763aa0fbf63bb15060c6827135f3f67 ]
fault_status is read only register. fault_cntl is not accessible from guest environment.
Signed-off-by: Hawking Zhang Hawking.Zhang@amd.com Reviewed-by: Tao Zhou tao.zhou1@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c | 8 +++++--- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 3 ++- drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c | 8 +++++--- 3 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c index 77df8c9cbad2f..9e10e552952e1 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c @@ -627,9 +627,11 @@ static bool gfxhub_v1_2_query_utcl2_poison_status(struct amdgpu_device *adev,
status = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regVM_L2_PROTECTION_FAULT_STATUS); fed = REG_GET_FIELD(status, VM_L2_PROTECTION_FAULT_STATUS, FED); - /* reset page fault status */ - WREG32_P(SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), - regVM_L2_PROTECTION_FAULT_STATUS), 1, ~1); + if (!amdgpu_sriov_vf(adev)) { + /* clear page fault status and address */ + WREG32_P(SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), + regVM_L2_PROTECTION_FAULT_CNTL), 1, ~1); + }
return fed; } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index c4ec1358f3aa6..67f36a79c6f41 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -671,7 +671,8 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 4, 2))) return 0;
- WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1); + if (!amdgpu_sriov_vf(adev)) + WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1);
amdgpu_vm_update_fault_cache(adev, entry->pasid, addr, status, vmhub);
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c index 7a1ff298417ab..8d7267a013d24 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c @@ -566,9 +566,11 @@ static bool mmhub_v1_8_query_utcl2_poison_status(struct amdgpu_device *adev,
status = RREG32_SOC15(MMHUB, hub_inst, regVM_L2_PROTECTION_FAULT_STATUS); fed = REG_GET_FIELD(status, VM_L2_PROTECTION_FAULT_STATUS, FED); - /* reset page fault status */ - WREG32_P(SOC15_REG_OFFSET(MMHUB, hub_inst, - regVM_L2_PROTECTION_FAULT_STATUS), 1, ~1); + if (!amdgpu_sriov_vf(adev)) { + /* clear page fault status and address */ + WREG32_P(SOC15_REG_OFFSET(MMHUB, hub_inst, + regVM_L2_PROTECTION_FAULT_STATUS), 1, ~1); + }
return fed; }
From: Alex Hung alex.hung@amd.com
[ Upstream commit 3a82f62b0d9d7687eac47603bb6cd14a50fa718b ]
[WHAT] The DC_LOG_DC should be run after link->link_enc is checked, not before.
This fixes 1 REVERSE_INULL issue reported by Coverity.
Reviewed-by: Rodrigo Siqueira rodrigo.siqueira@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/link/link_factory.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index 2c3f5d6622851..c5486e6d89bd5 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -611,14 +611,14 @@ static bool construct_phy(struct dc_link *link, link->link_enc = link->dc->res_pool->funcs->link_enc_create(dc_ctx, &enc_init_data);
- DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C); - DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE); - if (!link->link_enc) { DC_ERROR("Failed to create link encoder!\n"); goto link_enc_create_fail; }
+ DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C); + DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE); + /* Update link encoder tracking variables. These are used for the dynamic * assignment of link encoders to streams. */
From: Alex Hung alex.hung@amd.com
[ Upstream commit 5d93060d430b359e16e7c555c8f151ead1ac614b ]
[WHAT & HOW] Check mod_hdcp_execute_and_set() return values in authenticated_dp.
This fixes 3 CHECKED_RETURN issues reported by Coverity.
Reviewed-by: Rodrigo Siqueira rodrigo.siqueira@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../amd/display/modules/hdcp/hdcp1_execution.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c index 182e7532dda8a..d77836cef5635 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c @@ -433,17 +433,20 @@ static enum mod_hdcp_status authenticated_dp(struct mod_hdcp *hdcp, }
if (status == MOD_HDCP_STATUS_SUCCESS) - mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, + if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, &input->bstatus_read, &status, - hdcp, "bstatus_read"); + hdcp, "bstatus_read")) + goto out; if (status == MOD_HDCP_STATUS_SUCCESS) - mod_hdcp_execute_and_set(check_link_integrity_dp, + if (!mod_hdcp_execute_and_set(check_link_integrity_dp, &input->link_integrity_check, &status, - hdcp, "link_integrity_check"); + hdcp, "link_integrity_check")) + goto out; if (status == MOD_HDCP_STATUS_SUCCESS) - mod_hdcp_execute_and_set(check_no_reauthentication_request_dp, + if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp, &input->reauth_request_check, &status, - hdcp, "reauth_request_check"); + hdcp, "reauth_request_check")) + goto out; out: return status; }
From: Alex Hung alex.hung@amd.com
[ Upstream commit 673f816b9e1e92d1f70e1bf5f21b531e0ff9ad6c ]
[WHAT & HOW] Function return values must be checked before data can be used in subsequent functions.
This fixes 4 CHECKED_RETURN issues reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 7 +++++-- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c | 3 ++- .../drm/amd/display/dc/link/protocols/link_dp_training.c | 3 +-- 3 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 2293a92df3bed..22d2ab8ce7f8b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -245,7 +245,9 @@ bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv *dc_dmub_srv, unsigned int coun if (status == DMUB_STATUS_POWER_STATE_D3) return false;
- dmub_srv_wait_for_idle(dmub, 100000); + status = dmub_srv_wait_for_idle(dmub, 100000); + if (status != DMUB_STATUS_OK) + return false;
/* Requeue the command. */ status = dmub_srv_cmd_queue(dmub, &cmd_list[i]); @@ -511,7 +513,8 @@ void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pi union dmub_rb_cmd cmd = { 0 }; unsigned int panel_inst = 0;
- dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, &panel_inst); + if (!dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, &panel_inst)) + return;
memset(&cmd, 0, sizeof(cmd));
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c index c6f859871d11e..7e4ca2022d649 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c @@ -595,7 +595,8 @@ static bool hubbub2_program_watermarks( hubbub1->base.ctx->dc->clk_mgr->clks.p_state_change_support == false) safe_to_lower = true;
- hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); + if (hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower)) + wm_pending = true;
REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0, DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index b8e704dbe9567..8c0dea6f75bf1 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -1659,8 +1659,7 @@ bool perform_link_training_with_retries( if (status == LINK_TRAINING_ABORT) { enum dc_connection_type type = dc_connection_none;
- link_detect_connection_type(link, &type); - if (type == dc_connection_none) { + if (link_detect_connection_type(link, &type) && type == dc_connection_none) { DC_LOG_HW_LINK_TRAINING("%s: Aborting training because sink unplugged\n", __func__); break; }
From: Bob Zhou bob.zhou@amd.com
[ Upstream commit 9ff2e14cf013fa887e269bdc5ea3cffacada8635 ]
Fix the unchecked return value warning reported by Coverity, so add error handling.
Signed-off-by: Bob Zhou bob.zhou@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 08b9dfb653355..1f02d282cfcd7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -720,7 +720,11 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid, ndw += kiq->pmf->invalidate_tlbs_size;
spin_lock(&adev->gfx.kiq[inst].ring_lock); - amdgpu_ring_alloc(ring, ndw); + r = amdgpu_ring_alloc(ring, ndw); + if (r) { + spin_unlock(&adev->gfx.kiq[inst].ring_lock); + goto error_unlock_reset; + } if (adev->gmc.flush_tlb_needs_extra_type_2) kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub);
From: Nathan Lynch nathanl@linux.ibm.com
[ Upstream commit 0974d03eb479384466d828d65637814bee6b26d7 ]
Smatch warns:
arch/powerpc/kernel/rtas.c:1932 __do_sys_rtas() warn: potential spectre issue 'args.args' [r] (local cap)
The 'nargs' and 'nret' locals come directly from a user-supplied buffer and are used as indexes into a small stack-based array and as inputs to copy_to_user() after they are subject to bounds checks.
Use array_index_nospec() after the bounds checks to clamp these values for speculative execution.
Signed-off-by: Nathan Lynch nathanl@linux.ibm.com Reported-by: Breno Leitao leitao@debian.org Reviewed-by: Breno Leitao leitao@debian.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20240530-sys_rtas-nargs-nret-v1-1-129acddd4d89@linux.ibm.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/rtas.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 8064d9c3de862..f7e86e09c49fa 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -19,6 +19,7 @@ #include <linux/lockdep.h> #include <linux/memblock.h> #include <linux/mutex.h> +#include <linux/nospec.h> #include <linux/of.h> #include <linux/of_fdt.h> #include <linux/reboot.h> @@ -1916,6 +1917,9 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs) || nargs + nret > ARRAY_SIZE(args.args)) return -EINVAL;
+ nargs = array_index_nospec(nargs, ARRAY_SIZE(args.args)); + nret = array_index_nospec(nret, ARRAY_SIZE(args.args) - nargs); + /* Copy in args. */ if (copy_from_user(args.args, uargs->args, nargs * sizeof(rtas_arg_t)) != 0)
From: Alex Hung alex.hung@amd.com
[ Upstream commit 116a678f3a9abc24f5c9d2525b7393d18d9eb58e ]
[WHAT & HOW] A denominator cannot be 0, and is checked before used.
This fixes 1 DIVIDE_BY_ZERO issue reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Signed-off-by: Jerry Zuo jerry.zuo@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
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 64fdce551e627..6c9a7089537af 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7344,7 +7344,7 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state, } }
- if (j == dc_state->stream_count) + if (j == dc_state->stream_count || pbn_div == 0) continue;
slot_num = DIV_ROUND_UP(pbn, pbn_div);
From: Alex Hung alex.hung@amd.com
[ Upstream commit ea79068d4073bf303f8203f2625af7d9185a1bc6 ]
[WHAT & HOW] A denominator cannot be 0, and is checked before used.
This fixes 2 DIVIDE_BY_ZERO issues reported by Coverity.
Reviewed-by: Harry Wentland harry.wentland@amd.com Signed-off-by: Jerry Zuo jerry.zuo@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c index 4ce0f4bf1d9bb..3329eaecfb15b 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c @@ -1756,7 +1756,7 @@ static int dcn315_populate_dml_pipes_from_context( bool split_required = pipe->stream->timing.pix_clk_100hz >= dcn_get_max_non_odm_pix_rate_100hz(&dc->dml.soc) || (pipe->plane_state && pipe->plane_state->src_rect.width > 5120);
- if (remaining_det_segs > MIN_RESERVED_DET_SEGS) + if (remaining_det_segs > MIN_RESERVED_DET_SEGS && crb_pipes != 0) pipes[pipe_cnt].pipe.src.det_size_override += (remaining_det_segs - MIN_RESERVED_DET_SEGS) / crb_pipes + (crb_idx < (remaining_det_segs - MIN_RESERVED_DET_SEGS) % crb_pipes ? 1 : 0); if (pipes[pipe_cnt].pipe.src.det_size_override > 2 * DCN3_15_MAX_DET_SEGS) {
From: Sean Anderson sean.anderson@linux.dev
[ Upstream commit d79c6840917097285e03a49f709321f5fb972750 ]
Take the phy mutex in xlate to protect against concurrent modification/access to gtr_phy. This does not typically cause any issues, since in most systems the phys are only xlated once and thereafter accessed with the phy API (which takes the locks). However, we are about to allow userspace to access phys for debugging, so it's important to avoid any data races.
Signed-off-by: Sean Anderson sean.anderson@linux.dev Link: https://lore.kernel.org/r/20240628205540.3098010-5-sean.anderson@linux.dev Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/xilinx/phy-zynqmp.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c index dc8319bda43d7..feaece2ed0d47 100644 --- a/drivers/phy/xilinx/phy-zynqmp.c +++ b/drivers/phy/xilinx/phy-zynqmp.c @@ -798,6 +798,7 @@ static struct phy *xpsgtr_xlate(struct device *dev, phy_type = args->args[1]; phy_instance = args->args[2];
+ guard(mutex)(>r_phy->phy->mutex); ret = xpsgtr_set_lane_type(gtr_phy, phy_type, phy_instance); if (ret < 0) { dev_err(gtr_dev->dev, "Invalid PHY type and/or instance\n");
From: Waiman Long longman@redhat.com
[ Upstream commit 57b56d16800e8961278ecff0dc755d46c4575092 ]
The writing of css->cgroup associated with the cgroup root in rebind_subsystems() is currently protected only by cgroup_mutex. However, the reading of css->cgroup in both proc_cpuset_show() and proc_cgroup_show() is protected just by css_set_lock. That makes the readers susceptible to racing problems like data tearing or caching. It is also a problem that can be reported by KCSAN.
This can be fixed by using READ_ONCE() and WRITE_ONCE() to access css->cgroup. Alternatively, the writing of css->cgroup can be moved under css_set_lock as well which is done by this patch.
Signed-off-by: Waiman Long longman@redhat.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/cgroup/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index e32b6972c4784..278889170f941 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -1839,9 +1839,9 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask) RCU_INIT_POINTER(scgrp->subsys[ssid], NULL); rcu_assign_pointer(dcgrp->subsys[ssid], css); ss->root = dst_root; - css->cgroup = dcgrp;
spin_lock_irq(&css_set_lock); + css->cgroup = dcgrp; WARN_ON(!list_empty(&dcgrp->e_csets[ss->id])); list_for_each_entry_safe(cset, cset_pos, &scgrp->e_csets[ss->id], e_cset_node[ss->id]) {
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 824ac4a5edd3f7494ab1996826c4f47f8ef0f63d ]
The pointer isn't initialized by callers, but I have encountered cases where it's still printed; initialize it in all possible cases in setup_one_line().
Link: https://patch.msgid.link/20240703172235.ad863568b55f.Iaa1eba4db8265d7715ba71... Acked-By: Anton Ivanov anton.ivanov@cambridgegreys.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/um/drivers/line.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index d82bc3fdb86e7..43d8959cc746f 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -383,6 +383,7 @@ int setup_one_line(struct line *lines, int n, char *init, parse_chan_pair(NULL, line, n, opts, error_out); err = 0; } + *error_out = "configured as 'none'"; } else { char *new = kstrdup(init, GFP_KERNEL); if (!new) { @@ -406,6 +407,7 @@ int setup_one_line(struct line *lines, int n, char *init, } } if (err) { + *error_out = "failed to parse channel pair"; line->init_str = NULL; line->valid = 0; kfree(new);
From: Zijun Hu quic_zijuhu@quicinc.com
[ Upstream commit 56a20ad349b5c51909cf8810f7c79b288864ad33 ]
Initialize an uninitialized struct member for driver API devres_open_group().
Signed-off-by: Zijun Hu quic_zijuhu@quicinc.com Link: https://lore.kernel.org/r/1719931914-19035-4-git-send-email-quic_zijuhu@quic... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/devres.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 3df0025d12aa4..3beedeaa0ffca 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -567,6 +567,7 @@ void * devres_open_group(struct device *dev, void *id, gfp_t gfp) grp->id = grp; if (id) grp->id = id; + grp->color = 0;
spin_lock_irqsave(&dev->devres_lock, flags); add_dr(dev, &grp->node[0]);
From: Emmanuel Grumbach emmanuel.grumbach@intel.com
[ Upstream commit 187accaa328dc4de98064eef176841b8a4716f96 ]
The firmware can't handle that (it will crash with ASSERT 300A). This happened because we looked at vif->bss_conf which is not the right bss_conf to look at in case of an MLD connection. Fix iwl_mvm_roc_duration_and_delay to iterate on the active links to get the right value for the dtim_interval.
Signed-off-by: Emmanuel Grumbach emmanuel.grumbach@intel.com Signed-off-by: Miri Korenblit miriam.rachel.korenblit@intel.com Reviewed-by: Johannes Berg johannes.berg@intel.com Link: https://patch.msgid.link/20240703064027.e12f8d84c8fd.I3dd9f720c678c06ec7a5bf... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/wireless/intel/iwlwifi/mvm/time-event.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c index 31bc80cdcb7d5..97cfd72312f2f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c @@ -984,12 +984,21 @@ void iwl_mvm_roc_duration_and_delay(struct ieee80211_vif *vif, u32 *duration_tu, u32 *delay) { - u32 dtim_interval = vif->bss_conf.dtim_period * - vif->bss_conf.beacon_int; + struct ieee80211_bss_conf *link_conf; + unsigned int link_id; + u32 dtim_interval = 0;
*delay = AUX_ROC_MIN_DELAY; *duration_tu = MSEC_TO_TU(duration_ms);
+ rcu_read_lock(); + for_each_vif_active_link(vif, link_conf, link_id) { + dtim_interval = + max_t(u32, dtim_interval, + link_conf->dtim_period * link_conf->beacon_int); + } + rcu_read_unlock(); + /* * If we are associated we want the delay time to be at least one * dtim interval so that the FW can wait until after the DTIM and @@ -998,8 +1007,10 @@ void iwl_mvm_roc_duration_and_delay(struct ieee80211_vif *vif, * Since we want to use almost a whole dtim interval we would also * like the delay to be for 2-3 dtim intervals, in case there are * other time events with higher priority. + * dtim_interval should never be 0, it can be 1 if we don't know it + * (we haven't heard any beacon yet). */ - if (vif->cfg.assoc) { + if (vif->cfg.assoc && !WARN_ON(!dtim_interval)) { *delay = min_t(u32, dtim_interval * 3, AUX_ROC_MAX_DELAY); /* We cannot remain off-channel longer than the DTIM interval */ if (dtim_interval <= *duration_tu) {
From: Krishna Kumar krishnak@linux.ibm.com
[ Upstream commit 335e35b748527f0c06ded9eebb65387f60647fda ]
The hotplug driver for powerpc (pci/hotplug/pnv_php.c) causes a kernel crash when we try to hot-unplug/disable the PCIe switch/bridge from the PHB.
The crash occurs because although the MSI data structure has been released during disable/hot-unplug path and it has been assigned with NULL, still during unregistration the code was again trying to explicitly disable the MSI which causes the NULL pointer dereference and kernel crash.
The patch fixes the check during unregistration path to prevent invoking pci_disable_msi/msix() since its data structure is already freed.
Reported-by: Timothy Pearson tpearson@raptorengineering.com Closes: https://lore.kernel.org/all/1981605666.2142272.1703742465927.JavaMail.zimbra... Acked-by: Bjorn Helgaas bhelgaas@google.com Tested-by: Shawn Anastasio sanastasio@raptorengineering.com Signed-off-by: Krishna Kumar krishnak@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20240701074513.94873-2-krishnak@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/hotplug/pnv_php.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c index 694349be9d0aa..573a41869c153 100644 --- a/drivers/pci/hotplug/pnv_php.c +++ b/drivers/pci/hotplug/pnv_php.c @@ -40,7 +40,6 @@ static void pnv_php_disable_irq(struct pnv_php_slot *php_slot, bool disable_device) { struct pci_dev *pdev = php_slot->pdev; - int irq = php_slot->irq; u16 ctrl;
if (php_slot->irq > 0) { @@ -59,7 +58,7 @@ static void pnv_php_disable_irq(struct pnv_php_slot *php_slot, php_slot->wq = NULL; }
- if (disable_device || irq > 0) { + if (disable_device) { if (pdev->msix_enabled) pci_disable_msix(pdev); else if (pdev->msi_enabled)
From: Xuan Zhuo xuanzhuo@linux.alibaba.com
[ Upstream commit 840b2d39a2dc1b96deb3f5c7fef76c9b24f08f51 ]
Add kmsan for virtqueue_dma_map_single_attrs to fix:
BUG: KMSAN: uninit-value in receive_buf+0x45ca/0x6990 receive_buf+0x45ca/0x6990 virtnet_poll+0x17e0/0x3130 net_rx_action+0x832/0x26e0 handle_softirqs+0x330/0x10f0 [...]
Uninit was created at: __alloc_pages_noprof+0x62a/0xe60 alloc_pages_noprof+0x392/0x830 skb_page_frag_refill+0x21a/0x5c0 virtnet_rq_alloc+0x50/0x1500 try_fill_recv+0x372/0x54c0 virtnet_open+0x210/0xbe0 __dev_open+0x56e/0x920 __dev_change_flags+0x39c/0x2000 dev_change_flags+0xaa/0x200 do_setlink+0x197a/0x7420 rtnl_setlink+0x77c/0x860 [...]
Signed-off-by: Xuan Zhuo xuanzhuo@linux.alibaba.com Tested-by: Alexander Potapenko glider@google.com Message-Id: 20240606111345.93600-1-xuanzhuo@linux.alibaba.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Tested-by: Ilya Leoshkevich iii@linux.ibm.com # s390x Acked-by: Jason Wang jasowang@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/virtio/virtio_ring.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 2a972752ff1bc..9d3a9942c8c82 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -3121,8 +3121,10 @@ dma_addr_t virtqueue_dma_map_single_attrs(struct virtqueue *_vq, void *ptr, { struct vring_virtqueue *vq = to_vvq(_vq);
- if (!vq->use_dma_api) + if (!vq->use_dma_api) { + kmsan_handle_dma(virt_to_page(ptr), offset_in_page(ptr), size, dir); return (dma_addr_t)virt_to_phys(ptr); + }
return dma_map_single_attrs(vring_dma_dev(vq), ptr, size, dir, attrs); }
From: Marcin Ślusarz mslusarz@renau.com
[ Upstream commit adc539784c98a7cc602cbf557debfc2e7b9be8b3 ]
Right now it's possible to hit NULL pointer dereference in rtw_rx_fill_rx_status on hw object and/or its fields because initialization routine can start getting USB replies before rtw_dev is fully setup.
The stack trace looks like this:
rtw_rx_fill_rx_status rtw8821c_query_rx_desc rtw_usb_rx_handler ... queue_work rtw_usb_read_port_complete ... usb_submit_urb rtw_usb_rx_resubmit rtw_usb_init_rx rtw_usb_probe
So while we do the async stuff rtw_usb_probe continues and calls rtw_register_hw, which does all kinds of initialization (e.g. via ieee80211_register_hw) that rtw_rx_fill_rx_status relies on.
Fix this by moving the first usb_submit_urb after everything is set up.
For me, this bug manifested as: [ 8.893177] rtw_8821cu 1-1:1.2: band wrong, packet dropped [ 8.910904] rtw_8821cu 1-1:1.2: hw->conf.chandef.chan NULL in rtw_rx_fill_rx_status because I'm using Larry's backport of rtw88 driver with the NULL checks in rtw_rx_fill_rx_status.
Link: https://lore.kernel.org/linux-wireless/CA+shoWQ7P49jhQasofDcTdQhiuarPTjYEDa-... Signed-off-by: Marcin Ślusarz mslusarz@renau.com Cc: Tim K tpkuester@gmail.com Cc: Ping-Ke Shih pkshih@realtek.com Cc: Larry Finger Larry.Finger@lwfinger.net Cc: Kalle Valo kvalo@kernel.org Cc: linux-wireless@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Ping-Ke Shih pkshih@realtek.com Link: https://patch.msgid.link/20240528110246.477321-1-marcin.slusarz@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw88/usb.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c index a0188511099a1..98f81e3ae13e7 100644 --- a/drivers/net/wireless/realtek/rtw88/usb.c +++ b/drivers/net/wireless/realtek/rtw88/usb.c @@ -740,7 +740,6 @@ static struct rtw_hci_ops rtw_usb_ops = { static int rtw_usb_init_rx(struct rtw_dev *rtwdev) { struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); - int i;
rtwusb->rxwq = create_singlethread_workqueue("rtw88_usb: rx wq"); if (!rtwusb->rxwq) { @@ -752,13 +751,19 @@ static int rtw_usb_init_rx(struct rtw_dev *rtwdev)
INIT_WORK(&rtwusb->rx_work, rtw_usb_rx_handler);
+ return 0; +} + +static void rtw_usb_setup_rx(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + int i; + for (i = 0; i < RTW_USB_RXCB_NUM; i++) { struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i];
rtw_usb_rx_resubmit(rtwusb, rxcb); } - - return 0; }
static void rtw_usb_deinit_rx(struct rtw_dev *rtwdev) @@ -895,6 +900,8 @@ int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) goto err_destroy_rxwq; }
+ rtw_usb_setup_rx(rtwdev); + return 0;
err_destroy_rxwq:
From: Igor Pylypiv ipylypiv@google.com
[ Upstream commit e4f949ef1516c0d74745ee54a0f4882c1f6c7aea ]
pm8001_phy_control() populates the enable_completion pointer with a stack address, sends a PHY_LINK_RESET / PHY_HARD_RESET, waits 300 ms, and returns. The problem arises when a phy control response comes late. After 300 ms the pm8001_phy_control() function returns and the passed enable_completion stack address is no longer valid. Late phy control response invokes complete() on a dangling enable_completion pointer which leads to a kernel crash.
Signed-off-by: Igor Pylypiv ipylypiv@google.com Signed-off-by: Terrence Adams tadamsjr@google.com Link: https://lore.kernel.org/r/20240627155924.2361370-2-tadamsjr@google.com Acked-by: Jack Wang jinpu.wang@ionos.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/pm8001/pm8001_sas.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index a5a31dfa45122..ee2da8e49d4cf 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -166,7 +166,6 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, unsigned long flags; pm8001_ha = sas_phy->ha->lldd_ha; phy = &pm8001_ha->phy[phy_id]; - pm8001_ha->phy[phy_id].enable_completion = &completion;
if (PM8001_CHIP_DISP->fatal_errors(pm8001_ha)) { /* @@ -190,6 +189,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, rates->maximum_linkrate; } if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) { + pm8001_ha->phy[phy_id].enable_completion = &completion; PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); wait_for_completion(&completion); } @@ -198,6 +198,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, break; case PHY_FUNC_HARD_RESET: if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) { + pm8001_ha->phy[phy_id].enable_completion = &completion; PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); wait_for_completion(&completion); } @@ -206,6 +207,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, break; case PHY_FUNC_LINK_RESET: if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) { + pm8001_ha->phy[phy_id].enable_completion = &completion; PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); wait_for_completion(&completion); }
From: Christoph Hellwig hch@lst.de
[ Upstream commit 73a768d5f95533574bb8ace34eb683a88c40509e ]
Contrary to the comment in __blkdev_issue_write_zeroes, nothing here checks for a potential bi_size overflow. Add a helper mirroring the secure erase code for the check.
Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Martin K. Petersen martin.petersen@oracle.com Link: https://lore.kernel.org/r/20240701165219.1571322-6-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-lib.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/block/blk-lib.c b/block/blk-lib.c index 442da9dad0421..297bcf6896930 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c @@ -103,24 +103,28 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, } EXPORT_SYMBOL(blkdev_issue_discard);
+static sector_t bio_write_zeroes_limit(struct block_device *bdev) +{ + sector_t bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1; + + return min(bdev_write_zeroes_sectors(bdev), + (UINT_MAX >> SECTOR_SHIFT) & ~bs_mask); +} + static int __blkdev_issue_write_zeroes(struct block_device *bdev, sector_t sector, sector_t nr_sects, gfp_t gfp_mask, struct bio **biop, unsigned flags) { struct bio *bio = *biop; - unsigned int max_sectors;
if (bdev_read_only(bdev)) return -EPERM; - - /* Ensure that max_sectors doesn't overflow bi_size */ - max_sectors = bdev_write_zeroes_sectors(bdev); - - if (max_sectors == 0) + if (!bdev_write_zeroes_sectors(bdev)) return -EOPNOTSUPP;
while (nr_sects) { - unsigned int len = min_t(sector_t, nr_sects, max_sectors); + unsigned int len = min_t(sector_t, nr_sects, + bio_write_zeroes_limit(bdev));
bio = blk_next_bio(bio, bdev, 0, REQ_OP_WRITE_ZEROES, gfp_mask); bio->bi_iter.bi_sector = sector;
From: Guenter Roeck linux@roeck-us.net
[ Upstream commit af64e3e1537896337405f880c1e9ac1f8c0c6198 ]
DIV_ROUND_CLOSEST() after kstrtol() results in an underflow if a large negative number such as -9223372036854775808 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/lm95234.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/lm95234.c b/drivers/hwmon/lm95234.c index 67b9d7636ee42..37e8e9679aeb6 100644 --- a/drivers/hwmon/lm95234.c +++ b/drivers/hwmon/lm95234.c @@ -301,7 +301,8 @@ static ssize_t tcrit2_store(struct device *dev, struct device_attribute *attr, if (ret < 0) return ret;
- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, index ? 255 : 127); + val = DIV_ROUND_CLOSEST(clamp_val(val, 0, (index ? 255 : 127) * 1000), + 1000);
mutex_lock(&data->update_lock); data->tcrit2[index] = val; @@ -350,7 +351,7 @@ static ssize_t tcrit1_store(struct device *dev, struct device_attribute *attr, if (ret < 0) return ret;
- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255); + val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 255000), 1000);
mutex_lock(&data->update_lock); data->tcrit1[index] = val; @@ -391,7 +392,7 @@ static ssize_t tcrit1_hyst_store(struct device *dev, if (ret < 0) return ret;
- val = DIV_ROUND_CLOSEST(val, 1000); + val = DIV_ROUND_CLOSEST(clamp_val(val, -255000, 255000), 1000); val = clamp_val((int)data->tcrit1[index] - val, 0, 31);
mutex_lock(&data->update_lock); @@ -431,7 +432,7 @@ static ssize_t offset_store(struct device *dev, struct device_attribute *attr, return ret;
/* Accuracy is 1/2 degrees C */ - val = clamp_val(DIV_ROUND_CLOSEST(val, 500), -128, 127); + val = DIV_ROUND_CLOSEST(clamp_val(val, -64000, 63500), 500);
mutex_lock(&data->update_lock); data->toffset[index] = val;
From: Guenter Roeck linux@roeck-us.net
[ Upstream commit 0403e10bf0824bf0ec2bb135d4cf1c0cc3bf4bf0 ]
DIV_ROUND_CLOSEST() after kstrtol() results in an underflow if a large negative number such as -9223372036854775808 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/nct6775-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwmon/nct6775-core.c b/drivers/hwmon/nct6775-core.c index 9fbab8f023340..934fed3dd5866 100644 --- a/drivers/hwmon/nct6775-core.c +++ b/drivers/hwmon/nct6775-core.c @@ -2262,7 +2262,7 @@ store_temp_offset(struct device *dev, struct device_attribute *attr, if (err < 0) return err;
- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127); + val = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000);
mutex_lock(&data->update_lock); data->temp_offset[nr] = val;
From: Guenter Roeck linux@roeck-us.net
[ Upstream commit 5c1de37969b7bc0abcb20b86e91e70caebbd4f89 ]
DIV_ROUND_CLOSEST() after kstrtol() results in an underflow if a large negative number such as -9223372036854775808 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/w83627ehf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index fe960c0a624f7..7d7d70afde655 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -895,7 +895,7 @@ store_target_temp(struct device *dev, struct device_attribute *attr, if (err < 0) return err;
- val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 127); + val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 127000), 1000);
mutex_lock(&data->update_lock); data->target_temp[nr] = val; @@ -920,7 +920,7 @@ store_tolerance(struct device *dev, struct device_attribute *attr, return err;
/* Limit the temp to 0C - 15C */ - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 15); + val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 15000), 1000);
mutex_lock(&data->update_lock); reg = w83627ehf_read_value(data, W83627EHF_REG_TOLERANCE[nr]);
From: Andreas Ziegler ziegler.andreas@siemens.com
[ Upstream commit cedc12c5b57f7efa6dbebfb2b140e8675f5a2616 ]
In the current state, an erroneous call to bpf_object__find_map_by_name(NULL, ...) leads to a segmentation fault through the following call chain:
bpf_object__find_map_by_name(obj = NULL, ...) -> bpf_object__for_each_map(pos, obj = NULL) -> bpf_object__next_map((obj = NULL), NULL) -> return (obj = NULL)->maps
While calling bpf_object__find_map_by_name with obj = NULL is obviously incorrect, this should not lead to a segmentation fault but rather be handled gracefully.
As __bpf_map__iter already handles this situation correctly, we can delegate the check for the regular case there and only add a check in case the prev or next parameter is NULL.
Signed-off-by: Andreas Ziegler ziegler.andreas@siemens.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20240703083436.505124-1-ziegler.andreas@siemens.... Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 5401f2df463d2..5edb717647847 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -10336,7 +10336,7 @@ __bpf_map__iter(const struct bpf_map *m, const struct bpf_object *obj, int i) struct bpf_map * bpf_object__next_map(const struct bpf_object *obj, const struct bpf_map *prev) { - if (prev == NULL) + if (prev == NULL && obj != NULL) return obj->maps;
return __bpf_map__iter(prev, obj, 1); @@ -10345,7 +10345,7 @@ bpf_object__next_map(const struct bpf_object *obj, const struct bpf_map *prev) struct bpf_map * bpf_object__prev_map(const struct bpf_object *obj, const struct bpf_map *next) { - if (next == NULL) { + if (next == NULL && obj != NULL) { if (!obj->nr_maps) return NULL; return obj->maps + obj->nr_maps - 1;
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit b3603133d3b727b0b07a7094ab74cf27c8aee3bd ]
WARN_ON("string") will unconditionally trigger a warning, but not really do what it may look like. Use WARN(1, ...) instead and add the mode number as well.
Signed-off-by: Johannes Berg johannes.berg@intel.com Link: https://patch.msgid.link/20240705133921.a50aa5b15ece.I9a25b7448b0498c0c2e503... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/virtual/mac80211_hwsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c index c5d896994e709..53a725908f742 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c @@ -3260,7 +3260,7 @@ static int mac80211_hwsim_switch_vif_chanctx(struct ieee80211_hw *hw, hwsim_clear_chanctx_magic(vifs[i].old_ctx); break; default: - WARN_ON("Invalid mode"); + WARN(1, "Invalid mode %d\n", mode); } } return 0;
From: Sascha Hauer s.hauer@pengutronix.de
[ Upstream commit c145eea2f75ff7949392aebecf7ef0a81c1f6c14 ]
mwifiex_get_priv_by_id() returns the priv pointer corresponding to the bss_num and bss_type, but without checking if the priv is actually currently in use. Unused priv pointers do not have a wiphy attached to them which can lead to NULL pointer dereferences further down the callstack. Fix this by returning only used priv pointers which have priv->bss_mode set to something else than NL80211_IFTYPE_UNSPECIFIED.
Said NULL pointer dereference happened when an Accesspoint was started with wpa_supplicant -i mlan0 with this config:
network={ ssid="somessid" mode=2 frequency=2412 key_mgmt=WPA-PSK WPA-PSK-SHA256 proto=RSN group=CCMP pairwise=CCMP psk="12345678" }
When waiting for the AP to be established, interrupting wpa_supplicant with <ctrl-c> and starting it again this happens:
| Unable to handle kernel NULL pointer dereference at virtual address 0000000000000140 | Mem abort info: | ESR = 0x0000000096000004 | EC = 0x25: DABT (current EL), IL = 32 bits | SET = 0, FnV = 0 | EA = 0, S1PTW = 0 | FSC = 0x04: level 0 translation fault | Data abort info: | ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 | CM = 0, WnR = 0, TnD = 0, TagAccess = 0 | GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 | user pgtable: 4k pages, 48-bit VAs, pgdp=0000000046d96000 | [0000000000000140] pgd=0000000000000000, p4d=0000000000000000 | Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP | Modules linked in: caam_jr caamhash_desc spidev caamalg_desc crypto_engine authenc libdes mwifiex_sdio +mwifiex crct10dif_ce cdc_acm onboard_usb_hub fsl_imx8_ddr_perf imx8m_ddrc rtc_ds1307 lm75 rtc_snvs +imx_sdma caam imx8mm_thermal spi_imx error imx_cpufreq_dt fuse ip_tables x_tables ipv6 | CPU: 0 PID: 8 Comm: kworker/0:1 Not tainted 6.9.0-00007-g937242013fce-dirty #18 | Hardware name: somemachine (DT) | Workqueue: events sdio_irq_work | pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : mwifiex_get_cfp+0xd8/0x15c [mwifiex] | lr : mwifiex_get_cfp+0x34/0x15c [mwifiex] | sp : ffff8000818b3a70 | x29: ffff8000818b3a70 x28: ffff000006bfd8a5 x27: 0000000000000004 | x26: 000000000000002c x25: 0000000000001511 x24: 0000000002e86bc9 | x23: ffff000006bfd996 x22: 0000000000000004 x21: ffff000007bec000 | x20: 000000000000002c x19: 0000000000000000 x18: 0000000000000000 | x17: 000000040044ffff x16: 00500072b5503510 x15: ccc283740681e517 | x14: 0201000101006d15 x13: 0000000002e8ff43 x12: 002c01000000ffb1 | x11: 0100000000000000 x10: 02e8ff43002c0100 x9 : 0000ffb100100157 | x8 : ffff000003d20000 x7 : 00000000000002f1 x6 : 00000000ffffe124 | x5 : 0000000000000001 x4 : 0000000000000003 x3 : 0000000000000000 | x2 : 0000000000000000 x1 : 0001000000011001 x0 : 0000000000000000 | Call trace: | mwifiex_get_cfp+0xd8/0x15c [mwifiex] | mwifiex_parse_single_response_buf+0x1d0/0x504 [mwifiex] | mwifiex_handle_event_ext_scan_report+0x19c/0x2f8 [mwifiex] | mwifiex_process_sta_event+0x298/0xf0c [mwifiex] | mwifiex_process_event+0x110/0x238 [mwifiex] | mwifiex_main_process+0x428/0xa44 [mwifiex] | mwifiex_sdio_interrupt+0x64/0x12c [mwifiex_sdio] | process_sdio_pending_irqs+0x64/0x1b8 | sdio_irq_work+0x4c/0x7c | process_one_work+0x148/0x2a0 | worker_thread+0x2fc/0x40c | kthread+0x110/0x114 | ret_from_fork+0x10/0x20 | Code: a94153f3 a8c37bfd d50323bf d65f03c0 (f940a000) | ---[ end trace 0000000000000000 ]---
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de Acked-by: Brian Norris briannorris@chromium.org Reviewed-by: Francesco Dolcini francesco.dolcini@toradex.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://patch.msgid.link/20240703072409.556618-1-s.hauer@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/main.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index 175882485a195..c5164ae41b547 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -1287,6 +1287,9 @@ mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter,
for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { + if (adapter->priv[i]->bss_mode == NL80211_IFTYPE_UNSPECIFIED) + continue; + if ((adapter->priv[i]->bss_num == bss_num) && (adapter->priv[i]->bss_type == bss_type)) break;
From: Jarkko Nikula jarkko.nikula@linux.intel.com
[ Upstream commit 8a2be2f1db268ec735419e53ef04ca039fc027dc ]
Definitely condition dma_get_cache_alignment * defined value > 256 during driver initialization is not reason to BUG_ON(). Turn that to graceful error out with -EINVAL.
Signed-off-by: Jarkko Nikula jarkko.nikula@linux.intel.com Link: https://lore.kernel.org/r/20240628131559.502822-3-jarkko.nikula@linux.intel.... Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i3c/master/mipi-i3c-hci/dma.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c index 4e01a95cc4d0a..1a96bf5a0bf87 100644 --- a/drivers/i3c/master/mipi-i3c-hci/dma.c +++ b/drivers/i3c/master/mipi-i3c-hci/dma.c @@ -294,7 +294,10 @@ static int hci_dma_init(struct i3c_hci *hci)
rh->ibi_chunk_sz = dma_get_cache_alignment(); rh->ibi_chunk_sz *= IBI_CHUNK_CACHELINES; - BUG_ON(rh->ibi_chunk_sz > 256); + if (rh->ibi_chunk_sz > 256) { + ret = -EINVAL; + goto err_out; + }
ibi_status_ring_sz = rh->ibi_status_sz * rh->ibi_status_entries; ibi_data_ring_sz = rh->ibi_chunk_sz * rh->ibi_chunks_total;
linux-stable-mirror@lists.linaro.org