ixgbe: Fix crash with VFs and flow director on interface flap
authorRadoslaw Tyl <radoslawx.tyl@intel.com>
Mon, 24 Sep 2018 07:24:20 +0000 (09:24 +0200)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Wed, 3 Oct 2018 19:36:20 +0000 (12:36 -0700)
This patch fix crash when we have restore flow director filters after reset
adapter. In ixgbe_fdir_filter_restore() filter->action is outside of the
rx_ring array, as it has a VF identifier in the upper 32 bits.

Signed-off-by: Radoslaw Tyl <radoslawx.tyl@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

index ddc22557155b602d779318de8bad73add78bd048..2928ce7653eb0f215926e03df492e7192f646545 100644 (file)
@@ -5179,6 +5179,7 @@ static void ixgbe_fdir_filter_restore(struct ixgbe_adapter *adapter)
        struct ixgbe_hw *hw = &adapter->hw;
        struct hlist_node *node2;
        struct ixgbe_fdir_filter *filter;
+       u64 action;
 
        spin_lock(&adapter->fdir_perfect_lock);
 
@@ -5187,12 +5188,17 @@ static void ixgbe_fdir_filter_restore(struct ixgbe_adapter *adapter)
 
        hlist_for_each_entry_safe(filter, node2,
                                  &adapter->fdir_filter_list, fdir_node) {
+               action = filter->action;
+               if (action != IXGBE_FDIR_DROP_QUEUE && action != 0)
+                       action =
+                       (action >> ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF) - 1;
+
                ixgbe_fdir_write_perfect_filter_82599(hw,
                                &filter->filter,
                                filter->sw_idx,
-                               (filter->action == IXGBE_FDIR_DROP_QUEUE) ?
+                               (action == IXGBE_FDIR_DROP_QUEUE) ?
                                IXGBE_FDIR_DROP_QUEUE :
-                               adapter->rx_ring[filter->action]->reg_idx);
+                               adapter->rx_ring[action]->reg_idx);
        }
 
        spin_unlock(&adapter->fdir_perfect_lock);