{
        struct ixgbe_fwd_adapter *fwd_adapter = NULL;
        struct ixgbe_adapter *adapter = netdev_priv(pdev);
+       int used_pools = adapter->num_vfs + adapter->num_rx_pools;
        unsigned int limit;
        int pool, err;
 
+       /* Hardware has a limited number of available pools. Each VF, and the
+        * PF require a pool. Check to ensure we don't attempt to use more
+        * then the available number of pools.
+        */
+       if (used_pools >= IXGBE_MAX_VF_FUNCTIONS)
+               return ERR_PTR(-EINVAL);
+
 #ifdef CONFIG_RPS
        if (vdev->num_rx_queues != vdev->num_tx_queues) {
                netdev_info(pdev, "%s: Only supports a single queue count for TX and RX\n",
 
        if (err)
                return err;
 
-       /* While the SR-IOV capability structure reports total VFs to be
-        * 64 we limit the actual number that can be allocated to 63 so
-        * that some transmit/receive resources can be reserved to the
-        * PF.  The PCI bus driver already checks for other values out of
-        * range.
+       /* While the SR-IOV capability structure reports total VFs to be 64,
+        * we have to limit the actual number allocated based on two factors.
+        * First, we reserve some transmit/receive resources for the PF.
+        * Second, VMDQ also uses the same pools that SR-IOV does. We need to
+        * account for this, so that we don't accidentally allocate more VFs
+        * than we have available pools. The PCI bus driver already checks for
+        * other values out of range.
         */
-       if (num_vfs > IXGBE_MAX_VFS_DRV_LIMIT)
+       if ((num_vfs + adapter->num_rx_pools) > IXGBE_MAX_VF_FUNCTIONS)
                return -EPERM;
 
        adapter->num_vfs = num_vfs;