Skip to content

Commit

Permalink
drm/amd/display: Fix invalid DPIA AUX reply causing system hang
Browse files Browse the repository at this point in the history
commit 8d8494c upstream.

[Why]
Some DPIA AUX replies have incorrect data length from original request.
This could lead to overwriting of destination buffer if reply length is
larger, which could cause invalid access to stack since many destination
buffers are declared as local variables.

[How]
Check for invalid length from DPIA AUX replies and trigger a retry if
reply length is not the same as original request. A DRM_WARN() dmesg log
is also produced.

Reviewed-by: Roman Li <Roman.Li@amd.com>
Acked-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Stylon Wang <stylon.wang@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org # 6.0.x
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Stylon Wang authored and gregkh committed Nov 26, 2022
1 parent 2f341d7 commit 09b5567
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 6 deletions.
20 changes: 20 additions & 0 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Expand Up @@ -146,6 +146,14 @@ MODULE_FIRMWARE(FIRMWARE_NAVI12_DMCU);
/* Number of bytes in PSP footer for firmware. */
#define PSP_FOOTER_BYTES 0x100

/*
* DMUB Async to Sync Mechanism Status
*/
#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1
#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2
#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3
#define DMUB_ASYNC_TO_SYNC_ACCESS_INVALID 4

/**
* DOC: overview
*
Expand Down Expand Up @@ -10149,6 +10157,8 @@ static int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux,
*operation_result = AUX_RET_ERROR_TIMEOUT;
} else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_FAIL) {
*operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE;
} else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_INVALID) {
*operation_result = AUX_RET_ERROR_INVALID_REPLY;
} else {
*operation_result = AUX_RET_ERROR_UNKNOWN;
}
Expand Down Expand Up @@ -10196,6 +10206,16 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux, struct dc_context
payload->reply[0] = adev->dm.dmub_notify->aux_reply.command;
if (!payload->write && adev->dm.dmub_notify->aux_reply.length &&
payload->reply[0] == AUX_TRANSACTION_REPLY_AUX_ACK) {

if (payload->length != adev->dm.dmub_notify->aux_reply.length) {
DRM_WARN("invalid read from DPIA AUX %x(%d) got length %d!\n",
payload->address, payload->length,
adev->dm.dmub_notify->aux_reply.length);
return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux, ctx,
DMUB_ASYNC_TO_SYNC_ACCESS_INVALID,
(uint32_t *)operation_result);
}

memcpy(payload->data, adev->dm.dmub_notify->aux_reply.data,
adev->dm.dmub_notify->aux_reply.length);
}
Expand Down
6 changes: 0 additions & 6 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
Expand Up @@ -50,12 +50,6 @@

#define AMDGPU_DMUB_NOTIFICATION_MAX 5

/*
* DMUB Async to Sync Mechanism Status
*/
#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1
#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2
#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3
/*
#include "include/amdgpu_dal_power_if.h"
#include "amdgpu_dm_irq.h"
Expand Down

0 comments on commit 09b5567

Please sign in to comment.