@@ -192,14 +192,61 @@ static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
192
192
return shm ;
193
193
}
194
194
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
+
195
241
static void handle_rpc_func_cmd_shm_alloc (struct tee_context * ctx ,
196
242
struct optee_msg_arg * arg ,
197
243
struct optee_call_ctx * call_ctx )
198
244
{
199
- phys_addr_t pa ;
200
245
struct tee_shm * shm ;
246
+ void * pages_list ;
201
247
size_t sz ;
202
248
size_t n ;
249
+ int rc ;
203
250
204
251
arg -> ret_origin = TEEC_ORIGIN_COMMS ;
205
252
@@ -237,52 +284,16 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
237
284
return ;
238
285
}
239
286
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 ;
242
291
goto bad ;
243
292
}
244
293
245
- sz = tee_shm_get_size (shm );
246
-
247
294
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
-
264
295
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 ;
286
297
}
287
298
288
299
arg -> ret = TEEC_SUCCESS ;
0 commit comments