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

Commit e90d1e54 authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Fix an overrun while constructing the GPMU load command



The calculation for the size of the buffer to contain the load
commands for the GPMU firmware was off - the size was calculated
using the type4 max size (128) but that includes the opcode, so
it really should have been the payload size (127).

Change-Id: Ic0dedbad1920c94c72ee38bfcd62ce0ac60efeb2
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 53d2912c
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -597,12 +597,24 @@ static void a5xx_enable_pc(struct adreno_device *adreno_dev)
	trace_adreno_sp_tp((unsigned long) __builtin_return_address(0));
};

/*
 * The maximum payload of a type4 packet is the max size minus one for the
 * opcode
 */
#define TYPE4_MAX_PAYLOAD (PM4_TYPE4_PKT_SIZE_MAX - 1)

static int _gpmu_create_load_cmds(struct adreno_device *adreno_dev,
	uint32_t *ucode, uint32_t size)
{
	uint32_t *start, *cmds;
	uint32_t offset = 0;
	uint32_t cmds_size = size + size / PM4_TYPE4_PKT_SIZE_MAX + 5;
	uint32_t cmds_size = size;

	/* Add a dword for each PM4 packet */
	cmds_size += (size / TYPE4_MAX_PAYLOAD) + 1;

	/* Add 4 dwords for the protected mode */
	cmds_size += 4;

	if (adreno_dev->gpmu_cmds != NULL)
		return 0;
@@ -625,8 +637,8 @@ static int _gpmu_create_load_cmds(struct adreno_device *adreno_dev,
	while (size > 0) {
		int tmp_size = size;

		if (size >= PM4_TYPE4_PKT_SIZE_MAX - 1)
			tmp_size = PM4_TYPE4_PKT_SIZE_MAX - 1;
		if (size >= TYPE4_MAX_PAYLOAD)
			tmp_size = TYPE4_MAX_PAYLOAD;

		*cmds++ = cp_type4_packet(
				A5XX_GPMU_INST_RAM_BASE + offset,
@@ -643,7 +655,7 @@ static int _gpmu_create_load_cmds(struct adreno_device *adreno_dev,
	*cmds++ = cp_type7_packet(CP_SET_PROTECTED_MODE, 1);
	*cmds++ = 1;

	adreno_dev->gpmu_cmds_size = cmds - start;
	adreno_dev->gpmu_cmds_size = (size_t) (cmds - start);

	return 0;
}