diff options
author | Ira Weiny <ira.weiny@intel.com> | 2023-02-03 20:06:34 -0800 |
---|---|---|
committer | Jens Wiklander <jens.wiklander@linaro.org> | 2023-02-13 14:16:40 +0100 |
commit | 0249a75b365911f91b87935bc08a4795a6fa7dd0 (patch) | |
tree | 49f9d088d7dfaaa7ae7fc9d8873fa6684c646d5e /drivers/tee | |
parent | c83900393aa133d5fefdbf2ab3377c7fbeec0c07 (diff) | |
download | lwn-0249a75b365911f91b87935bc08a4795a6fa7dd0.tar.gz lwn-0249a75b365911f91b87935bc08a4795a6fa7dd0.zip |
tee: Remove call to get_kernel_pages()
The kernel pages used by shm_get_kernel_pages() are allocated using
GFP_KERNEL through the following call stack:
trusted_instantiate()
trusted_payload_alloc() -> GFP_KERNEL
<trusted key op>
tee_shm_register_kernel_buf()
register_shm_helper()
shm_get_kernel_pages()
Where <trusted key op> is one of:
trusted_key_unseal()
trusted_key_get_random()
trusted_key_seal()
Because the pages can't be from highmem get_kernel_pages() boils down to
a get_page() call.
Remove the get_kernel_pages() call and open code the get_page().
In case a highmem page does slip through warn on once for a kmap'ed
address.
Cc: Jens Wiklander <jens.wiklander@linaro.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: "Fabio M. De Francesco" <fmdefrancesco@gmail.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'drivers/tee')
-rw-r--r-- | drivers/tee/tee_shm.c | 21 |
1 files changed, 8 insertions, 13 deletions
diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index 527a6eabc03e..b1c6231defad 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -11,6 +11,7 @@ #include <linux/tee_drv.h> #include <linux/uaccess.h> #include <linux/uio.h> +#include <linux/highmem.h> #include "tee_private.h" static void shm_put_kernel_pages(struct page **pages, size_t page_count) @@ -24,26 +25,20 @@ static void shm_put_kernel_pages(struct page **pages, size_t page_count) static int shm_get_kernel_pages(unsigned long start, size_t page_count, struct page **pages) { - struct kvec *kiov; + struct page *page; size_t n; - int rc; - if (WARN_ON_ONCE(is_vmalloc_addr((void *)start))) + if (WARN_ON_ONCE(is_vmalloc_addr((void *)start) || + is_kmap_addr((void *)start))) return -EINVAL; - kiov = kcalloc(page_count, sizeof(*kiov), GFP_KERNEL); - if (!kiov) - return -ENOMEM; - + page = virt_to_page(start); for (n = 0; n < page_count; n++) { - kiov[n].iov_base = (void *)(start + n * PAGE_SIZE); - kiov[n].iov_len = PAGE_SIZE; + pages[n] = page + n; + get_page(pages[n]); } - rc = get_kernel_pages(kiov, page_count, 0, pages); - kfree(kiov); - - return rc; + return page_count; } static void release_registered_pages(struct tee_shm *shm) |