|
@@ -48,7 +48,7 @@ static void i40e_vc_vf_broadcast(struct i40e_pf *pf,
|
|
|
int i;
|
|
|
|
|
|
for (i = 0; i < pf->num_alloc_vfs; i++, vf++) {
|
|
|
- int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
|
|
|
+ int abs_vf_id = vf->vf_id + (int)hw->func_caps.vf_base_id;
|
|
|
/* Not all vfs are enabled so skip the ones that are not */
|
|
|
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) &&
|
|
|
!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states))
|
|
@@ -74,7 +74,7 @@ static void i40e_vc_notify_vf_link_state(struct i40e_vf *vf)
|
|
|
struct i40e_pf *pf = vf->pf;
|
|
|
struct i40e_hw *hw = &pf->hw;
|
|
|
struct i40e_link_status *ls = &pf->hw.phy.link_info;
|
|
|
- int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
|
|
|
+ int abs_vf_id = vf->vf_id + (int)hw->func_caps.vf_base_id;
|
|
|
|
|
|
pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
|
|
|
pfe.severity = I40E_PF_EVENT_SEVERITY_INFO;
|
|
@@ -141,7 +141,7 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf)
|
|
|
!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states))
|
|
|
return;
|
|
|
|
|
|
- abs_vf_id = vf->vf_id + vf->pf->hw.func_caps.vf_base_id;
|
|
|
+ abs_vf_id = vf->vf_id + (int)vf->pf->hw.func_caps.vf_base_id;
|
|
|
|
|
|
pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING;
|
|
|
pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM;
|
|
@@ -860,7 +860,11 @@ static int i40e_alloc_vf_res(struct i40e_vf *vf)
|
|
|
if (ret)
|
|
|
goto error_alloc;
|
|
|
total_queue_pairs += pf->vsi[vf->lan_vsi_idx]->alloc_queue_pairs;
|
|
|
- set_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps);
|
|
|
+
|
|
|
+ if (vf->trusted)
|
|
|
+ set_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps);
|
|
|
+ else
|
|
|
+ clear_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps);
|
|
|
|
|
|
/* store the total qps number for the runtime
|
|
|
* VF req validation
|
|
@@ -1827,6 +1831,10 @@ error_param:
|
|
|
(u8 *)&stats, sizeof(stats));
|
|
|
}
|
|
|
|
|
|
+/* If the VF is not trusted restrict the number of MAC/VLAN it can program */
|
|
|
+#define I40E_VC_MAX_MAC_ADDR_PER_VF 8
|
|
|
+#define I40E_VC_MAX_VLAN_PER_VF 8
|
|
|
+
|
|
|
/**
|
|
|
* i40e_check_vf_permission
|
|
|
* @vf: pointer to the VF info
|
|
@@ -1847,15 +1855,22 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf, u8 *macaddr)
|
|
|
dev_err(&pf->pdev->dev, "invalid VF MAC addr %pM\n", macaddr);
|
|
|
ret = I40E_ERR_INVALID_MAC_ADDR;
|
|
|
} else if (vf->pf_set_mac && !is_multicast_ether_addr(macaddr) &&
|
|
|
+ !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) &&
|
|
|
!ether_addr_equal(macaddr, vf->default_lan_addr.addr)) {
|
|
|
/* If the host VMM administrator has set the VF MAC address
|
|
|
* administratively via the ndo_set_vf_mac command then deny
|
|
|
* permission to the VF to add or delete unicast MAC addresses.
|
|
|
+ * Unless the VF is privileged and then it can do whatever.
|
|
|
* The VF may request to set the MAC address filter already
|
|
|
* assigned to it so do not return an error in that case.
|
|
|
*/
|
|
|
dev_err(&pf->pdev->dev,
|
|
|
- "VF attempting to override administratively set MAC address\nPlease reload the VF driver to resume normal operation\n");
|
|
|
+ "VF attempting to override administratively set MAC address, reload the VF driver to resume normal operation\n");
|
|
|
+ ret = -EPERM;
|
|
|
+ } else if ((vf->num_mac >= I40E_VC_MAX_MAC_ADDR_PER_VF) &&
|
|
|
+ !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps)) {
|
|
|
+ dev_err(&pf->pdev->dev,
|
|
|
+ "VF is not trusted, switch the VF to trusted to add more functionality\n");
|
|
|
ret = -EPERM;
|
|
|
}
|
|
|
return ret;
|
|
@@ -1880,7 +1895,6 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
|
|
|
int i;
|
|
|
|
|
|
if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states) ||
|
|
|
- !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) ||
|
|
|
!i40e_vc_isvalid_vsi_id(vf, vsi_id)) {
|
|
|
ret = I40E_ERR_PARAM;
|
|
|
goto error_param;
|
|
@@ -1919,6 +1933,8 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
|
|
|
ret = I40E_ERR_PARAM;
|
|
|
spin_unlock_bh(&vsi->mac_filter_list_lock);
|
|
|
goto error_param;
|
|
|
+ } else {
|
|
|
+ vf->num_mac++;
|
|
|
}
|
|
|
}
|
|
|
spin_unlock_bh(&vsi->mac_filter_list_lock);
|
|
@@ -1954,7 +1970,6 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
|
|
|
int i;
|
|
|
|
|
|
if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states) ||
|
|
|
- !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) ||
|
|
|
!i40e_vc_isvalid_vsi_id(vf, vsi_id)) {
|
|
|
ret = I40E_ERR_PARAM;
|
|
|
goto error_param;
|
|
@@ -1978,6 +1993,8 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
|
|
|
ret = I40E_ERR_INVALID_MAC_ADDR;
|
|
|
spin_unlock_bh(&vsi->mac_filter_list_lock);
|
|
|
goto error_param;
|
|
|
+ } else {
|
|
|
+ vf->num_mac--;
|
|
|
}
|
|
|
|
|
|
spin_unlock_bh(&vsi->mac_filter_list_lock);
|
|
@@ -2012,8 +2029,13 @@ static int i40e_vc_add_vlan_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
|
|
|
i40e_status aq_ret = 0;
|
|
|
int i;
|
|
|
|
|
|
+ if ((vf->num_vlan >= I40E_VC_MAX_VLAN_PER_VF) &&
|
|
|
+ !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps)) {
|
|
|
+ dev_err(&pf->pdev->dev,
|
|
|
+ "VF is not trusted, switch the VF to trusted to add more VLAN addresses\n");
|
|
|
+ goto error_param;
|
|
|
+ }
|
|
|
if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states) ||
|
|
|
- !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) ||
|
|
|
!i40e_vc_isvalid_vsi_id(vf, vsi_id)) {
|
|
|
aq_ret = I40E_ERR_PARAM;
|
|
|
goto error_param;
|
|
@@ -2037,6 +2059,8 @@ static int i40e_vc_add_vlan_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
|
|
|
for (i = 0; i < vfl->num_elements; i++) {
|
|
|
/* add new VLAN filter */
|
|
|
int ret = i40e_vsi_add_vlan(vsi, vfl->vlan_id[i]);
|
|
|
+ if (!ret)
|
|
|
+ vf->num_vlan++;
|
|
|
|
|
|
if (test_bit(I40E_VF_STAT_UC_PROMISC, &vf->vf_states))
|
|
|
i40e_aq_set_vsi_uc_promisc_on_vlan(&pf->hw, vsi->seid,
|
|
@@ -2079,7 +2103,6 @@ static int i40e_vc_remove_vlan_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
|
|
|
int i;
|
|
|
|
|
|
if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states) ||
|
|
|
- !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) ||
|
|
|
!i40e_vc_isvalid_vsi_id(vf, vsi_id)) {
|
|
|
aq_ret = I40E_ERR_PARAM;
|
|
|
goto error_param;
|
|
@@ -2100,6 +2123,8 @@ static int i40e_vc_remove_vlan_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
|
|
|
|
|
|
for (i = 0; i < vfl->num_elements; i++) {
|
|
|
int ret = i40e_vsi_kill_vlan(vsi, vfl->vlan_id[i]);
|
|
|
+ if (!ret)
|
|
|
+ vf->num_vlan--;
|
|
|
|
|
|
if (test_bit(I40E_VF_STAT_UC_PROMISC, &vf->vf_states))
|
|
|
i40e_aq_set_vsi_uc_promisc_on_vlan(&pf->hw, vsi->seid,
|
|
@@ -2207,7 +2232,6 @@ static int i40e_vc_config_rss_key(struct i40e_vf *vf, u8 *msg, u16 msglen)
|
|
|
i40e_status aq_ret = 0;
|
|
|
|
|
|
if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states) ||
|
|
|
- !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) ||
|
|
|
!i40e_vc_isvalid_vsi_id(vf, vsi_id) ||
|
|
|
(vrk->key_len != I40E_HKEY_ARRAY_SIZE)) {
|
|
|
aq_ret = I40E_ERR_PARAM;
|
|
@@ -2240,7 +2264,6 @@ static int i40e_vc_config_rss_lut(struct i40e_vf *vf, u8 *msg, u16 msglen)
|
|
|
i40e_status aq_ret = 0;
|
|
|
|
|
|
if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states) ||
|
|
|
- !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) ||
|
|
|
!i40e_vc_isvalid_vsi_id(vf, vsi_id) ||
|
|
|
(vrl->lut_entries != I40E_VF_HLUT_ARRAY_SIZE)) {
|
|
|
aq_ret = I40E_ERR_PARAM;
|
|
@@ -2270,8 +2293,7 @@ static int i40e_vc_get_rss_hena(struct i40e_vf *vf, u8 *msg, u16 msglen)
|
|
|
i40e_status aq_ret = 0;
|
|
|
int len = 0;
|
|
|
|
|
|
- if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states) ||
|
|
|
- !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps)) {
|
|
|
+ if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states)) {
|
|
|
aq_ret = I40E_ERR_PARAM;
|
|
|
goto err;
|
|
|
}
|
|
@@ -2307,8 +2329,7 @@ static int i40e_vc_set_rss_hena(struct i40e_vf *vf, u8 *msg, u16 msglen)
|
|
|
struct i40e_hw *hw = &pf->hw;
|
|
|
i40e_status aq_ret = 0;
|
|
|
|
|
|
- if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states) ||
|
|
|
- !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps)) {
|
|
|
+ if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states)) {
|
|
|
aq_ret = I40E_ERR_PARAM;
|
|
|
goto err;
|
|
|
}
|
|
@@ -2335,7 +2356,7 @@ static int i40e_vc_validate_vf_msg(struct i40e_vf *vf, u32 v_opcode,
|
|
|
u32 v_retval, u8 *msg, u16 msglen)
|
|
|
{
|
|
|
bool err_msg_format = false;
|
|
|
- int valid_len;
|
|
|
+ int valid_len = 0;
|
|
|
|
|
|
/* Check if VF is disabled. */
|
|
|
if (test_bit(I40E_VF_STAT_DISABLED, &vf->vf_states))
|
|
@@ -2347,13 +2368,10 @@ static int i40e_vc_validate_vf_msg(struct i40e_vf *vf, u32 v_opcode,
|
|
|
valid_len = sizeof(struct i40e_virtchnl_version_info);
|
|
|
break;
|
|
|
case I40E_VIRTCHNL_OP_RESET_VF:
|
|
|
- valid_len = 0;
|
|
|
break;
|
|
|
case I40E_VIRTCHNL_OP_GET_VF_RESOURCES:
|
|
|
if (VF_IS_V11(vf))
|
|
|
valid_len = sizeof(u32);
|
|
|
- else
|
|
|
- valid_len = 0;
|
|
|
break;
|
|
|
case I40E_VIRTCHNL_OP_CONFIG_TX_QUEUE:
|
|
|
valid_len = sizeof(struct i40e_virtchnl_txq_info);
|
|
@@ -2468,7 +2486,6 @@ static int i40e_vc_validate_vf_msg(struct i40e_vf *vf, u32 v_opcode,
|
|
|
}
|
|
|
break;
|
|
|
case I40E_VIRTCHNL_OP_GET_RSS_HENA_CAPS:
|
|
|
- valid_len = 0;
|
|
|
break;
|
|
|
case I40E_VIRTCHNL_OP_SET_RSS_HENA:
|
|
|
valid_len = sizeof(struct i40e_virtchnl_rss_hena);
|
|
@@ -2499,11 +2516,11 @@ static int i40e_vc_validate_vf_msg(struct i40e_vf *vf, u32 v_opcode,
|
|
|
* called from the common aeq/arq handler to
|
|
|
* process request from VF
|
|
|
**/
|
|
|
-int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode,
|
|
|
+int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode,
|
|
|
u32 v_retval, u8 *msg, u16 msglen)
|
|
|
{
|
|
|
struct i40e_hw *hw = &pf->hw;
|
|
|
- unsigned int local_vf_id = vf_id - hw->func_caps.vf_base_id;
|
|
|
+ int local_vf_id = vf_id - (s16)hw->func_caps.vf_base_id;
|
|
|
struct i40e_vf *vf;
|
|
|
int ret;
|
|
|
|
|
@@ -2605,9 +2622,10 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode,
|
|
|
**/
|
|
|
int i40e_vc_process_vflr_event(struct i40e_pf *pf)
|
|
|
{
|
|
|
- u32 reg, reg_idx, bit_idx, vf_id;
|
|
|
struct i40e_hw *hw = &pf->hw;
|
|
|
+ u32 reg, reg_idx, bit_idx;
|
|
|
struct i40e_vf *vf;
|
|
|
+ int vf_id;
|
|
|
|
|
|
if (!test_bit(__I40E_VFLR_EVENT_PENDING, &pf->state))
|
|
|
return 0;
|