Skip to content

Commit

Permalink
ixgbe: add improvement for MDD response functionality
Browse files Browse the repository at this point in the history
The 82599 PF driver disable VF driver after a special MDD event occurs.
Adds the option for administrators to control whether VFs are
automatically disabled after several MDD events.
The automatically disabling is now the default mode for 82599 PF driver,
as it is more reliable.

This addresses CVE-2021-33061.

Signed-off-by: Slawomir Mrozowicz <[email protected]>
Tested-by: Konrad Jankowski <[email protected]>
Signed-off-by: Tony Nguyen <[email protected]>
  • Loading branch information
smrozowx authored and anguy11 committed Mar 8, 2022
1 parent 366fd10 commit 008ca35
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ struct vf_data_storage {
u8 trusted;
int xcast_mode;
unsigned int vf_api;
u8 primary_abort_count;
};

enum ixgbevf_xcast_modes {
Expand Down Expand Up @@ -558,6 +559,8 @@ struct ixgbe_mac_addr {
#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
#define IXGBE_SFP_POLL_JIFFIES (2 * HZ) /* SFP poll every 2 seconds */

#define IXGBE_PRIMARY_ABORT_LIMIT 5

/* board specific private data structure */
struct ixgbe_adapter {
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
Expand Down Expand Up @@ -616,6 +619,7 @@ struct ixgbe_adapter {
#define IXGBE_FLAG2_RX_LEGACY BIT(16)
#define IXGBE_FLAG2_IPSEC_ENABLED BIT(17)
#define IXGBE_FLAG2_VF_IPSEC_ENABLED BIT(18)
#define IXGBE_FLAG2_AUTO_DISABLE_VF BIT(19)

/* Tx fast path data */
int num_tx_queues;
Expand Down
21 changes: 21 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ static const char ixgbe_priv_flags_strings[][ETH_GSTRING_LEN] = {
"legacy-rx",
#define IXGBE_PRIV_FLAGS_VF_IPSEC_EN BIT(1)
"vf-ipsec",
#define IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF BIT(2)
"mdd-disable-vf",
};

#define IXGBE_PRIV_FLAGS_STR_LEN ARRAY_SIZE(ixgbe_priv_flags_strings)
Expand Down Expand Up @@ -3510,13 +3512,17 @@ static u32 ixgbe_get_priv_flags(struct net_device *netdev)
if (adapter->flags2 & IXGBE_FLAG2_VF_IPSEC_ENABLED)
priv_flags |= IXGBE_PRIV_FLAGS_VF_IPSEC_EN;

if (adapter->flags2 & IXGBE_FLAG2_AUTO_DISABLE_VF)
priv_flags |= IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF;

return priv_flags;
}

static int ixgbe_set_priv_flags(struct net_device *netdev, u32 priv_flags)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
unsigned int flags2 = adapter->flags2;
unsigned int i;

flags2 &= ~IXGBE_FLAG2_RX_LEGACY;
if (priv_flags & IXGBE_PRIV_FLAGS_LEGACY_RX)
Expand All @@ -3526,6 +3532,21 @@ static int ixgbe_set_priv_flags(struct net_device *netdev, u32 priv_flags)
if (priv_flags & IXGBE_PRIV_FLAGS_VF_IPSEC_EN)
flags2 |= IXGBE_FLAG2_VF_IPSEC_ENABLED;

flags2 &= ~IXGBE_FLAG2_AUTO_DISABLE_VF;
if (priv_flags & IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF) {
if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
/* Reset primary abort counter */
for (i = 0; i < adapter->num_vfs; i++)
adapter->vfinfo[i].primary_abort_count = 0;

flags2 |= IXGBE_FLAG2_AUTO_DISABLE_VF;
} else {
e_info(probe,
"Cannot set private flags: Operation not supported\n");
return -EOPNOTSUPP;
}
}

if (flags2 != adapter->flags2) {
adapter->flags2 = flags2;

Expand Down
28 changes: 27 additions & 1 deletion drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7613,6 +7613,27 @@ static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter)
}

#ifdef CONFIG_PCI_IOV
static void ixgbe_bad_vf_abort(struct ixgbe_adapter *adapter, u32 vf)
{
struct ixgbe_hw *hw = &adapter->hw;

if (adapter->hw.mac.type == ixgbe_mac_82599EB &&
adapter->flags2 & IXGBE_FLAG2_AUTO_DISABLE_VF) {
adapter->vfinfo[vf].primary_abort_count++;
if (adapter->vfinfo[vf].primary_abort_count ==
IXGBE_PRIMARY_ABORT_LIMIT) {
ixgbe_set_vf_link_state(adapter, vf,
IFLA_VF_LINK_STATE_DISABLE);
adapter->vfinfo[vf].primary_abort_count = 0;

e_info(drv,
"Malicious Driver Detection event detected on PF %d VF %d MAC: %pM mdd-disable-vf=on",
hw->bus.func, vf,
adapter->vfinfo[vf].vf_mac_addresses);
}
}
}

static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
Expand Down Expand Up @@ -7644,8 +7665,10 @@ static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter)
continue;
pci_read_config_word(vfdev, PCI_STATUS, &status_reg);
if (status_reg != IXGBE_FAILED_READ_CFG_WORD &&
status_reg & PCI_STATUS_REC_MASTER_ABORT)
status_reg & PCI_STATUS_REC_MASTER_ABORT) {
ixgbe_bad_vf_abort(adapter, vf);
pcie_flr(vfdev);
}
}
}

Expand Down Expand Up @@ -10746,6 +10769,9 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto err_sw_init;

if (adapter->hw.mac.type == ixgbe_mac_82599EB)
adapter->flags2 |= IXGBE_FLAG2_AUTO_DISABLE_VF;

switch (adapter->hw.mac.type) {
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
Expand Down

0 comments on commit 008ca35

Please sign in to comment.