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

Commit d321ac0a 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 388c29ac 61576b99
Loading
Loading
Loading
Loading
+32 −8
Original line number Diff line number Diff line
@@ -469,7 +469,7 @@ static void kgsl_page_alloc_unmap_kernel(struct kgsl_memdesc *memdesc)
	mutex_unlock(&kernel_map_global_lock);
}

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

	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 */
	for_each_sg(sgt->sgl, sg, sgt->nents, i)
		SetPagePrivate(sg_page(sg));
	}
	return ret;

	return 0;
}

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

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

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

			goto done;
		}

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

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

		__free_page(page);
		return NULL;
	}