Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: 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>
Signed-off-by: Matthew Wilcox <willy@infradead.org>
Co-developed-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
Tested-by: Sven Püschel <s.pueschel@pengutronix.de>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>

authored by

Matthew Wilcox and committed by
Jens Wiklander
08d9a458 6de23f81

-27
-27
drivers/tee/tee_shm.c
··· 23 23 struct page *page; 24 24 }; 25 25 26 - static void shm_put_kernel_pages(struct page **pages, size_t page_count) 27 - { 28 - size_t n; 29 - 30 - for (n = 0; n < page_count; n++) 31 - put_page(pages[n]); 32 - } 33 - 34 - static void shm_get_kernel_pages(struct page **pages, size_t page_count) 35 - { 36 - size_t n; 37 - 38 - for (n = 0; n < page_count; n++) 39 - get_page(pages[n]); 40 - } 41 - 42 26 static void release_registered_pages(struct tee_shm *shm) 43 27 { 44 28 if (shm->pages) { 45 29 if (shm->flags & TEE_SHM_USER_MAPPED) 46 30 unpin_user_pages(shm->pages, shm->num_pages); 47 - else 48 - shm_put_kernel_pages(shm->pages, shm->num_pages); 49 31 50 32 kfree(shm->pages); 51 33 } ··· 459 477 goto err_put_shm_pages; 460 478 } 461 479 462 - /* 463 - * iov_iter_extract_kvec_pages does not get reference on the pages, 464 - * get a reference on them. 465 - */ 466 - if (iov_iter_is_kvec(iter)) 467 - shm_get_kernel_pages(shm->pages, num_pages); 468 - 469 480 shm->offset = off; 470 481 shm->size = len; 471 482 shm->num_pages = num_pages; ··· 474 499 err_put_shm_pages: 475 500 if (!iov_iter_is_kvec(iter)) 476 501 unpin_user_pages(shm->pages, shm->num_pages); 477 - else 478 - shm_put_kernel_pages(shm->pages, shm->num_pages); 479 502 err_free_shm_pages: 480 503 kfree(shm->pages); 481 504 err_free_shm: