Commit 08d9a458 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Jens Wiklander
Browse files

tee: shm: Remove refcounting of kernel pages



Earlier TEE subsystem assumed to refcount all the memory pages to be
shared with TEE implementation to be refcounted. However, the slab
allocations within the kernel don't allow refcounting kernel pages.

It is rather better to trust the kernel clients to not free pages while
being shared with TEE implementation. Hence, remove refcounting of kernel
pages from register_shm_helper() API.

Fixes: b9c0e49a ("mm: decline to manipulate the refcount on a slab page")
Reported-by: default avatarMarco Felsch <m.felsch@pengutronix.de>
Reported-by: default avatarSven Püschel <s.pueschel@pengutronix.de>
Signed-off-by: default avatarMatthew Wilcox <willy@infradead.org>
Co-developed-by: default avatarSumit Garg <sumit.garg@oss.qualcomm.com>
Signed-off-by: default avatarSumit Garg <sumit.garg@oss.qualcomm.com>
Tested-by: default avatarSven Püschel <s.pueschel@pengutronix.de>
Signed-off-by: default avatarJens Wiklander <jens.wiklander@linaro.org>
parent 6de23f81
Loading
Loading
Loading
Loading
+0 −27
Original line number Diff line number Diff line
@@ -23,29 +23,11 @@ struct tee_shm_dma_mem {
	struct page *page;
};

static void shm_put_kernel_pages(struct page **pages, size_t page_count)
{
	size_t n;

	for (n = 0; n < page_count; n++)
		put_page(pages[n]);
}

static void shm_get_kernel_pages(struct page **pages, size_t page_count)
{
	size_t n;

	for (n = 0; n < page_count; n++)
		get_page(pages[n]);
}

static void release_registered_pages(struct tee_shm *shm)
{
	if (shm->pages) {
		if (shm->flags & TEE_SHM_USER_MAPPED)
			unpin_user_pages(shm->pages, shm->num_pages);
		else
			shm_put_kernel_pages(shm->pages, shm->num_pages);

		kfree(shm->pages);
	}
@@ -477,13 +459,6 @@ register_shm_helper(struct tee_context *ctx, struct iov_iter *iter, u32 flags,
		goto err_put_shm_pages;
	}

	/*
	 * iov_iter_extract_kvec_pages does not get reference on the pages,
	 * get a reference on them.
	 */
	if (iov_iter_is_kvec(iter))
		shm_get_kernel_pages(shm->pages, num_pages);

	shm->offset = off;
	shm->size = len;
	shm->num_pages = num_pages;
@@ -499,8 +474,6 @@ register_shm_helper(struct tee_context *ctx, struct iov_iter *iter, u32 flags,
err_put_shm_pages:
	if (!iov_iter_is_kvec(iter))
		unpin_user_pages(shm->pages, shm->num_pages);
	else
		shm_put_kernel_pages(shm->pages, shm->num_pages);
err_free_shm_pages:
	kfree(shm->pages);
err_free_shm: