From: Sumit Garg sumit.garg@oss.qualcomm.com
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: b9c0e49abfca ("mm: decline to manipulate the refcount on a slab page") Reported-by: Marco Felsch m.felsch@pengutronix.de Reported-by: Sven Püschel s.pueschel@pengutronix.de Suggested-by: Matthew Wilcox willy@infradead.org Signed-off-by: Sumit Garg sumit.garg@oss.qualcomm.com --- drivers/tee/tee_shm.c | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-)
diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index 4a47de4bb2e5..54e2ba3afb25 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -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; @@ -497,10 +472,8 @@ register_shm_helper(struct tee_context *ctx, struct iov_iter *iter, u32 flags,
return shm; err_put_shm_pages: - if (!iov_iter_is_kvec(iter)) + if (iter_is_uvec(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:
On Fri, Feb 13, 2026 at 05:03:17PM +0530, Sumit Garg wrote:
From: Sumit Garg sumit.garg@oss.qualcomm.com
Um, this patch is exactly the patch I sent. You're stealing my authorship! This patch should have my From: and Signed-off-by: lines. Your role in this is "handling and transporting the patch" (see Documentation/process/submitting-patches.rst). By all means take credit for writing the commit message.
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: b9c0e49abfca ("mm: decline to manipulate the refcount on a slab page") Reported-by: Marco Felsch m.felsch@pengutronix.de Reported-by: Sven Püschel s.pueschel@pengutronix.de Suggested-by: Matthew Wilcox willy@infradead.org Signed-off-by: Sumit Garg sumit.garg@oss.qualcomm.com
drivers/tee/tee_shm.c | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-)
diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index 4a47de4bb2e5..54e2ba3afb25 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -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);
elseshm_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;
@@ -497,10 +472,8 @@ register_shm_helper(struct tee_context *ctx, struct iov_iter *iter, u32 flags, return shm; err_put_shm_pages:
- if (!iov_iter_is_kvec(iter))
- if (iter_is_uvec(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: -- 2.51.0
op-tee@lists.trustedfirmware.org