Skip to content

Commit c0653ba

Browse files
author
Hernan Gatta
committed
optee: refactor RPC memory allocation function
Allow the logic used to handle allocating shared memory during RPCs to be reusable for other purposes. Specifically, the code in question is necessary to handle shared memory allocation requests for OCALLs. This change refactors that code into a shared function. Signed-off-by: Hernan Gatta <[email protected]>
1 parent 1bfeb47 commit c0653ba

File tree

1 file changed

+53
-42
lines changed

1 file changed

+53
-42
lines changed

drivers/tee/optee/rpc.c

Lines changed: 53 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,61 @@ static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
192192
return shm;
193193
}
194194

195+
int optee_rpc_process_shm_alloc(struct tee_shm *shm,
196+
struct optee_msg_param *msg_param, void **list)
197+
{
198+
phys_addr_t pa;
199+
size_t sz;
200+
201+
struct page **pages;
202+
size_t page_num;
203+
void *pages_list;
204+
205+
if (tee_shm_get_pa(shm, 0, &pa))
206+
return -EINVAL;
207+
208+
sz = tee_shm_get_size(shm);
209+
210+
if (tee_shm_is_registered(shm)) {
211+
pages = tee_shm_get_pages(shm, &page_num);
212+
if (!pages || !page_num)
213+
return -EINVAL;
214+
215+
pages_list = optee_allocate_pages_list(page_num);
216+
if (!pages_list)
217+
return -ENOMEM;
218+
219+
msg_param->attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
220+
OPTEE_MSG_ATTR_NONCONTIG;
221+
msg_param->u.tmem.buf_ptr =
222+
virt_to_phys(pages_list) |
223+
(tee_shm_get_page_offset(shm) &
224+
(OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
225+
msg_param->u.tmem.size = tee_shm_get_size(shm);
226+
msg_param->u.tmem.shm_ref = (unsigned long)shm;
227+
optee_fill_pages_list(pages_list, pages, page_num,
228+
tee_shm_get_page_offset(shm));
229+
*list = pages_list;
230+
} else {
231+
msg_param->attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT;
232+
msg_param->u.tmem.buf_ptr = pa;
233+
msg_param->u.tmem.size = sz;
234+
msg_param->u.tmem.shm_ref = (unsigned long)shm;
235+
*list = NULL;
236+
}
237+
238+
return 0;
239+
}
240+
195241
static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
196242
struct optee_msg_arg *arg,
197243
struct optee_call_ctx *call_ctx)
198244
{
199-
phys_addr_t pa;
200245
struct tee_shm *shm;
246+
void *pages_list;
201247
size_t sz;
202248
size_t n;
249+
int rc;
203250

204251
arg->ret_origin = TEEC_ORIGIN_COMMS;
205252

@@ -237,52 +284,16 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
237284
return;
238285
}
239286

240-
if (tee_shm_get_pa(shm, 0, &pa)) {
241-
arg->ret = TEEC_ERROR_BAD_PARAMETERS;
287+
rc = optee_rpc_process_shm_alloc(shm, &arg->params[0], &pages_list);
288+
if (rc) {
289+
arg->ret = rc == -ENOMEM
290+
? TEEC_ERROR_OUT_OF_MEMORY : TEEC_ERROR_BAD_PARAMETERS;
242291
goto bad;
243292
}
244293

245-
sz = tee_shm_get_size(shm);
246-
247294
if (tee_shm_is_registered(shm)) {
248-
struct page **pages;
249-
u64 *pages_list;
250-
size_t page_num;
251-
252-
pages = tee_shm_get_pages(shm, &page_num);
253-
if (!pages || !page_num) {
254-
arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
255-
goto bad;
256-
}
257-
258-
pages_list = optee_allocate_pages_list(page_num);
259-
if (!pages_list) {
260-
arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
261-
goto bad;
262-
}
263-
264295
call_ctx->pages_list = pages_list;
265-
call_ctx->num_entries = page_num;
266-
267-
arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
268-
OPTEE_MSG_ATTR_NONCONTIG;
269-
/*
270-
* In the least bits of u.tmem.buf_ptr we store buffer offset
271-
* from 4k page, as described in OP-TEE ABI.
272-
*/
273-
arg->params[0].u.tmem.buf_ptr = virt_to_phys(pages_list) |
274-
(tee_shm_get_page_offset(shm) &
275-
(OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
276-
arg->params[0].u.tmem.size = tee_shm_get_size(shm);
277-
arg->params[0].u.tmem.shm_ref = (unsigned long)shm;
278-
279-
optee_fill_pages_list(pages_list, pages, page_num,
280-
tee_shm_get_page_offset(shm));
281-
} else {
282-
arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT;
283-
arg->params[0].u.tmem.buf_ptr = pa;
284-
arg->params[0].u.tmem.size = sz;
285-
arg->params[0].u.tmem.shm_ref = (unsigned long)shm;
296+
call_ctx->num_entries = shm->num_pages;
286297
}
287298

288299
arg->ret = TEEC_SUCCESS;

0 commit comments

Comments
 (0)