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

staging: sep: Basic infrastructure for SEP DMA access to non CPU regions

[This is picked out of the differences between the upstream driver and
the staging driver. I'm resolving the differences as a series of updates -AC]

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Mark A. Allyn and committed by
Greg Kroah-Hartman
aca58ec8 ffcf1281

+223 -25
+14 -1
drivers/staging/sep/sep_driver_api.h
··· 61 61 HASH_INIT, 62 62 HASH_UPDATE, 63 63 HASH_FINISH, 64 - HASH_DIGEST 64 + HASH_DIGEST, 65 + HASH_FINUP_DATA, 66 + HASH_FINUP_FINISH 65 67 }; 66 68 67 69 /* ··· 207 205 */ 208 206 struct sep_fastcall_hdr { 209 207 u32 magic; 208 + u32 secure_dma; 210 209 u32 msg_len; 211 210 u32 num_dcbs; 212 211 }; ··· 234 231 u32 dmatables_len; 235 232 /* size of input data */ 236 233 u32 input_data_len; 234 + /* secure dma use (for imr memory restriced area in output */ 235 + bool secure_dma; 237 236 struct sep_dma_resource dma_res_arr[SEP_MAX_NUM_SYNC_DMA_OPS]; 238 237 /* Scatter gather for kernel crypto */ 239 238 struct scatterlist *src_sg; ··· 322 317 * @tail_block_size: u32; for size of tail block 323 318 * @isapplet: bool; to indicate external app 324 319 * @is_kva: bool; kernel buffer; only used for kernel crypto module 320 + * @secure_dma; indicates whether this is secure_dma using IMR 325 321 * 326 322 * This function prepares the linked DMA tables and puts the 327 323 * address for the linked list of tables inta a DCB (data control ··· 338 332 u32 tail_block_size, 339 333 bool isapplet, 340 334 bool is_kva, 335 + bool secure_dma, 341 336 struct sep_dcblock *dcb_region, 342 337 void **dmatables_region, 343 338 struct sep_dma_context **dma_ctx, ··· 392 385 _IO(SEP_IOC_MAGIC_NUMBER, 36) 393 386 394 387 struct sep_device; 388 + 389 + #define SEP_IOCPREPAREDCB_SECURE_DMA \ 390 + _IOW(SEP_IOC_MAGIC_NUMBER, 38, struct build_dcb_struct) 391 + 392 + #define SEP_IOCFREEDCB_SECURE_DMA \ 393 + _IO(SEP_IOC_MAGIC_NUMBER, 39) 395 394 396 395 #endif
+209 -24
drivers/staging/sep/sep_main.c
··· 485 485 kfree(dma->in_map_array); 486 486 } 487 487 488 - /* Unmap output map array, DON'T free it yet */ 489 - if (dma->out_map_array) { 488 + /** 489 + * Output is handled different. If 490 + * this was a secure dma into restricted memory, 491 + * then we skip this step altogether as restricted 492 + * memory is not available to the o/s at all. 493 + */ 494 + if (((*dma_ctx)->secure_dma == false) && 495 + (dma->out_map_array)) { 496 + 490 497 for (count = 0; count < dma->out_num_pages; count++) { 491 498 dma_unmap_page(&sep->pdev->dev, 492 499 dma->out_map_array[count].dma_addr, ··· 512 505 kfree(dma->in_page_array); 513 506 } 514 507 515 - if (dma->out_page_array) { 508 + /* Again, we do this only for non secure dma */ 509 + if (((*dma_ctx)->secure_dma == false) && 510 + (dma->out_page_array)) { 511 + 516 512 for (count = 0; count < dma->out_num_pages; count++) { 517 513 if (!PageReserved(dma->out_page_array[count])) 518 514 ··· 1393 1383 } 1394 1384 1395 1385 /** 1386 + * sep_lli_table_secure_dma - get lli array for IMR addresses 1387 + * @sep: pointer to struct sep_device 1388 + * @app_virt_addr: user memory data buffer 1389 + * @data_size: size of data buffer 1390 + * @lli_array_ptr: lli array 1391 + * @in_out_flag: not used 1392 + * @dma_ctx: pointer to struct sep_dma_context 1393 + * 1394 + * This function creates lli tables for outputting data to 1395 + * IMR memory, which is memory that cannot be accessed by the 1396 + * the x86 processor. 1397 + */ 1398 + static int sep_lli_table_secure_dma(struct sep_device *sep, 1399 + u32 app_virt_addr, 1400 + u32 data_size, 1401 + struct sep_lli_entry **lli_array_ptr, 1402 + int in_out_flag, 1403 + struct sep_dma_context *dma_ctx) 1404 + 1405 + { 1406 + int error = 0; 1407 + u32 count; 1408 + /* The the page of the end address of the user space buffer */ 1409 + u32 end_page; 1410 + /* The page of the start address of the user space buffer */ 1411 + u32 start_page; 1412 + /* The range in pages */ 1413 + u32 num_pages; 1414 + /* Array of lli */ 1415 + struct sep_lli_entry *lli_array; 1416 + 1417 + /* Set start and end pages and num pages */ 1418 + end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; 1419 + start_page = app_virt_addr >> PAGE_SHIFT; 1420 + num_pages = end_page - start_page + 1; 1421 + 1422 + dev_dbg(&sep->pdev->dev, "[PID%d] lock user pages" 1423 + " app_virt_addr is %x\n", current->pid, app_virt_addr); 1424 + 1425 + dev_dbg(&sep->pdev->dev, "[PID%d] data_size is (hex) %x\n", 1426 + current->pid, data_size); 1427 + dev_dbg(&sep->pdev->dev, "[PID%d] start_page is (hex) %x\n", 1428 + current->pid, start_page); 1429 + dev_dbg(&sep->pdev->dev, "[PID%d] end_page is (hex) %x\n", 1430 + current->pid, end_page); 1431 + dev_dbg(&sep->pdev->dev, "[PID%d] num_pages is (hex) %x\n", 1432 + current->pid, num_pages); 1433 + 1434 + lli_array = kmalloc(sizeof(struct sep_lli_entry) * num_pages, 1435 + GFP_ATOMIC); 1436 + 1437 + if (!lli_array) { 1438 + dev_warn(&sep->pdev->dev, 1439 + "[PID%d] kmalloc for lli_array failed\n", 1440 + current->pid); 1441 + return -ENOMEM; 1442 + } 1443 + 1444 + /* 1445 + * Fill the lli_array 1446 + */ 1447 + start_page = start_page << PAGE_SHIFT; 1448 + for (count = 0; count < num_pages; count++) { 1449 + /* Fill the lli array entry */ 1450 + lli_array[count].bus_address = start_page; 1451 + lli_array[count].block_size = PAGE_SIZE; 1452 + 1453 + start_page += PAGE_SIZE; 1454 + 1455 + dev_dbg(&sep->pdev->dev, 1456 + "[PID%d] lli_array[%x].bus_address is %08lx, " 1457 + "lli_array[%x].block_size is (hex) %x\n", 1458 + current->pid, 1459 + count, (unsigned long)lli_array[count].bus_address, 1460 + count, lli_array[count].block_size); 1461 + } 1462 + 1463 + /* Check the offset for the first page */ 1464 + lli_array[0].bus_address = 1465 + lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK)); 1466 + 1467 + /* Check that not all the data is in the first page only */ 1468 + if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size) 1469 + lli_array[0].block_size = data_size; 1470 + else 1471 + lli_array[0].block_size = 1472 + PAGE_SIZE - (app_virt_addr & (~PAGE_MASK)); 1473 + 1474 + dev_dbg(&sep->pdev->dev, 1475 + "[PID%d] After check if page 0 has all data\n" 1476 + "lli_array[0].bus_address is (hex) %08lx, " 1477 + "lli_array[0].block_size is (hex) %x\n", 1478 + current->pid, 1479 + (unsigned long)lli_array[0].bus_address, 1480 + lli_array[0].block_size); 1481 + 1482 + /* Check the size of the last page */ 1483 + if (num_pages > 1) { 1484 + lli_array[num_pages - 1].block_size = 1485 + (app_virt_addr + data_size) & (~PAGE_MASK); 1486 + if (lli_array[num_pages - 1].block_size == 0) 1487 + lli_array[num_pages - 1].block_size = PAGE_SIZE; 1488 + 1489 + dev_dbg(&sep->pdev->dev, 1490 + "[PID%d] After last page size adjustment\n" 1491 + "lli_array[%x].bus_address is (hex) %08lx, " 1492 + "lli_array[%x].block_size is (hex) %x\n", 1493 + current->pid, num_pages - 1, 1494 + (unsigned long)lli_array[num_pages - 1].bus_address, 1495 + num_pages - 1, 1496 + lli_array[num_pages - 1].block_size); 1497 + } 1498 + *lli_array_ptr = lli_array; 1499 + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages = num_pages; 1500 + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL; 1501 + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array = NULL; 1502 + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_num_entries = 0; 1503 + 1504 + return error; 1505 + } 1506 + 1507 + /** 1396 1508 * sep_calculate_lli_table_max_size - size the LLI table 1397 1509 * @sep: pointer to struct sep_device 1398 1510 * @lli_in_array_ptr ··· 1745 1613 unsigned long num_table_entries, 1746 1614 unsigned long table_data_size) 1747 1615 { 1616 + #ifdef DEBUG 1748 1617 unsigned long table_count = 1; 1749 1618 unsigned long entries_count = 0; 1750 1619 ··· 1819 1686 } 1820 1687 dev_dbg(&sep->pdev->dev, "[PID%d] sep_debug_print_lli_tables end\n", 1821 1688 current->pid); 1689 + #endif 1822 1690 } 1823 1691 1824 1692 ··· 2090 1956 end_function_error: 2091 1957 /* Free all the allocated resources */ 2092 1958 kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array); 1959 + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array = NULL; 2093 1960 kfree(lli_array_ptr); 2094 1961 kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array); 1962 + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL; 2095 1963 2096 1964 end_function: 2097 1965 return error; ··· 2496 2360 goto end_function; 2497 2361 } 2498 2362 2499 - dev_dbg(&sep->pdev->dev, "[PID%d] Locking user output pages\n", 2363 + if (dma_ctx->secure_dma == true) { 2364 + /* secure_dma requires use of non accessible memory */ 2365 + dev_dbg(&sep->pdev->dev, "[PID%d] in secure_dma\n", 2366 + current->pid); 2367 + error = sep_lli_table_secure_dma(sep, 2368 + app_virt_out_addr, data_size, &lli_out_array, 2369 + SEP_DRIVER_OUT_FLAG, dma_ctx); 2370 + if (error) { 2371 + dev_warn(&sep->pdev->dev, 2372 + "[PID%d] secure dma table setup " 2373 + " for output virtual buffer failed\n", 2374 + current->pid); 2375 + 2376 + goto end_function_free_lli_in; 2377 + } 2378 + } else { 2379 + /* For normal, non-secure dma */ 2380 + dev_dbg(&sep->pdev->dev, "[PID%d] not in secure_dma\n", 2500 2381 current->pid); 2501 2382 2502 - error = sep_lock_user_pages(sep, app_virt_out_addr, 2383 + dev_dbg(&sep->pdev->dev, 2384 + "[PID%d] Locking user output pages\n", 2385 + current->pid); 2386 + 2387 + error = sep_lock_user_pages(sep, app_virt_out_addr, 2503 2388 data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG, 2504 2389 dma_ctx); 2505 2390 2506 - if (error) { 2507 - dev_warn(&sep->pdev->dev, 2391 + if (error) { 2392 + dev_warn(&sep->pdev->dev, 2508 2393 "[PID%d] sep_lock_user_pages" 2509 2394 " for output virtual buffer failed\n", 2510 2395 current->pid); 2511 2396 2512 - goto end_function_free_lli_in; 2397 + goto end_function_free_lli_in; 2398 + } 2513 2399 } 2514 2400 } 2515 2401 ··· 2579 2421 2580 2422 end_function_with_error: 2581 2423 kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array); 2424 + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array = NULL; 2582 2425 kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array); 2426 + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL; 2583 2427 kfree(lli_out_array); 2584 2428 2585 2429 2586 2430 end_function_free_lli_in: 2587 2431 kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array); 2432 + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array = NULL; 2588 2433 kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array); 2434 + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL; 2589 2435 kfree(lli_in_array); 2590 2436 2591 2437 end_function: ··· 2607 2445 * @tail_block_size: u32; for size of tail block 2608 2446 * @isapplet: bool; to indicate external app 2609 2447 * @is_kva: bool; kernel buffer; only used for kernel crypto module 2448 + * @secure_dma; indicates whether this is secure_dma using IMR 2610 2449 * 2611 2450 * This function prepares the linked DMA tables and puts the 2612 2451 * address for the linked list of tables inta a DCB (data control ··· 2623 2460 u32 tail_block_size, 2624 2461 bool isapplet, 2625 2462 bool is_kva, 2463 + bool secure_dma, 2626 2464 struct sep_dcblock *dcb_region, 2627 2465 void **dmatables_region, 2628 2466 struct sep_dma_context **dma_ctx, ··· 2697 2533 "[PID%d] Created DMA context addr at 0x%p\n", 2698 2534 current->pid, *dma_ctx); 2699 2535 } 2536 + 2537 + (*dma_ctx)->secure_dma = secure_dma; 2700 2538 2701 2539 /* these are for kernel crypto only */ 2702 2540 (*dma_ctx)->src_sg = src_sg; ··· 2856 2690 2857 2691 end_function_error: 2858 2692 kfree(*dma_ctx); 2693 + *dma_ctx = NULL; 2859 2694 2860 2695 end_function: 2861 2696 return error; ··· 2886 2719 dev_dbg(&sep->pdev->dev, "[PID%d] sep_free_dma_tables_and_dcb\n", 2887 2720 current->pid); 2888 2721 2889 - if (isapplet == true) { 2722 + if (((*dma_ctx)->secure_dma == false) && (isapplet == true)) { 2723 + dev_dbg(&sep->pdev->dev, "[PID%d] handling applet\n", 2724 + current->pid); 2725 + 2726 + /* Tail stuff is only for non secure_dma */ 2890 2727 /* Set pointer to first DCB table */ 2891 2728 dcb_table_ptr = (struct sep_dcblock *) 2892 2729 (sep->shared_addr + 2893 2730 SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES); 2894 2731 2895 - /* Go over each DCB and see if tail pointer must be updated */ 2896 - for (i = 0; 2897 - i < (*dma_ctx)->nr_dcb_creat; i++, dcb_table_ptr++) { 2732 + /** 2733 + * Go over each DCB and see if 2734 + * tail pointer must be updated 2735 + */ 2736 + for (i = 0; dma_ctx && *dma_ctx && 2737 + i < (*dma_ctx)->nr_dcb_creat; i++, dcb_table_ptr++) { 2898 2738 if (dcb_table_ptr->out_vr_tail_pt) { 2899 2739 pt_hold = (unsigned long)dcb_table_ptr-> 2900 2740 out_vr_tail_pt; ··· 2923 2749 } 2924 2750 } 2925 2751 } 2752 + 2926 2753 /* Free the output pages, if any */ 2927 2754 sep_free_dma_table_data_handler(sep, dma_ctx); 2928 2755 ··· 2937 2762 * sep_prepare_dcb_handler - prepare a control block 2938 2763 * @sep: pointer to struct sep_device 2939 2764 * @arg: pointer to user parameters 2765 + * @secure_dma: indicate whether we are using secure_dma on IMR 2940 2766 * 2941 2767 * This function will retrieve the RAR buffer physical addresses, type 2942 2768 * & size corresponding to the RAR handles provided in the buffers vector. 2943 2769 */ 2944 2770 static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg, 2771 + bool secure_dma, 2945 2772 struct sep_dma_context **dma_ctx) 2946 2773 { 2947 2774 int error; ··· 2989 2812 command_args.data_in_size, command_args.block_size, 2990 2813 command_args.tail_block_size, 2991 2814 command_args.is_applet, false, 2992 - NULL, NULL, dma_ctx, NULL, NULL); 2815 + secure_dma, NULL, NULL, dma_ctx, NULL, NULL); 2993 2816 2994 2817 end_function: 2995 2818 return error; ··· 3006 2829 static int sep_free_dcb_handler(struct sep_device *sep, 3007 2830 struct sep_dma_context **dma_ctx) 3008 2831 { 3009 - int error = 0; 3010 - 3011 2832 if (!dma_ctx || !(*dma_ctx)) { 3012 - dev_dbg(&sep->pdev->dev, "[PID%d] no dma context defined, nothing to free\n", 2833 + dev_dbg(&sep->pdev->dev, 2834 + "[PID%d] no dma context defined, nothing to free\n", 3013 2835 current->pid); 3014 - return error; 2836 + return -EINVAL; 3015 2837 } 3016 2838 3017 2839 dev_dbg(&sep->pdev->dev, "[PID%d] free dcbs num of DCBs %x\n", 3018 2840 current->pid, 3019 2841 (*dma_ctx)->nr_dcb_creat); 3020 2842 3021 - error = sep_free_dma_tables_and_dcb(sep, false, false, dma_ctx); 3022 - 3023 - return error; 2843 + return sep_free_dma_tables_and_dcb(sep, false, false, dma_ctx); 3024 2844 } 3025 2845 3026 2846 /** ··· 3105 2931 goto end_function; 3106 2932 } 3107 2933 3108 - error = sep_prepare_dcb_handler(sep, arg, dma_ctx); 2934 + error = sep_prepare_dcb_handler(sep, arg, false, dma_ctx); 3109 2935 dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCPREPAREDCB end\n", 3110 2936 current->pid); 3111 2937 break; ··· 3344 3170 * @dma_ctx: DMA context buf to create for current transaction 3345 3171 * @user_dcb_args: User arguments for DCB/MLLI creation 3346 3172 * @num_dcbs: Number of DCBs to create 3173 + * @secure_dma: Indicate use of IMR restricted memory secure dma 3347 3174 */ 3348 3175 static ssize_t sep_create_dcb_dmatables_context(struct sep_device *sep, 3349 3176 struct sep_dcblock **dcb_region, 3350 3177 void **dmatables_region, 3351 3178 struct sep_dma_context **dma_ctx, 3352 3179 const struct build_dcb_struct __user *user_dcb_args, 3353 - const u32 num_dcbs) 3180 + const u32 num_dcbs, bool secure_dma) 3354 3181 { 3355 3182 int error = 0; 3356 3183 int i = 0; ··· 3406 3231 dcb_args[i].block_size, 3407 3232 dcb_args[i].tail_block_size, 3408 3233 dcb_args[i].is_applet, 3409 - false, 3234 + false, secure_dma, 3410 3235 *dcb_region, dmatables_region, 3411 3236 dma_ctx, 3412 3237 NULL, ··· 3417 3242 current->pid); 3418 3243 goto end_function; 3419 3244 } 3245 + 3246 + if (dcb_args[i].app_in_address != 0) 3247 + (*dma_ctx)->input_data_len += dcb_args[i].data_in_size; 3420 3248 } 3421 3249 3422 3250 end_function: ··· 3489 3311 dcb_data->tail_block_size, 3490 3312 dcb_data->is_applet, 3491 3313 true, 3314 + false, 3492 3315 *dcb_region, dmatables_region, 3493 3316 dma_ctx, 3494 3317 dcb_data->src_sg, ··· 3776 3597 struct sep_dcblock *dcb_region = NULL; 3777 3598 ssize_t error = 0; 3778 3599 struct sep_queue_info *my_queue_elem = NULL; 3600 + bool my_secure_dma; /* are we using secure_dma (IMR)? */ 3779 3601 3780 3602 dev_dbg(&sep->pdev->dev, "[PID%d] sep dev is 0x%p\n", 3781 3603 current->pid, sep); ··· 3788 3608 goto end_function; 3789 3609 3790 3610 buf_user += sizeof(struct sep_fastcall_hdr); 3611 + 3612 + if (call_hdr.secure_dma == 0) 3613 + my_secure_dma = false; 3614 + else 3615 + my_secure_dma = true; 3791 3616 3792 3617 /* 3793 3618 * Controlling driver memory usage by limiting amount of ··· 3821 3636 &dma_ctx, 3822 3637 (const struct build_dcb_struct __user *) 3823 3638 buf_user, 3824 - call_hdr.num_dcbs); 3639 + call_hdr.num_dcbs, my_secure_dma); 3825 3640 if (error) 3826 3641 goto end_function_error_doublebuf; 3827 3642