]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ibmvnic: Ensure that SCRQ entry reads are correctly ordered
authorThomas Falcon <tlfalcon@linux.ibm.com>
Tue, 1 Dec 2020 15:52:10 +0000 (09:52 -0600)
committerDavid S. Miller <davem@davemloft.net>
Tue, 1 Dec 2020 18:09:04 +0000 (10:09 -0800)
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: 032c5e82847a ("Driver for IBM System i/p VNIC protocol")
Signed-off-by: Thomas Falcon <tlfalcon@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/ibm/ibmvnic.c

index bca1becd33f057abdcb329f87c3f9d5cbcfae947..0e34c36c3e86f6576cdcb61a11aef4e1ac481035 100644 (file)
@@ -2404,6 +2404,12 @@ restart_poll:
 
                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 @@ restart_loop:
                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;
 }