linux/drivers/dma
Mika Westerberg 6d0709d200 dma/ep93xx_dma: prevent ep93xx_dma_tasklet() to reference an empty list
If dma_terminate_all() is called before the ep93xx_dma_tasklet() gets to run,
it tries to access an empty ->active list which results following OOPS:

  Internal error: Oops - undefined instruction: 0 [#1]
  CPU: 0    Not tainted  (3.2.0-rc1EP-1+ #1008)
  PC is at 0xc184c868
  LR is at ep93xx_dma_tasklet+0xec/0x164
  pc : [<c184c868>]    lr : [<c012b528>]    psr: 00000013
  sp : c02b7e70  ip : ffffffff  fp : c02b7ea4
  r10: 00000100  r9 : 80000013  r8 : c02b7e50
  r7 : c02b7e70  r6 : c02b7ea4  r5 : 000000a4  r4 : c02b7e70
  r3 : c02b751d  r2 : 8ae34598  r1 : c184c6e0  r0 : c02b7ea4
  Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
  Control: c000717f  Table: c0004000  DAC: 00000017
  Process swapper (pid: 0, stack limit = 0xc02b6270)
  Stack: (0xc02b7e70 to 0xc02b8000)
  7e60:                                     c02b7ea4 c02b7e70 c0008b64 c02bd5c4
  7e80: c02d60e0 00000000 00000000 c02bd44c c02d60e0 00000100 c02b7ec4 c02b7ea8
  7ea0: c001c49c c012b44c 00000018 00000001 c02d60e0 c02b6000 c02b7f04 c02b7ec8
  7ec0: c001cbc0 c001c3e4 c02b7eec c02b7ed8 00000006 0000000a c02bf674 c02c458c
  7ee0: 00000011 00000000 c02b7f7c c0004000 41129200 c02b0c80 c02b7f14 c02b7f08
  7f00: c001cdd0 c001cb38 c02b7f34 c02b7f18 c000983c c001cd98 c0009a60 60000013
  7f20: fefb0001 c02b7f7c c02b7f44 c02b7f38 c0008190 c0009810 c02b7f9c c02b7f48
  7f40: c0008b64 c0008190 c02c2bf8 00000002 c02b7f90 60000013 c02b6000 c02d1504
  7f60: c02baa88 c02baa80 c0004000 41129200 c02b0c80 c02b7f9c c02b7fa0 c02b7f90
  7f80: c0009a54 c0009a60 60000013 ffffffff c02b7fbc c02b7fa0 c000a03c c0009a40
  7fa0: c02b80b0 c02b19dc c02b19d8 c02baa80 c02b7fcc c02b7fc0 c02384e4 c0009fd4
  7fc0: c02b7ff4 c02b7fd0 c029d924 c0238494 c029d49c 00000000 00000000 c02b19dc
  7fe0: c0007175 c02b803c 00000000 c02b7ff8 c000803c c029d700 00000000 00000000
  Backtrace:
  [<c012b43c>] (ep93xx_dma_tasklet+0x0/0x164) from [<c001c49c>] (tasklet_action+0xc8/0xdc)
  [<c001c3d4>] (tasklet_action+0x0/0xdc) from [<c001cbc0>] (__do_softirq+0x98/0x154)
   r7:c02b6000 r6:c02d60e0 r5:00000001 r4:00000018
  [<c001cb28>] (__do_softirq+0x0/0x154) from [<c001cdd0>] (irq_exit+0x48/0x50)
  [<c001cd88>] (irq_exit+0x0/0x50) from [<c000983c>] (handle_IRQ+0x3c/0x8c)
  [<c0009800>] (handle_IRQ+0x0/0x8c) from [<c0008190>] (asm_do_IRQ+0x10/0x14)
   r7:c02b7f7c r6:fefb0001 r5:60000013 r4:c0009a60
  [<c0008180>] (asm_do_IRQ+0x0/0x14) from [<c0008b64>] (__irq_svc+0x24/0xc0)
  Exception stack(0xc02b7f48 to 0xc02b7f90)
  7f40:                   c02c2bf8 00000002 c02b7f90 60000013 c02b6000 c02d1504
  7f60: c02baa88 c02baa80 c0004000 41129200 c02b0c80 c02b7f9c c02b7fa0 c02b7f90
  7f80: c0009a54 c0009a60 60000013 ffffffff
  [<c0009a30>] (default_idle+0x0/0x34) from [<c000a03c>] (cpu_idle+0x78/0xb0)
  [<c0009fc4>] (cpu_idle+0x0/0xb0) from [<c02384e4>] (rest_init+0x60/0x78)
   r7:c02baa80 r6:c02b19d8 r5:c02b19dc r4:c02b80b0
  [<c0238484>] (rest_init+0x0/0x78) from [<c029d924>] (start_kernel+0x234/0x278)
  [<c029d6f0>] (start_kernel+0x0/0x278) from [<c000803c>] (0xc000803c)
   r5:c02b803c r4:c0007175
  Code: 42555300 54535953 643d4d45 65766972 (53007372)

To make the code a bit more robust against things like these, we modify
ep93xx_dma_get_active() to return NULL in case of empty ->active list and make
sure that callers handle this correctly.

Reported-by: Rafal Prylowski <prylowski@metasoft.pl>
Signed-off-by: Mika Westerberg <mika.westerberg@iki.fi>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
2011-12-05 08:16:26 +05:30
..
ioat ioat: fix xor_idx_to_desc 2011-08-03 22:25:06 -07:00
ipu Merge branch 'dma_slave_direction' into next_test_dirn 2011-11-17 14:54:57 +05:30
ppc4xx Merge branch 'old_next' into next 2011-04-06 11:51:12 +05:30
amba-pl08x.c dmaengine: move drivers to dma_transfer_direction 2011-10-27 20:53:43 +05:30
at_hdmac_regs.h dmaengine: at_hdmac: simplify device selection from platform data or DT 2011-11-28 15:55:36 +05:30
at_hdmac.c dmaengine: at_hdmac: simplify device selection from platform data or DT 2011-11-28 15:55:36 +05:30
coh901318_lli.c dmaengine: move drivers to dma_transfer_direction 2011-10-27 20:53:43 +05:30
coh901318_lli.h dmaengine: move drivers to dma_transfer_direction 2011-10-27 20:53:43 +05:30
coh901318.c dmaengine: move drivers to dma_transfer_direction 2011-10-27 20:53:43 +05:30
dmaengine.c DMAEngine: Define interleaved transfer request api 2011-11-18 12:16:24 +05:30
dmatest.c dmatest: make dmatest threads freezable 2011-08-29 18:01:27 +05:30
dw_dmac_regs.h dmaengine/dw_dmac: Reconfigure interrupt and chan_cfg register on resume 2011-11-28 08:48:02 +05:30
dw_dmac.c dmaengine/dw_dmac: Reconfigure interrupt and chan_cfg register on resume 2011-11-28 08:48:02 +05:30
ep93xx_dma.c dma/ep93xx_dma: prevent ep93xx_dma_tasklet() to reference an empty list 2011-12-05 08:16:26 +05:30
fsldma.c dmaengine: move drivers to dma_transfer_direction 2011-10-27 20:53:43 +05:30
fsldma.h fsldma: fix controller lockups 2011-03-11 17:52:36 -08:00
imx-dma.c Merge branch 'dma_slave_direction' into next_test_dirn 2011-11-17 14:54:57 +05:30
imx-sdma.c IMX/DMA : set the DMA direction in the sdma_control() 2011-11-22 09:51:45 +05:30
intel_mid_dma_regs.h dmaengine: move drivers to dma_transfer_direction 2011-10-27 20:53:43 +05:30
intel_mid_dma.c Merge branch 'dma_slave_direction' into next_test_dirn 2011-11-17 14:54:57 +05:30
iop-adma.c dma: fix spacing for method declaration, coding style issue in iop-adma.c 2011-11-17 14:25:25 +05:30
iovlock.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
Kconfig dmaengine: add CSR SiRFprimaII DMAC driver 2011-11-18 12:25:22 +05:30
Makefile dmaengine: add CSR SiRFprimaII DMAC driver 2011-11-18 12:25:22 +05:30
mpc512x_dma.c dmaengine: delete redundant chan_id and chancnt initialization in dma drivers 2011-09-20 11:51:33 +05:30
mv_xor.c dma: mv_xor: use resource_size() 2011-07-14 03:32:31 +05:30
mv_xor.h mv_xor: implement a private tx_list 2009-09-08 17:53:03 -07:00
mxs-dma.c dmaengine: move drivers to dma_transfer_direction 2011-10-27 20:53:43 +05:30
pch_dma.c Merge branch 'dma_slave_direction' into next_test_dirn 2011-11-17 14:54:57 +05:30
pl330.c Merge branch 'dma_slave_direction' into next_test_dirn 2011-11-17 14:54:57 +05:30
shdma.c dmaengine: move drivers to dma_transfer_direction 2011-10-27 20:53:43 +05:30
shdma.h dma: shdma: transfer based runtime PM 2011-09-28 10:07:40 +05:30
sirf-dma.c dmaengine: add CSR SiRFprimaII DMAC driver 2011-11-18 12:25:22 +05:30
ste_dma40_ll.c dma40: cyclic xfer support 2011-01-30 22:27:21 -08:00
ste_dma40_ll.h dmaengine/ste_dma40: support pm in dma40 2011-11-22 09:46:06 +05:30
ste_dma40.c dmaengine/ste_dma40: Add support to use lcla area from esram 2011-11-28 09:00:08 +05:30
timb_dma.c dmaengine: timb_dma: fix the spare warinings 2011-11-28 08:51:16 +05:30
TODO dmaengine: remove ste_dma40 from issue_pending TODO 2011-07-14 04:02:08 +05:30
txx9dmac.c dmaengine: move drivers to dma_transfer_direction 2011-10-27 20:53:43 +05:30
txx9dmac.h txx9dmac: implement a private tx_list 2009-09-08 17:53:03 -07:00