Commit b71ec952 authored by Thomas Falcon's avatar Thomas Falcon Committed by David S. Miller
Browse files

ibmvnic: Ensure that SCRQ entry reads are correctly ordered



Ensure that received Subordinate Command-Response Queue (SCRQ)
entries are properly read in order by the driver. These queues
are used in the ibmvnic device to process RX buffer and TX completion
descriptors. dma_rmb barriers have been added after checking for a
pending descriptor to ensure the correct descriptor entry is checked
and after reading the SCRQ descriptor to ensure the entire
descriptor is read before processing.

Fixes: 032c5e82 ("Driver for IBM System i/p VNIC protocol")
Signed-off-by: default avatarThomas Falcon <tlfalcon@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 237f977a
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -2404,6 +2404,12 @@ static int ibmvnic_poll(struct napi_struct *napi, int budget)

		if (!pending_scrq(adapter, adapter->rx_scrq[scrq_num]))
			break;
		/* The queue entry at the current index is peeked at above
		 * to determine that there is a valid descriptor awaiting
		 * processing. We want to be sure that the current slot
		 * holds a valid descriptor before reading its contents.
		 */
		dma_rmb();
		next = ibmvnic_next_scrq(adapter, adapter->rx_scrq[scrq_num]);
		rx_buff =
		    (struct ibmvnic_rx_buff *)be64_to_cpu(next->
@@ -3113,6 +3119,13 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
		unsigned int pool = scrq->pool_index;
		int num_entries = 0;

		/* The queue entry at the current index is peeked at above
		 * to determine that there is a valid descriptor awaiting
		 * processing. We want to be sure that the current slot
		 * holds a valid descriptor before reading its contents.
		 */
		dma_rmb();

		next = ibmvnic_next_scrq(adapter, scrq);
		for (i = 0; i < next->tx_comp.num_comps; i++) {
			if (next->tx_comp.rcs[i]) {
@@ -3513,6 +3526,11 @@ static union sub_crq *ibmvnic_next_scrq(struct ibmvnic_adapter *adapter,
	}
	spin_unlock_irqrestore(&scrq->lock, flags);

	/* Ensure that the entire buffer descriptor has been
	 * loaded before reading its contents
	 */
	dma_rmb();

	return entry;
}