spmi: qpnp-int: prevent a race condition in mask/unmask of interrupts
Currently the accesses to the peripheral data's irq enable count is
unprotected. The ACC bit in the spmi arbiter represents if any of the
eight interrupts in the peripheral is enabled. The counts are used to
ensure that the ACC bit for that peripheral is enabled when
the first interrupt in the peripheral is unmasked and is disabled when
the last interrupt in the peripheral is masked.
A race like this could happen.
Initial condition: Only two interrupts are enabled in the peripheral.
cpu0 cpu1
1. Mask 1st
2. Handle 1st
3. Unmask 1st. Sees that 2nd is
unmasked
3. Mask 2nd. Disables ACC
4. Handle 2nd
5. Unmask 1st continues. Skips
enabling ACC since it sees that
this is not the first interrupt
being unmasked. Although it is,
since 2nd interrupt was masked
after enabled counts were read.
6. Unmask 2nd, sees that 1st is
enabled and skips enabling ACC
bit
7. After this, the ACC bit for that peripheral remains disabled even when
interrupts are in unmasked state at the peripheral.
Fix this by ensuring 3 and 5 happen atomically, i.e. the reading of the
masked state and the action of enabling/disabling ACC bit should be
atomic.
CRs-Fixed: 968643
Change-Id: I02cb7b3350d73c9b24b6445a5008f52cbc32cecf
Signed-off-by:
Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Loading
Please register or sign in to comment