1
linux/drivers/tty
Yoshii Takashi 49d4bcaddc serial: sh-sci: fix a race of DMA submit_tx on transfer
When DMA is enabled, sh-sci transfer begins with
 uart_start()
  sci_start_tx()
    if (cookie_tx < 0) schedule_work()
Then, starts DMA when wq scheduled, -- (A)
 process_one_work()
  work_fn_rx()
   cookie_tx = desc->submit_tx()
And finishes when DMA transfer ends, -- (B)
 sci_dma_tx_complete()
  async_tx_ack()
  cookie_tx = -EINVAL
  (possible another schedule_work())

This A to B sequence is not reentrant, since controlling variables
(for example, cookie_tx above) are not queues nor lists. So, they
must be invoked as A B A B..., otherwise results in kernel crash.

To ensure the sequence, sci_start_tx() seems to test if cookie_tx < 0
(represents "not used") to call schedule_work().
But cookie_tx will not be set (to a cookie, also means "used") until
in the middle of work queue scheduled function work_fn_tx().

This gap between the test and set allows the breakage of the sequence
under the very frequently call of uart_start().
Another gap between async_tx_ack() and another schedule_work() results
in the same issue, too.

This patch introduces a new condition "cookie_tx == 0" just to mark
it is "busy" and assign it within spin-locked region to fill the gaps.

Signed-off-by: Takashi Yoshii <takashi.yoshii.zj@renesas.com>
Reviewed-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: stable@vger.kernel.org
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
2012-03-28 14:26:05 +09:00
..
hvc Features: 2012-03-22 20:16:14 -07:00
ipwireless Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2012-03-20 21:04:47 -07:00
serial serial: sh-sci: fix a race of DMA submit_tx on transfer 2012-03-28 14:26:05 +09:00
vt TTY: Wrong unicode value copied in con_set_unimap() 2012-03-15 13:28:52 -07:00
amiserial.c TTY: amiserial, use tty_port_close_start 2012-03-08 12:50:02 -08:00
bfin_jtag_comm.c TTY: remove re-assignments to tty_driver members 2012-03-08 11:37:58 -08:00
cyclades.c TTY: remove unneeded tty->index checks 2012-03-08 11:42:21 -08:00
ehv_bytechan.c TTY: remove re-assignments to tty_driver members 2012-03-08 11:37:58 -08:00
isicom.c TTY: remove unneeded tty->index checks 2012-03-08 11:42:21 -08:00
Kconfig
Makefile
moxa.c tty: moxa: fix bit test in moxa_start() 2012-03-08 12:55:48 -08:00
moxa.h
mxser.c TTY: remove unneeded tty->index checks 2012-03-08 11:42:21 -08:00
mxser.h
n_gsm.c TTY: remove re-assignments to tty_driver members 2012-03-08 11:37:58 -08:00
n_hdlc.c
n_r3964.c
n_tracerouter.c
n_tracesink.c
n_tracesink.h
n_tty.c
nozomi.c TTY: remove re-assignments to tty_driver members 2012-03-08 11:37:58 -08:00
pty.c TTY: remove re-assignments to tty_driver members 2012-03-08 11:37:58 -08:00
rocket_int.h
rocket.c TTY: remove unneeded tty->index checks 2012-03-08 11:42:21 -08:00
rocket.h
synclink_gt.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2012-03-20 21:12:50 -07:00
synclink.c TTY: remove unneeded tty->index checks 2012-03-08 11:42:21 -08:00
synclinkmp.c TTY: remove unneeded tty->index checks 2012-03-08 11:42:21 -08:00
sysrq.c mm, oom: force oom kill on sysrq+f 2012-03-21 17:54:58 -07:00
tty_audit.c
tty_buffer.c
tty_io.c TTY: remove tty driver re-set from tty_reopen 2012-03-08 11:38:50 -08:00
tty_ioctl.c
tty_ldisc.c
tty_mutex.c
tty_port.c