Skip to content

Commit

Permalink
[POWERPC] spufs: fix save of mfc_cntl register
Browse files Browse the repository at this point in the history
Currently, we can introduce invalid entries into the MFC queues:

1) context starts a DMA

2) context gets scheduled out during a DMA
  - kernel saves MFC queue to CSA
  - kernel saves 0x0 in csa->mfc_control_RW

3) context gets scheduled in
  - csa->mfc_control[Q] ('queues empty') isn't set, so DMA queues are
    restored from the CSA

4) context's DMA is completed

5) context gets scheduled out again, no DMA occuring this time
  - kernel sees that MFC_CNTL[Q] ('queues empty') is set, so doesn't
    touch saved queue data in CSA
  - kernel saves 0x0 in csa->mfc_control_RW

6) context gets scheduled in
  - csa->mfc_control[Q] ('queues empty') isn't set (we saved is as 0!),
    so DMA queues are restored from the CSA

In this last restore, we've restored the queue status from step 2,
which are now invalid.

This change makes save_mfc_cntl() closer to the save/restore sequence,
as specified in the CBE handbook.

With changes from Luke Browning.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
  • Loading branch information
Jeremy Kerr committed May 5, 2008
1 parent 943906b commit 1ca4264
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions arch/powerpc/platforms/cell/spufs/switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,20 +186,21 @@ static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu)
MFC_CNTL_SUSPEND_COMPLETE);
/* fall through */
case MFC_CNTL_SUSPEND_COMPLETE:
if (csa) {
if (csa)
csa->priv2.mfc_control_RW =
MFC_CNTL_SUSPEND_MASK |
in_be64(&priv2->mfc_control_RW) |
MFC_CNTL_SUSPEND_DMA_QUEUE;
}
break;
case MFC_CNTL_NORMAL_DMA_QUEUE_OPERATION:
out_be64(&priv2->mfc_control_RW, MFC_CNTL_SUSPEND_DMA_QUEUE);
POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) &
MFC_CNTL_SUSPEND_DMA_STATUS_MASK) ==
MFC_CNTL_SUSPEND_COMPLETE);
if (csa) {
csa->priv2.mfc_control_RW = 0;
}
if (csa)
csa->priv2.mfc_control_RW =
in_be64(&priv2->mfc_control_RW) &
~MFC_CNTL_SUSPEND_DMA_QUEUE &
~MFC_CNTL_SUSPEND_MASK;
break;
}
}
Expand Down

0 comments on commit 1ca4264

Please sign in to comment.