|
9 | 9 | #include <linux/sched.h>
|
10 | 10 | #include <linux/slab.h>
|
11 | 11 | #include <linux/tee_drv.h>
|
| 12 | +#include <linux/uio.h> |
12 | 13 | #include "tee_private.h"
|
13 | 14 |
|
14 | 15 | static void tee_shm_release(struct tee_shm *shm)
|
@@ -185,14 +186,15 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
|
185 | 186 | size_t length, u32 flags)
|
186 | 187 | {
|
187 | 188 | struct tee_device *teedev = ctx->teedev;
|
188 |
| - const u32 req_flags = TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED; |
| 189 | + const u32 req_user_flags = TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED; |
| 190 | + const u32 req_kernel_flags = TEE_SHM_DMA_BUF | TEE_SHM_KERNEL_MAPPED; |
189 | 191 | struct tee_shm *shm;
|
190 | 192 | void *ret;
|
191 | 193 | int rc;
|
192 | 194 | int num_pages;
|
193 | 195 | unsigned long start;
|
194 | 196 |
|
195 |
| - if (flags != req_flags) |
| 197 | + if (flags != req_user_flags && flags != req_kernel_flags) |
196 | 198 | return ERR_PTR(-ENOTSUPP);
|
197 | 199 |
|
198 | 200 | if (!tee_device_get(teedev))
|
@@ -226,7 +228,27 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
|
226 | 228 | goto err;
|
227 | 229 | }
|
228 | 230 |
|
229 |
| - rc = get_user_pages_fast(start, num_pages, FOLL_WRITE, shm->pages); |
| 231 | + if (flags & TEE_SHM_USER_MAPPED) { |
| 232 | + rc = get_user_pages_fast(start, num_pages, FOLL_WRITE, |
| 233 | + shm->pages); |
| 234 | + } else { |
| 235 | + struct kvec *kiov; |
| 236 | + int i; |
| 237 | + |
| 238 | + kiov = kcalloc(num_pages, sizeof(*kiov), GFP_KERNEL); |
| 239 | + if (!kiov) { |
| 240 | + ret = ERR_PTR(-ENOMEM); |
| 241 | + goto err; |
| 242 | + } |
| 243 | + |
| 244 | + for (i = 0; i < num_pages; i++) { |
| 245 | + kiov[i].iov_base = (void *)(start + i * PAGE_SIZE); |
| 246 | + kiov[i].iov_len = PAGE_SIZE; |
| 247 | + } |
| 248 | + |
| 249 | + rc = get_kernel_pages(kiov, num_pages, 0, shm->pages); |
| 250 | + kfree(kiov); |
| 251 | + } |
230 | 252 | if (rc > 0)
|
231 | 253 | shm->num_pages = rc;
|
232 | 254 | if (rc != num_pages) {
|
|
0 commit comments