wcxb: Do not access cur_transfer/cur_msg outside of lock.

The spi master cur_transfer and cur_msg should only be changed under the
spin_lock for the master. The result is that if running user space tools, like
fxstest, that check registers on the modules, it's possible to have a message
that was not yet complete flagged as completed which would result in a bad read.

This does not affect "normal" operation of the wcaxx driver since interrupts are
not enabled during module detection, and during normal operation all access to
the resgisters is done in the context of the interrupt handler. This would only
be an issue if the interrupt handler was running and register accesses are tried
in user space context on an SMP system.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
This commit is contained in:
Shaun Ruffell 2013-12-02 13:36:59 -06:00
parent d803fad133
commit 0faac26dde

View File

@ -291,14 +291,18 @@ _wcxb_spi_next_transfer(struct wcxb_spi_transfer *t)
*/ */
void wcxb_spi_handle_interrupt(struct wcxb_spi_master *master) void wcxb_spi_handle_interrupt(struct wcxb_spi_master *master)
{ {
struct wcxb_spi_message *msg = master->cur_msg; struct wcxb_spi_message *msg;
struct wcxb_spi_transfer *t = master->cur_transfer; struct wcxb_spi_transfer *t;
void (*complete)(void *arg) = NULL; void (*complete)(void *arg) = NULL;
unsigned long flags; unsigned long flags;
/* Check if we're not in the middle of a transfer, or not finished with /* Check if we're not in the middle of a transfer, or not finished with
* a part of one. */ * a part of one. */
spin_lock_irqsave(&master->lock, flags); spin_lock_irqsave(&master->lock, flags);
t = master->cur_transfer;
msg = master->cur_msg;
if (!msg || !is_txfifo_empty(master)) if (!msg || !is_txfifo_empty(master))
goto done; goto done;