Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5fe40ed2 authored by Aric Cyr's avatar Aric Cyr Committed by Greg Kroah-Hartman
Browse files

drm/amd/display: dal_ddc_i2c_payloads_create can fail causing panic



[ Upstream commit 6a6c4a4d459ecacc9013c45dcbf2bc9747fdbdbd ]

[Why]
Since the i2c payload allocation can fail need to check return codes

[How]
Clean up i2c payload allocations and check for errors

Signed-off-by: default avatarAric Cyr <aric.cyr@amd.com>
Reviewed-by: default avatarJoshua Aberback <Joshua.Aberback@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 7fbd24e0
Loading
Loading
Loading
Loading
+25 −27
Original line number Diff line number Diff line
@@ -127,22 +127,16 @@ struct aux_payloads {
	struct vector payloads;
};

static struct i2c_payloads *dal_ddc_i2c_payloads_create(struct dc_context *ctx, uint32_t count)
static bool dal_ddc_i2c_payloads_create(
		struct dc_context *ctx,
		struct i2c_payloads *payloads,
		uint32_t count)
{
	struct i2c_payloads *payloads;

	payloads = kzalloc(sizeof(struct i2c_payloads), GFP_KERNEL);

	if (!payloads)
		return NULL;

	if (dal_vector_construct(
		&payloads->payloads, ctx, count, sizeof(struct i2c_payload)))
		return payloads;

	kfree(payloads);
	return NULL;
		return true;

	return false;
}

static struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p)
@@ -155,14 +149,12 @@ static uint32_t dal_ddc_i2c_payloads_get_count(struct i2c_payloads *p)
	return p->payloads.count;
}

static void dal_ddc_i2c_payloads_destroy(struct i2c_payloads **p)
static void dal_ddc_i2c_payloads_destroy(struct i2c_payloads *p)
{
	if (!p || !*p)
	if (!p)
		return;
	dal_vector_destruct(&(*p)->payloads);
	kfree(*p);
	*p = NULL;

	dal_vector_destruct(&p->payloads);
}

static struct aux_payloads *dal_ddc_aux_payloads_create(struct dc_context *ctx, uint32_t count)
@@ -580,9 +572,13 @@ bool dal_ddc_service_query_ddc_data(

	uint32_t payloads_num = write_payloads + read_payloads;


	if (write_size > EDID_SEGMENT_SIZE || read_size > EDID_SEGMENT_SIZE)
		return false;

	if (!payloads_num)
		return false;

	/*TODO: len of payload data for i2c and aux is uint8!!!!,
	 *  but we want to read 256 over i2c!!!!*/
	if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) {
@@ -613,23 +609,25 @@ bool dal_ddc_service_query_ddc_data(
		dal_ddc_aux_payloads_destroy(&payloads);

	} else {
		struct i2c_payloads *payloads =
			dal_ddc_i2c_payloads_create(ddc->ctx, payloads_num);
		struct i2c_command command = {0};
		struct i2c_payloads payloads;

		struct i2c_command command = {
			.payloads = dal_ddc_i2c_payloads_get(payloads),
			.number_of_payloads = 0,
			.engine = DDC_I2C_COMMAND_ENGINE,
			.speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
		if (!dal_ddc_i2c_payloads_create(ddc->ctx, &payloads, payloads_num))
			return false;

		command.payloads = dal_ddc_i2c_payloads_get(&payloads);
		command.number_of_payloads = 0;
		command.engine = DDC_I2C_COMMAND_ENGINE;
		command.speed = ddc->ctx->dc->caps.i2c_speed_in_khz;

		dal_ddc_i2c_payloads_add(
			payloads, address, write_size, write_buf, true);
			&payloads, address, write_size, write_buf, true);

		dal_ddc_i2c_payloads_add(
			payloads, address, read_size, read_buf, false);
			&payloads, address, read_size, read_buf, false);

		command.number_of_payloads =
			dal_ddc_i2c_payloads_get_count(payloads);
			dal_ddc_i2c_payloads_get_count(&payloads);

		ret = dm_helpers_submit_i2c(
				ddc->ctx,