diff options
author | Brian King <brking@linux.vnet.ibm.com> | 2014-05-23 10:52:11 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-07-09 11:13:59 -0700 |
commit | c8e9b34fdc16b7f568237d54002f1f292103b15f (patch) | |
tree | 763f1075d91bdc569318f368e8d5f87b6e0cc680 /drivers/scsi | |
parent | d383fcfd183759a78753d337e8a1a10f08984063 (diff) | |
download | linux-3.10-c8e9b34fdc16b7f568237d54002f1f292103b15f.tar.gz linux-3.10-c8e9b34fdc16b7f568237d54002f1f292103b15f.tar.bz2 linux-3.10-c8e9b34fdc16b7f568237d54002f1f292103b15f.zip |
ibmvscsi: Add memory barriers for send / receive
commit 7114aae02742d6b5c5a0d39a41deb61d415d3717 upstream.
Add a memory barrier prior to sending a new command to the VIOS
to ensure the VIOS does not receive stale data in the command buffer.
Also add a memory barrier when processing the CRQ for completed commands.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 1e29efc8271..c62b3e5d44b 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -185,6 +185,11 @@ static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue) if (crq->valid & 0x80) { if (++queue->cur == queue->size) queue->cur = 0; + + /* Ensure the read of the valid bit occurs before reading any + * other bits of the CRQ entry + */ + rmb(); } else crq = NULL; spin_unlock_irqrestore(&queue->lock, flags); @@ -203,6 +208,11 @@ static int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, { struct vio_dev *vdev = to_vio_dev(hostdata->dev); + /* + * Ensure the command buffer is flushed to memory before handing it + * over to the VIOS to prevent it from fetching any stale data. + */ + mb(); return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2); } |