| From 0ad840e46732e95df274a84b042dcb210be9f946 Mon Sep 17 00:00:00 2001 |
| From: Roy Pledge <roy.pledge@nxp.com> |
| Date: Thu, 28 Mar 2019 09:56:35 -0400 |
| Subject: [PATCH] sdk_qbman: Avoid variable length array in USDPAA |
| |
| As of Linux 5.0 variable length arrays on the stack are no |
| longer allowed. Change to a dynamic array and create a common |
| exit point in the function for cleanup. |
| |
| Signed-off-by: Roy Pledge <roy.pledge@nxp.com> |
| --- |
| drivers/staging/fsl_qbman/fsl_usdpaa.c | 36 +++++++++++++++++----------------- |
| 1 file changed, 18 insertions(+), 18 deletions(-) |
| |
| --- a/drivers/staging/fsl_qbman/fsl_usdpaa.c |
| +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c |
| @@ -559,6 +559,7 @@ static bool check_portal_channel(void *c |
| |
| static int usdpaa_release(struct inode *inode, struct file *filp) |
| { |
| + int err = 0; |
| struct ctx *ctx = filp->private_data; |
| struct mem_mapping *map, *tmpmap; |
| struct portal_mapping *portal, *tmpportal; |
| @@ -569,9 +570,14 @@ static int usdpaa_release(struct inode * |
| struct qm_portal_config *qm_alloced_portal = NULL; |
| struct bm_portal_config *bm_alloced_portal = NULL; |
| |
| - struct qm_portal *portal_array[qman_portal_max]; |
| + struct qm_portal **portal_array; |
| int portal_count = 0; |
| |
| + portal_array = kmalloc_array(qman_portal_max, |
| + sizeof(struct qm_portal *), GFP_KERNEL); |
| + if (!portal_array) |
| + return -ENOMEM; |
| + |
| /* Ensure the release operation cannot be migrated to another |
| CPU as CPU specific variables may be needed during cleanup */ |
| #ifdef CONFIG_PREEMPT_RT_FULL |
| @@ -612,18 +618,14 @@ static int usdpaa_release(struct inode * |
| qm_alloced_portal = qm_get_unused_portal(); |
| if (!qm_alloced_portal) { |
| pr_crit("No QMan portal avalaible for cleanup\n"); |
| -#ifdef CONFIG_PREEMPT_RT_FULL |
| - migrate_enable(); |
| -#endif |
| - return -1; |
| + err = -1; |
| + goto done; |
| } |
| qm_cleanup_portal = kmalloc(sizeof(struct qm_portal), |
| GFP_KERNEL); |
| if (!qm_cleanup_portal) { |
| -#ifdef CONFIG_PREEMPT_RT_FULL |
| - migrate_enable(); |
| -#endif |
| - return -ENOMEM; |
| + err = -ENOMEM; |
| + goto done; |
| } |
| init_qm_portal(qm_alloced_portal, qm_cleanup_portal); |
| portal_array[portal_count] = qm_cleanup_portal; |
| @@ -633,18 +635,14 @@ static int usdpaa_release(struct inode * |
| bm_alloced_portal = bm_get_unused_portal(); |
| if (!bm_alloced_portal) { |
| pr_crit("No BMan portal avalaible for cleanup\n"); |
| -#ifdef CONFIG_PREEMPT_RT_FULL |
| - migrate_enable(); |
| -#endif |
| - return -1; |
| + err = -1; |
| + goto done; |
| } |
| bm_cleanup_portal = kmalloc(sizeof(struct bm_portal), |
| GFP_KERNEL); |
| if (!bm_cleanup_portal) { |
| -#ifdef CONFIG_PREEMPT_RT_FULL |
| - migrate_enable(); |
| -#endif |
| - return -ENOMEM; |
| + err = -ENOMEM; |
| + goto done; |
| } |
| init_bm_portal(bm_alloced_portal, bm_cleanup_portal); |
| } |
| @@ -721,10 +719,12 @@ static int usdpaa_release(struct inode * |
| } |
| |
| kfree(ctx); |
| +done: |
| #ifdef CONFIG_PREEMPT_RT_FULL |
| migrate_enable(); |
| #endif |
| - return 0; |
| + kfree(portal_array); |
| + return err; |
| } |
| |
| static int check_mmap_dma(struct ctx *ctx, struct vm_area_struct *vma, |