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

Commit d3394510 authored by Shubhraprakash Das's avatar Shubhraprakash Das
Browse files

msm: kgsl: Fix overlap checking of address range



While checking if an address range can be merged or is contained within
a different address range also check if the type of the ranges are same.
If they are not same then do not merge them. Also, when checking for
overlap condition reduce the size of range by 1 since the last byte
till the size of the range is not a part of the range.

Change-Id: I721e5ee218d9222575516a188b6fc1e8649ecc10
Signed-off-by: default avatarShubhraprakash Das <sadas@codeaurora.org>
parent b4084af2
Loading
Loading
Loading
Loading
+8 −4
Original line number Original line Diff line number Diff line
@@ -86,20 +86,23 @@ static void adreno_ib_merge_range(struct adreno_ib_object *ib_obj,
 * adreno_ib_check_overlap() - Checks if an address range overlap
 * adreno_ib_check_overlap() - Checks if an address range overlap
 * @gpuaddr: The start address range to check for overlap
 * @gpuaddr: The start address range to check for overlap
 * @size: Size of the address range
 * @size: Size of the address range
 * @type: The type of address range
 * @ib_obj_list: The list of address ranges to check for overlap
 * @ib_obj_list: The list of address ranges to check for overlap
 *
 *
 * Checks if an address range overlaps with a list of address ranges
 * Checks if an address range overlaps with a list of address ranges
 * Returns the entry from list which overlaps else NULL
 * Returns the entry from list which overlaps else NULL
 */
 */
static struct adreno_ib_object *adreno_ib_check_overlap(unsigned int gpuaddr,
static struct adreno_ib_object *adreno_ib_check_overlap(unsigned int gpuaddr,
		unsigned int size, struct adreno_ib_object_list *ib_obj_list)
		unsigned int size, int type,
		struct adreno_ib_object_list *ib_obj_list)
{
{
	struct adreno_ib_object *ib_obj;
	struct adreno_ib_object *ib_obj;
	int i;
	int i;


	for (i = 0; i < ib_obj_list->num_objs; i++) {
	for (i = 0; i < ib_obj_list->num_objs; i++) {
		ib_obj = &(ib_obj_list->obj_list[i]);
		ib_obj = &(ib_obj_list->obj_list[i]);
		if (kgsl_addr_range_overlap(ib_obj->gpuaddr, ib_obj->size,
		if ((type == ib_obj->snapshot_obj_type) &&
			kgsl_addr_range_overlap(ib_obj->gpuaddr, ib_obj->size,
			gpuaddr, size))
			gpuaddr, size))
			/* regions overlap */
			/* regions overlap */
			return ib_obj;
			return ib_obj;
@@ -145,7 +148,7 @@ static int adreno_ib_add_range(struct kgsl_device *device,
		gpuaddr = entry->memdesc.gpuaddr;
		gpuaddr = entry->memdesc.gpuaddr;
	}
	}


	ib_obj = adreno_ib_check_overlap(gpuaddr, size, ib_obj_list);
	ib_obj = adreno_ib_check_overlap(gpuaddr, size, type, ib_obj_list);
	if (ib_obj) {
	if (ib_obj) {
		adreno_ib_merge_range(ib_obj, gpuaddr, size);
		adreno_ib_merge_range(ib_obj, gpuaddr, size);
	} else {
	} else {
@@ -714,7 +717,8 @@ static int adreno_ib_find_objs(struct kgsl_device *device,
	/* check that this IB is not already on list */
	/* check that this IB is not already on list */
	for (i = 0; i < ib_obj_list->num_objs; i++) {
	for (i = 0; i < ib_obj_list->num_objs; i++) {
		ib_obj = &(ib_obj_list->obj_list[i]);
		ib_obj = &(ib_obj_list->obj_list[i]);
		if ((ib_obj->gpuaddr <= gpuaddr) &&
		if ((obj_type == ib_obj->snapshot_obj_type) &&
			(ib_obj->gpuaddr <= gpuaddr) &&
			((ib_obj->gpuaddr + ib_obj->size) >=
			((ib_obj->gpuaddr + ib_obj->size) >=
			(gpuaddr + (dwords << 2))))
			(gpuaddr + (dwords << 2))))
			return 0;
			return 0;
+4 −2
Original line number Original line Diff line number Diff line
@@ -355,8 +355,10 @@ static inline bool kgsl_addr_range_overlap(unsigned int gpuaddr1,
		unsigned int size1,
		unsigned int size1,
		unsigned int gpuaddr2, unsigned int size2)
		unsigned int gpuaddr2, unsigned int size2)
{
{
	return !(((gpuaddr1 + size1) < gpuaddr2) ||
	if ((size1 > (UINT_MAX - gpuaddr1)) || (size2 > (UINT_MAX - gpuaddr2)))
		(gpuaddr1 > (gpuaddr2 + size2)));
		return false;
	return !(((gpuaddr1 + size1) <= gpuaddr2) ||
		(gpuaddr1 >= (gpuaddr2 + size2)));
}
}


#endif /* __KGSL_H */
#endif /* __KGSL_H */