Changeset 05749690 in rtems


Ignore:
Timestamp:
Jan 26, 2017, 10:01:10 AM (3 years ago)
Author:
Martin Aberg <maberg@…>
Branches:
5, master
Children:
ca4c4164
Parents:
5d367c56
git-author:
Martin Aberg <maberg@…> (01/26/17 10:01:10)
git-committer:
Daniel Hellstrom <daniel@…> (05/14/17 10:31:58)
Message:

leon, grcan: fixed race on interrupt mask register

There was a potential read-modify-write race on the interrupt mask (imr)
register between the ISR and user functions.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/shared/can/grcan.c

    r5d367c56 r05749690  
    17131713{
    17141714        struct grcan_priv *pDev = d;
     1715        SPIN_IRQFLAGS(oldLevel);
    17151716
    17161717        FUNCDBG();
     
    17221723
    17231724                 /* disable Sync interrupt */
     1725                SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
    17241726                pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~(GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
     1727                SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
    17251728        }else{
    17261729                /* Save filter */
     
    17281731
    17291732                /* Enable Sync interrupt */
     1733                SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
    17301734                pDev->regs->imr = READ_REG(&pDev->regs->imr) | (GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
     1735                SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
    17311736        }
    17321737        /* Set Sync RX/TX filter */
     
    17571762        unsigned int status = READ_REG(&pDev->regs->pimsr);
    17581763        unsigned int canstat = READ_REG(&pDev->regs->stat);
     1764        SPIN_ISR_IRQFLAGS(irqflags);
    17591765
    17601766        /* Spurious IRQ call? */
     
    17781784                 * to read/write until user has called ioctl(fd,START,0).
    17791785                 */
     1786                SPIN_LOCK(&pDev->devlock, irqflags);
    17801787                pDev->started = 0;
    17811788                grcan_hw_stop(pDev); /* this mask all IRQ sources */
     1789                SPIN_UNLOCK(&pDev->devlock, irqflags);
    17821790                status=0x1ffff; /* clear all interrupts */
    17831791                goto out;
     
    18041812                /* RX IRQ pointer interrupt */
    18051813                /*printk("RxIrq 0x%x\n",status);*/
     1814                SPIN_LOCK(&pDev->devlock, irqflags);
    18061815                pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~GRCAN_RXIRQ_IRQ;
     1816                SPIN_UNLOCK(&pDev->devlock, irqflags);
    18071817                rtems_semaphore_release(pDev->rx_sem);
    18081818        }
     
    18101820        if ( status & GRCAN_TXIRQ_IRQ ){
    18111821                /* TX IRQ pointer interrupt */
     1822                SPIN_LOCK(&pDev->devlock, irqflags);
    18121823                pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~GRCAN_TXIRQ_IRQ;
     1824                SPIN_UNLOCK(&pDev->devlock, irqflags);
    18131825                rtems_semaphore_release(pDev->tx_sem);
    18141826        }
     
    18251837
    18261838        if ( status & GRCAN_TXEMPTY_IRQ ){
     1839                SPIN_LOCK(&pDev->devlock, irqflags);
    18271840                pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~GRCAN_TXEMPTY_IRQ;
     1841                SPIN_UNLOCK(&pDev->devlock, irqflags);
    18281842                rtems_semaphore_release(pDev->txempty_sem);
    18291843        }
Note: See TracChangeset for help on using the changeset viewer.