mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 07:01:57 +00:00
drm/radeon: add locking around atombios scratch space usage
While developing MST support I noticed I often got the wrong data back from a transaction, in a racy fashion. I noticed the scratch space wasn't locked against concurrent users. Based on a patch by Alex, but I've made it a bit more obvious when things are locked. Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org
This commit is contained in:
parent
03dca70852
commit
1c94984254
@ -1217,7 +1217,7 @@ free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
|
||||
int atom_execute_table_scratch_unlocked(struct atom_context *ctx, int index, uint32_t * params)
|
||||
{
|
||||
int r;
|
||||
|
||||
@ -1238,6 +1238,15 @@ int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
|
||||
return r;
|
||||
}
|
||||
|
||||
int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
|
||||
{
|
||||
int r;
|
||||
mutex_lock(&ctx->scratch_mutex);
|
||||
r = atom_execute_table_scratch_unlocked(ctx, index, params);
|
||||
mutex_unlock(&ctx->scratch_mutex);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 };
|
||||
|
||||
static void atom_index_iio(struct atom_context *ctx, int base)
|
||||
|
@ -125,6 +125,7 @@ struct card_info {
|
||||
struct atom_context {
|
||||
struct card_info *card;
|
||||
struct mutex mutex;
|
||||
struct mutex scratch_mutex;
|
||||
void *bios;
|
||||
uint32_t cmd_table, data_table;
|
||||
uint16_t *iio;
|
||||
@ -145,6 +146,7 @@ extern int atom_debug;
|
||||
|
||||
struct atom_context *atom_parse(struct card_info *, void *);
|
||||
int atom_execute_table(struct atom_context *, int, uint32_t *);
|
||||
int atom_execute_table_scratch_unlocked(struct atom_context *, int, uint32_t *);
|
||||
int atom_asic_init(struct atom_context *);
|
||||
void atom_destroy(struct atom_context *);
|
||||
bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
|
||||
|
@ -100,6 +100,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
mutex_lock(&chan->mutex);
|
||||
mutex_lock(&rdev->mode_info.atom_context->scratch_mutex);
|
||||
|
||||
base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1);
|
||||
|
||||
@ -113,7 +114,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
|
||||
if (ASIC_IS_DCE4(rdev))
|
||||
args.v2.ucHPD_ID = chan->rec.hpd;
|
||||
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
atom_execute_table_scratch_unlocked(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
|
||||
*ack = args.v1.ucReplyStatus;
|
||||
|
||||
@ -147,6 +148,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
|
||||
|
||||
r = recv_bytes;
|
||||
done:
|
||||
mutex_unlock(&rdev->mode_info.atom_context->scratch_mutex);
|
||||
mutex_unlock(&chan->mutex);
|
||||
|
||||
return r;
|
||||
|
@ -48,6 +48,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
mutex_lock(&chan->mutex);
|
||||
mutex_lock(&rdev->mode_info.atom_context->scratch_mutex);
|
||||
|
||||
base = (unsigned char *)rdev->mode_info.atom_context->scratch;
|
||||
|
||||
@ -82,7 +83,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
|
||||
args.ucSlaveAddr = slave_addr << 1;
|
||||
args.ucLineNumber = chan->rec.i2c_id;
|
||||
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
atom_execute_table_scratch_unlocked(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
|
||||
/* error */
|
||||
if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) {
|
||||
@ -95,6 +96,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
|
||||
radeon_atom_copy_swap(buf, base, num, false);
|
||||
|
||||
done:
|
||||
mutex_unlock(&rdev->mode_info.atom_context->scratch_mutex);
|
||||
mutex_unlock(&chan->mutex);
|
||||
|
||||
return r;
|
||||
|
@ -952,6 +952,7 @@ int radeon_atombios_init(struct radeon_device *rdev)
|
||||
}
|
||||
|
||||
mutex_init(&rdev->mode_info.atom_context->mutex);
|
||||
mutex_init(&rdev->mode_info.atom_context->scratch_mutex);
|
||||
radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
|
||||
atom_allocate_fb_scratch(rdev->mode_info.atom_context);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user