summaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2018-06-29 14:51:07 -0400
committerVinod Koul <vkoul@kernel.org>2018-07-02 08:16:24 -0400
commite6a785116df09f07c8d185fb18211d2bbacb047b (patch)
tree97a7f7df406b79014a9c21fe7c547fd183ca37a9 /drivers/dma
parentce397d215ccd07b8ae3f71db689aedb85d56ab40 (diff)
dmaengine: ste_dma40: Remove VLA usage
In the quest to remove all stack VLA usage from the kernel[1], this switches to using a pre-allocated scratch register space, set up with all other other allocations. [1] https://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com Signed-off-by: Kees Cook <keescook@chromium.org> Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/ste_dma40.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 1bc149af990e..f4edfc56f34e 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -555,6 +555,7 @@ struct d40_gen_dmac {
555 * @reg_val_backup_v4: Backup of registers that only exits on dma40 v3 and 555 * @reg_val_backup_v4: Backup of registers that only exits on dma40 v3 and
556 * later 556 * later
557 * @reg_val_backup_chan: Backup data for standard channel parameter registers. 557 * @reg_val_backup_chan: Backup data for standard channel parameter registers.
558 * @regs_interrupt: Scratch space for registers during interrupt.
558 * @gcc_pwr_off_mask: Mask to maintain the channels that can be turned off. 559 * @gcc_pwr_off_mask: Mask to maintain the channels that can be turned off.
559 * @gen_dmac: the struct for generic registers values to represent u8500/8540 560 * @gen_dmac: the struct for generic registers values to represent u8500/8540
560 * DMA controller 561 * DMA controller
@@ -592,6 +593,7 @@ struct d40_base {
592 u32 reg_val_backup[BACKUP_REGS_SZ]; 593 u32 reg_val_backup[BACKUP_REGS_SZ];
593 u32 reg_val_backup_v4[BACKUP_REGS_SZ_MAX]; 594 u32 reg_val_backup_v4[BACKUP_REGS_SZ_MAX];
594 u32 *reg_val_backup_chan; 595 u32 *reg_val_backup_chan;
596 u32 *regs_interrupt;
595 u16 gcc_pwr_off_mask; 597 u16 gcc_pwr_off_mask;
596 struct d40_gen_dmac gen_dmac; 598 struct d40_gen_dmac gen_dmac;
597}; 599};
@@ -1637,7 +1639,7 @@ static irqreturn_t d40_handle_interrupt(int irq, void *data)
1637 struct d40_chan *d40c; 1639 struct d40_chan *d40c;
1638 unsigned long flags; 1640 unsigned long flags;
1639 struct d40_base *base = data; 1641 struct d40_base *base = data;
1640 u32 regs[base->gen_dmac.il_size]; 1642 u32 *regs = base->regs_interrupt;
1641 struct d40_interrupt_lookup *il = base->gen_dmac.il; 1643 struct d40_interrupt_lookup *il = base->gen_dmac.il;
1642 u32 il_size = base->gen_dmac.il_size; 1644 u32 il_size = base->gen_dmac.il_size;
1643 1645
@@ -3258,13 +3260,22 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
3258 if (!base->lcla_pool.alloc_map) 3260 if (!base->lcla_pool.alloc_map)
3259 goto free_backup_chan; 3261 goto free_backup_chan;
3260 3262
3263 base->regs_interrupt = kmalloc_array(base->gen_dmac.il_size,
3264 sizeof(*base->regs_interrupt),
3265 GFP_KERNEL);
3266 if (!base->regs_interrupt)
3267 goto free_map;
3268
3261 base->desc_slab = kmem_cache_create(D40_NAME, sizeof(struct d40_desc), 3269 base->desc_slab = kmem_cache_create(D40_NAME, sizeof(struct d40_desc),
3262 0, SLAB_HWCACHE_ALIGN, 3270 0, SLAB_HWCACHE_ALIGN,
3263 NULL); 3271 NULL);
3264 if (base->desc_slab == NULL) 3272 if (base->desc_slab == NULL)
3265 goto free_map; 3273 goto free_regs;
3274
3266 3275
3267 return base; 3276 return base;
3277 free_regs:
3278 kfree(base->regs_interrupt);
3268 free_map: 3279 free_map:
3269 kfree(base->lcla_pool.alloc_map); 3280 kfree(base->lcla_pool.alloc_map);
3270 free_backup_chan: 3281 free_backup_chan: