Commit 6e41709e authored by Hersen Wu's avatar Hersen Wu Committed by Alex Deucher

drm/amd/display: Add NULL pointer and OVERRUN check within amdgpu_dm irq register

[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: default avatarHarry Wentland <harry.wentland@amd.com>
Acked-by: default avatarTom Chung <chiahsuan.chung@amd.com>
Signed-off-by: default avatarHersen Wu <hersenxs.wu@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 2a5626ee
...@@ -3584,7 +3584,7 @@ static void handle_hpd_rx_irq(void *param) ...@@ -3584,7 +3584,7 @@ static void handle_hpd_rx_irq(void *param)
mutex_unlock(&aconnector->hpd_lock); 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_device *dev = adev_to_drm(adev);
struct drm_connector *connector; struct drm_connector *connector;
...@@ -3596,11 +3596,17 @@ static void register_hpd_handlers(struct amdgpu_device *adev) ...@@ -3596,11 +3596,17 @@ static void register_hpd_handlers(struct amdgpu_device *adev)
int_params.current_polarity = INTERRUPT_POLARITY_DEFAULT; int_params.current_polarity = INTERRUPT_POLARITY_DEFAULT;
if (dc_is_dmub_outbox_supported(adev->dm.dc)) { 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"); 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"); DRM_ERROR("amdgpu: fail to register dmub hpd callback");
return -EINVAL;
}
} }
list_for_each_entry(connector, list_for_each_entry(connector,
...@@ -3616,9 +3622,16 @@ static void register_hpd_handlers(struct amdgpu_device *adev) ...@@ -3616,9 +3622,16 @@ static void register_hpd_handlers(struct amdgpu_device *adev)
int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT; int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT;
int_params.irq_source = dc_link->irq_source_hpd; int_params.irq_source = dc_link->irq_source_hpd;
amdgpu_dm_irq_register_interrupt(adev, &int_params, if (int_params.irq_source == DC_IRQ_SOURCE_INVALID ||
handle_hpd_irq, int_params.irq_source < DC_IRQ_SOURCE_HPD1 ||
(void *) aconnector); 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) { if (dc_link->irq_source_hpd_rx != DC_IRQ_SOURCE_INVALID) {
...@@ -3627,11 +3640,19 @@ static void register_hpd_handlers(struct amdgpu_device *adev) ...@@ -3627,11 +3640,19 @@ static void register_hpd_handlers(struct amdgpu_device *adev)
int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT; int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT;
int_params.irq_source = dc_link->irq_source_hpd_rx; int_params.irq_source = dc_link->irq_source_hpd_rx;
amdgpu_dm_irq_register_interrupt(adev, &int_params, if (int_params.irq_source == DC_IRQ_SOURCE_INVALID ||
handle_hpd_rx_irq, int_params.irq_source < DC_IRQ_SOURCE_HPD1RX ||
(void *) aconnector); 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) #if defined(CONFIG_DRM_AMD_DC_SI)
...@@ -3672,13 +3693,21 @@ static int dce60_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3672,13 +3693,21 @@ static int dce60_register_irq_handlers(struct amdgpu_device *adev)
int_params.irq_source = int_params.irq_source =
dc_interrupt_to_irq_source(dc, i + 1, 0); 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->dm.vblank_params[int_params.irq_source - DC_IRQ_SOURCE_VBLANK1];
c_irq_params->adev = adev; c_irq_params->adev = adev;
c_irq_params->irq_src = int_params.irq_source; c_irq_params->irq_src = int_params.irq_source;
amdgpu_dm_irq_register_interrupt(adev, &int_params, if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
dm_crtc_high_irq, c_irq_params); dm_crtc_high_irq, c_irq_params))
return -ENOMEM;
} }
/* Use GRPH_PFLIP interrupt */ /* Use GRPH_PFLIP interrupt */
...@@ -3694,14 +3723,21 @@ static int dce60_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3694,14 +3723,21 @@ static int dce60_register_irq_handlers(struct amdgpu_device *adev)
int_params.irq_source = int_params.irq_source =
dc_interrupt_to_irq_source(dc, i, 0); 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->dm.pflip_params[int_params.irq_source - DC_IRQ_SOURCE_PFLIP_FIRST];
c_irq_params->adev = adev; c_irq_params->adev = adev;
c_irq_params->irq_src = int_params.irq_source; c_irq_params->irq_src = int_params.irq_source;
amdgpu_dm_irq_register_interrupt(adev, &int_params, if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
dm_pflip_high_irq, c_irq_params); dm_pflip_high_irq, c_irq_params))
return -ENOMEM;
} }
/* HPD */ /* HPD */
...@@ -3712,9 +3748,9 @@ static int dce60_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3712,9 +3748,9 @@ static int dce60_register_irq_handlers(struct amdgpu_device *adev)
return r; return r;
} }
register_hpd_handlers(adev); r = register_hpd_handlers(adev);
return 0; return r;
} }
#endif #endif
...@@ -3758,13 +3794,21 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3758,13 +3794,21 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev)
int_params.irq_source = int_params.irq_source =
dc_interrupt_to_irq_source(dc, i, 0); 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->dm.vblank_params[int_params.irq_source - DC_IRQ_SOURCE_VBLANK1];
c_irq_params->adev = adev; c_irq_params->adev = adev;
c_irq_params->irq_src = int_params.irq_source; c_irq_params->irq_src = int_params.irq_source;
amdgpu_dm_irq_register_interrupt(adev, &int_params, if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
dm_crtc_high_irq, c_irq_params); dm_crtc_high_irq, c_irq_params))
return -ENOMEM;
} }
/* Use VUPDATE interrupt */ /* Use VUPDATE interrupt */
...@@ -3779,13 +3823,21 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3779,13 +3823,21 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev)
int_params.irq_source = int_params.irq_source =
dc_interrupt_to_irq_source(dc, i, 0); 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->dm.vupdate_params[int_params.irq_source - DC_IRQ_SOURCE_VUPDATE1];
c_irq_params->adev = adev; c_irq_params->adev = adev;
c_irq_params->irq_src = int_params.irq_source; c_irq_params->irq_src = int_params.irq_source;
amdgpu_dm_irq_register_interrupt(adev, &int_params, if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
dm_vupdate_high_irq, c_irq_params); dm_vupdate_high_irq, c_irq_params))
return -ENOMEM;
} }
/* Use GRPH_PFLIP interrupt */ /* Use GRPH_PFLIP interrupt */
...@@ -3801,14 +3853,21 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3801,14 +3853,21 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev)
int_params.irq_source = int_params.irq_source =
dc_interrupt_to_irq_source(dc, i, 0); 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->dm.pflip_params[int_params.irq_source - DC_IRQ_SOURCE_PFLIP_FIRST];
c_irq_params->adev = adev; c_irq_params->adev = adev;
c_irq_params->irq_src = int_params.irq_source; c_irq_params->irq_src = int_params.irq_source;
amdgpu_dm_irq_register_interrupt(adev, &int_params, if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
dm_pflip_high_irq, c_irq_params); dm_pflip_high_irq, c_irq_params))
return -ENOMEM;
} }
/* HPD */ /* HPD */
...@@ -3819,9 +3878,9 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3819,9 +3878,9 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev)
return r; return r;
} }
register_hpd_handlers(adev); r = register_hpd_handlers(adev);
return 0; return r;
} }
/* Register IRQ sources and initialize IRQ callbacks */ /* Register IRQ sources and initialize IRQ callbacks */
...@@ -3873,13 +3932,21 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3873,13 +3932,21 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev)
int_params.irq_source = int_params.irq_source =
dc_interrupt_to_irq_source(dc, i, 0); 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->dm.vblank_params[int_params.irq_source - DC_IRQ_SOURCE_VBLANK1];
c_irq_params->adev = adev; c_irq_params->adev = adev;
c_irq_params->irq_src = int_params.irq_source; c_irq_params->irq_src = int_params.irq_source;
amdgpu_dm_irq_register_interrupt( if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
adev, &int_params, dm_crtc_high_irq, c_irq_params); dm_crtc_high_irq, c_irq_params))
return -ENOMEM;
} }
/* Use otg vertical line interrupt */ /* Use otg vertical line interrupt */
...@@ -3897,9 +3964,11 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3897,9 +3964,11 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev)
int_params.irq_source = int_params.irq_source =
dc_interrupt_to_irq_source(dc, vrtl_int_srcid[i], 0); dc_interrupt_to_irq_source(dc, vrtl_int_srcid[i], 0);
if (int_params.irq_source == DC_IRQ_SOURCE_INVALID) { if (int_params.irq_source == DC_IRQ_SOURCE_INVALID ||
DRM_ERROR("Failed to register vline0 irq %d!\n", vrtl_int_srcid[i]); int_params.irq_source < DC_IRQ_SOURCE_DC1_VLINE0 ||
break; 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 c_irq_params = &adev->dm.vline0_params[int_params.irq_source
...@@ -3908,8 +3977,10 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3908,8 +3977,10 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev)
c_irq_params->adev = adev; c_irq_params->adev = adev;
c_irq_params->irq_src = int_params.irq_source; c_irq_params->irq_src = int_params.irq_source;
amdgpu_dm_irq_register_interrupt(adev, &int_params, if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
dm_dcn_vertical_interrupt0_high_irq, c_irq_params); dm_dcn_vertical_interrupt0_high_irq,
c_irq_params))
return -ENOMEM;
} }
#endif #endif
...@@ -3932,13 +4003,21 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3932,13 +4003,21 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev)
int_params.irq_source = int_params.irq_source =
dc_interrupt_to_irq_source(dc, i, 0); 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->dm.vupdate_params[int_params.irq_source - DC_IRQ_SOURCE_VUPDATE1];
c_irq_params->adev = adev; c_irq_params->adev = adev;
c_irq_params->irq_src = int_params.irq_source; c_irq_params->irq_src = int_params.irq_source;
amdgpu_dm_irq_register_interrupt(adev, &int_params, if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
dm_vupdate_high_irq, c_irq_params); dm_vupdate_high_irq, c_irq_params))
return -ENOMEM;
} }
/* Use GRPH_PFLIP interrupt */ /* Use GRPH_PFLIP interrupt */
...@@ -3955,14 +4034,21 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3955,14 +4034,21 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev)
int_params.irq_source = int_params.irq_source =
dc_interrupt_to_irq_source(dc, i, 0); 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->dm.pflip_params[int_params.irq_source - DC_IRQ_SOURCE_PFLIP_FIRST];
c_irq_params->adev = adev; c_irq_params->adev = adev;
c_irq_params->irq_src = int_params.irq_source; c_irq_params->irq_src = int_params.irq_source;
amdgpu_dm_irq_register_interrupt(adev, &int_params, if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
dm_pflip_high_irq, c_irq_params); dm_pflip_high_irq, c_irq_params))
return -ENOMEM;
} }
/* HPD */ /* HPD */
...@@ -3973,9 +4059,9 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) ...@@ -3973,9 +4059,9 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev)
return r; return r;
} }
register_hpd_handlers(adev); r = register_hpd_handlers(adev);
return 0; return r;
} }
/* Register Outbox IRQ sources and initialize IRQ callbacks */ /* Register Outbox IRQ sources and initialize IRQ callbacks */
static int register_outbox_irq_handlers(struct amdgpu_device *adev) static int register_outbox_irq_handlers(struct amdgpu_device *adev)
...@@ -4006,8 +4092,9 @@ static int register_outbox_irq_handlers(struct amdgpu_device *adev) ...@@ -4006,8 +4092,9 @@ static int register_outbox_irq_handlers(struct amdgpu_device *adev)
c_irq_params->adev = adev; c_irq_params->adev = adev;
c_irq_params->irq_src = int_params.irq_source; c_irq_params->irq_src = int_params.irq_source;
amdgpu_dm_irq_register_interrupt(adev, &int_params, if (!amdgpu_dm_irq_register_interrupt(adev, &int_params,
dm_dmub_outbox1_low_irq, c_irq_params); dm_dmub_outbox1_low_irq, c_irq_params))
return -ENOMEM;
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment