b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | From 0ad840e46732e95df274a84b042dcb210be9f946 Mon Sep 17 00:00:00 2001 |
| 2 | From: Roy Pledge <roy.pledge@nxp.com> |
| 3 | Date: Thu, 28 Mar 2019 09:56:35 -0400 |
| 4 | Subject: [PATCH] sdk_qbman: Avoid variable length array in USDPAA |
| 5 | |
| 6 | As of Linux 5.0 variable length arrays on the stack are no |
| 7 | longer allowed. Change to a dynamic array and create a common |
| 8 | exit point in the function for cleanup. |
| 9 | |
| 10 | Signed-off-by: Roy Pledge <roy.pledge@nxp.com> |
| 11 | --- |
| 12 | drivers/staging/fsl_qbman/fsl_usdpaa.c | 36 +++++++++++++++++----------------- |
| 13 | 1 file changed, 18 insertions(+), 18 deletions(-) |
| 14 | |
| 15 | --- a/drivers/staging/fsl_qbman/fsl_usdpaa.c |
| 16 | +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c |
| 17 | @@ -559,6 +559,7 @@ static bool check_portal_channel(void *c |
| 18 | |
| 19 | static int usdpaa_release(struct inode *inode, struct file *filp) |
| 20 | { |
| 21 | + int err = 0; |
| 22 | struct ctx *ctx = filp->private_data; |
| 23 | struct mem_mapping *map, *tmpmap; |
| 24 | struct portal_mapping *portal, *tmpportal; |
| 25 | @@ -569,9 +570,14 @@ static int usdpaa_release(struct inode * |
| 26 | struct qm_portal_config *qm_alloced_portal = NULL; |
| 27 | struct bm_portal_config *bm_alloced_portal = NULL; |
| 28 | |
| 29 | - struct qm_portal *portal_array[qman_portal_max]; |
| 30 | + struct qm_portal **portal_array; |
| 31 | int portal_count = 0; |
| 32 | |
| 33 | + portal_array = kmalloc_array(qman_portal_max, |
| 34 | + sizeof(struct qm_portal *), GFP_KERNEL); |
| 35 | + if (!portal_array) |
| 36 | + return -ENOMEM; |
| 37 | + |
| 38 | /* Ensure the release operation cannot be migrated to another |
| 39 | CPU as CPU specific variables may be needed during cleanup */ |
| 40 | #ifdef CONFIG_PREEMPT_RT_FULL |
| 41 | @@ -612,18 +618,14 @@ static int usdpaa_release(struct inode * |
| 42 | qm_alloced_portal = qm_get_unused_portal(); |
| 43 | if (!qm_alloced_portal) { |
| 44 | pr_crit("No QMan portal avalaible for cleanup\n"); |
| 45 | -#ifdef CONFIG_PREEMPT_RT_FULL |
| 46 | - migrate_enable(); |
| 47 | -#endif |
| 48 | - return -1; |
| 49 | + err = -1; |
| 50 | + goto done; |
| 51 | } |
| 52 | qm_cleanup_portal = kmalloc(sizeof(struct qm_portal), |
| 53 | GFP_KERNEL); |
| 54 | if (!qm_cleanup_portal) { |
| 55 | -#ifdef CONFIG_PREEMPT_RT_FULL |
| 56 | - migrate_enable(); |
| 57 | -#endif |
| 58 | - return -ENOMEM; |
| 59 | + err = -ENOMEM; |
| 60 | + goto done; |
| 61 | } |
| 62 | init_qm_portal(qm_alloced_portal, qm_cleanup_portal); |
| 63 | portal_array[portal_count] = qm_cleanup_portal; |
| 64 | @@ -633,18 +635,14 @@ static int usdpaa_release(struct inode * |
| 65 | bm_alloced_portal = bm_get_unused_portal(); |
| 66 | if (!bm_alloced_portal) { |
| 67 | pr_crit("No BMan portal avalaible for cleanup\n"); |
| 68 | -#ifdef CONFIG_PREEMPT_RT_FULL |
| 69 | - migrate_enable(); |
| 70 | -#endif |
| 71 | - return -1; |
| 72 | + err = -1; |
| 73 | + goto done; |
| 74 | } |
| 75 | bm_cleanup_portal = kmalloc(sizeof(struct bm_portal), |
| 76 | GFP_KERNEL); |
| 77 | if (!bm_cleanup_portal) { |
| 78 | -#ifdef CONFIG_PREEMPT_RT_FULL |
| 79 | - migrate_enable(); |
| 80 | -#endif |
| 81 | - return -ENOMEM; |
| 82 | + err = -ENOMEM; |
| 83 | + goto done; |
| 84 | } |
| 85 | init_bm_portal(bm_alloced_portal, bm_cleanup_portal); |
| 86 | } |
| 87 | @@ -721,10 +719,12 @@ static int usdpaa_release(struct inode * |
| 88 | } |
| 89 | |
| 90 | kfree(ctx); |
| 91 | +done: |
| 92 | #ifdef CONFIG_PREEMPT_RT_FULL |
| 93 | migrate_enable(); |
| 94 | #endif |
| 95 | - return 0; |
| 96 | + kfree(portal_array); |
| 97 | + return err; |
| 98 | } |
| 99 | |
| 100 | static int check_mmap_dma(struct ctx *ctx, struct vm_area_struct *vma, |