drm/amdkfd: Fix possible infinite loop
When the loop predicating timeout parameter passed happens to not be a multiple of 20 the unsigned integer will overflow and the loop will become unbounded. Signed-off-by: Edward O'Callaghan <funfunctor@folklore1984.net> Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com> Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
This commit is contained in:
parent
ad16a469ff
commit
1d602430d3
|
@ -103,11 +103,11 @@ static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
|
|||
uint32_t pipe_id, uint32_t queue_id);
|
||||
|
||||
static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
|
||||
unsigned int timeout, uint32_t pipe_id,
|
||||
unsigned int utimeout, uint32_t pipe_id,
|
||||
uint32_t queue_id);
|
||||
static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd);
|
||||
static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
|
||||
unsigned int timeout);
|
||||
unsigned int utimeout);
|
||||
static int kgd_address_watch_disable(struct kgd_dev *kgd);
|
||||
static int kgd_address_watch_execute(struct kgd_dev *kgd,
|
||||
unsigned int watch_point_id,
|
||||
|
@ -437,11 +437,12 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
|
|||
}
|
||||
|
||||
static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
|
||||
unsigned int timeout, uint32_t pipe_id,
|
||||
unsigned int utimeout, uint32_t pipe_id,
|
||||
uint32_t queue_id)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
uint32_t temp;
|
||||
int timeout = utimeout;
|
||||
|
||||
acquire_queue(kgd, pipe_id, queue_id);
|
||||
WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, 0);
|
||||
|
@ -452,9 +453,8 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
|
|||
temp = RREG32(mmCP_HQD_ACTIVE);
|
||||
if (temp & CP_HQD_ACTIVE__ACTIVE_MASK)
|
||||
break;
|
||||
if (timeout == 0) {
|
||||
pr_err("kfd: cp queue preemption time out (%dms)\n",
|
||||
temp);
|
||||
if (timeout <= 0) {
|
||||
pr_err("kfd: cp queue preemption time out.\n");
|
||||
release_queue(kgd);
|
||||
return -ETIME;
|
||||
}
|
||||
|
@ -467,12 +467,13 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
|
|||
}
|
||||
|
||||
static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
|
||||
unsigned int timeout)
|
||||
unsigned int utimeout)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
struct cik_sdma_rlc_registers *m;
|
||||
uint32_t sdma_base_addr;
|
||||
uint32_t temp;
|
||||
int timeout = utimeout;
|
||||
|
||||
m = get_sdma_mqd(mqd);
|
||||
sdma_base_addr = get_sdma_base_addr(m);
|
||||
|
@ -485,7 +486,7 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
|
|||
temp = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS);
|
||||
if (temp & SDMA0_STATUS_REG__RB_CMD_IDLE__SHIFT)
|
||||
break;
|
||||
if (timeout == 0)
|
||||
if (timeout <= 0)
|
||||
return -ETIME;
|
||||
msleep(20);
|
||||
timeout -= 20;
|
||||
|
|
|
@ -62,10 +62,10 @@ static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
|
|||
uint32_t pipe_id, uint32_t queue_id);
|
||||
static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd);
|
||||
static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
|
||||
unsigned int timeout, uint32_t pipe_id,
|
||||
unsigned int utimeout, uint32_t pipe_id,
|
||||
uint32_t queue_id);
|
||||
static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
|
||||
unsigned int timeout);
|
||||
unsigned int utimeout);
|
||||
static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid);
|
||||
static int kgd_address_watch_disable(struct kgd_dev *kgd);
|
||||
static int kgd_address_watch_execute(struct kgd_dev *kgd,
|
||||
|
@ -349,11 +349,12 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
|
|||
}
|
||||
|
||||
static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
|
||||
unsigned int timeout, uint32_t pipe_id,
|
||||
unsigned int utimeout, uint32_t pipe_id,
|
||||
uint32_t queue_id)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
uint32_t temp;
|
||||
int timeout = utimeout;
|
||||
|
||||
acquire_queue(kgd, pipe_id, queue_id);
|
||||
|
||||
|
@ -363,9 +364,8 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
|
|||
temp = RREG32(mmCP_HQD_ACTIVE);
|
||||
if (temp & CP_HQD_ACTIVE__ACTIVE_MASK)
|
||||
break;
|
||||
if (timeout == 0) {
|
||||
pr_err("kfd: cp queue preemption time out (%dms)\n",
|
||||
temp);
|
||||
if (timeout <= 0) {
|
||||
pr_err("kfd: cp queue preemption time out.\n");
|
||||
release_queue(kgd);
|
||||
return -ETIME;
|
||||
}
|
||||
|
@ -378,12 +378,13 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
|
|||
}
|
||||
|
||||
static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
|
||||
unsigned int timeout)
|
||||
unsigned int utimeout)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
struct cik_sdma_rlc_registers *m;
|
||||
uint32_t sdma_base_addr;
|
||||
uint32_t temp;
|
||||
int timeout = utimeout;
|
||||
|
||||
m = get_sdma_mqd(mqd);
|
||||
sdma_base_addr = get_sdma_base_addr(m);
|
||||
|
@ -396,7 +397,7 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
|
|||
temp = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS);
|
||||
if (temp & SDMA0_STATUS_REG__RB_CMD_IDLE__SHIFT)
|
||||
break;
|
||||
if (timeout == 0)
|
||||
if (timeout <= 0)
|
||||
return -ETIME;
|
||||
msleep(20);
|
||||
timeout -= 20;
|
||||
|
|
Loading…
Reference in New Issue