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

Commit 4ce70e2d authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Don't free memory if locking failed with error EADDRNOTAVAIL"

parents a4369515 ffa2a297
Loading
Loading
Loading
Loading
+32 −8
Original line number Original line Diff line number Diff line
@@ -482,7 +482,7 @@ static void kgsl_page_alloc_unmap_kernel(struct kgsl_memdesc *memdesc)
	mutex_unlock(&kernel_map_global_lock);
	mutex_unlock(&kernel_map_global_lock);
}
}


static int kgsl_lock_sgt(struct sg_table *sgt)
static int kgsl_lock_sgt(struct sg_table *sgt, uint64_t size)
{
{
	struct scatterlist *sg;
	struct scatterlist *sg;
	int dest_perms = PERM_READ | PERM_WRITE;
	int dest_perms = PERM_READ | PERM_WRITE;
@@ -492,12 +492,26 @@ static int kgsl_lock_sgt(struct sg_table *sgt)
	int i;
	int i;


	ret = hyp_assign_table(sgt, &source_vm, 1, &dest_vm, &dest_perms, 1);
	ret = hyp_assign_table(sgt, &source_vm, 1, &dest_vm, &dest_perms, 1);
	if (!ret) {
	if (ret) {
		/*
		 * If returned error code is EADDRNOTAVAIL, then this
		 * memory may no longer be in a usable state as security
		 * state of the pages is unknown after this failure. This
		 * memory can neither be added back to the pool nor buddy
		 * system.
		 */
		if (ret == -EADDRNOTAVAIL)
			pr_err("Failure to lock secure GPU memory 0x%llx bytes will not be recoverable\n",
				size);

		return ret;
	}

	/* Set private bit for each sg to indicate that its secured */
	/* Set private bit for each sg to indicate that its secured */
	for_each_sg(sgt->sgl, sg, sgt->nents, i)
	for_each_sg(sgt->sgl, sg, sgt->nents, i)
		SetPagePrivate(sg_page(sg));
		SetPagePrivate(sg_page(sg));
	}

	return ret;
	return 0;
}
}


static int kgsl_unlock_sgt(struct sg_table *sgt)
static int kgsl_unlock_sgt(struct sg_table *sgt)
@@ -961,11 +975,18 @@ kgsl_sharedmem_page_alloc_user(struct kgsl_memdesc *memdesc,
			goto done;
			goto done;
		}
		}


		ret = kgsl_lock_sgt(memdesc->sgt);
		ret = kgsl_lock_sgt(memdesc->sgt, memdesc->size);
		if (ret) {
		if (ret) {
			sg_free_table(memdesc->sgt);
			sg_free_table(memdesc->sgt);
			kfree(memdesc->sgt);
			kfree(memdesc->sgt);
			memdesc->sgt = NULL;
			memdesc->sgt = NULL;

			if (ret == -EADDRNOTAVAIL) {
				kgsl_free(memdesc->pages);
				memset(memdesc, 0, sizeof(*memdesc));
				return ret;
			}

			goto done;
			goto done;
		}
		}


@@ -1068,8 +1089,11 @@ struct page *kgsl_alloc_secure_page(void)
	sg_init_table(&sgl, 1);
	sg_init_table(&sgl, 1);
	sg_set_page(&sgl, page, PAGE_SIZE, 0);
	sg_set_page(&sgl, page, PAGE_SIZE, 0);


	status = kgsl_lock_sgt(&sgt);
	status = kgsl_lock_sgt(&sgt, PAGE_SIZE);
	if (status) {
	if (status) {
		if (status == -EADDRNOTAVAIL)
			return NULL;

		__free_page(page);
		__free_page(page);
		return NULL;
		return NULL;
	}
	}