Skip to content

Commit 1932a62

Browse files
IronShenkuba-moo
authored andcommitted
net: hns3: add vlan list lock to protect vlan list
When adding port base VLAN, vf VLAN need to remove from HW and modify the vlan state in vf VLAN list as false. If the periodicity task is freeing the same node, it may cause "use after free" error. This patch adds a vlan list lock to protect the vlan list. Fixes: c6075b1 ("net: hns3: Record VF vlan tables") Signed-off-by: Jian Shen <shenjian15@huawei.com> Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent c0f46de commit 1932a62

2 files changed

Lines changed: 35 additions & 4 deletions

File tree

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9818,19 +9818,28 @@ static void hclge_add_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
98189818
bool writen_to_tbl)
98199819
{
98209820
struct hclge_vport_vlan_cfg *vlan, *tmp;
9821+
struct hclge_dev *hdev = vport->back;
98219822

9822-
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node)
9823-
if (vlan->vlan_id == vlan_id)
9823+
mutex_lock(&hdev->vport_lock);
9824+
9825+
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
9826+
if (vlan->vlan_id == vlan_id) {
9827+
mutex_unlock(&hdev->vport_lock);
98249828
return;
9829+
}
9830+
}
98259831

98269832
vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
9827-
if (!vlan)
9833+
if (!vlan) {
9834+
mutex_unlock(&hdev->vport_lock);
98289835
return;
9836+
}
98299837

98309838
vlan->hd_tbl_status = writen_to_tbl;
98319839
vlan->vlan_id = vlan_id;
98329840

98339841
list_add_tail(&vlan->node, &vport->vlan_list);
9842+
mutex_unlock(&hdev->vport_lock);
98349843
}
98359844

98369845
static int hclge_add_vport_all_vlan_table(struct hclge_vport *vport)
@@ -9839,6 +9848,8 @@ static int hclge_add_vport_all_vlan_table(struct hclge_vport *vport)
98399848
struct hclge_dev *hdev = vport->back;
98409849
int ret;
98419850

9851+
mutex_lock(&hdev->vport_lock);
9852+
98429853
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
98439854
if (!vlan->hd_tbl_status) {
98449855
ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q),
@@ -9848,12 +9859,16 @@ static int hclge_add_vport_all_vlan_table(struct hclge_vport *vport)
98489859
dev_err(&hdev->pdev->dev,
98499860
"restore vport vlan list failed, ret=%d\n",
98509861
ret);
9862+
9863+
mutex_unlock(&hdev->vport_lock);
98519864
return ret;
98529865
}
98539866
}
98549867
vlan->hd_tbl_status = true;
98559868
}
98569869

9870+
mutex_unlock(&hdev->vport_lock);
9871+
98579872
return 0;
98589873
}
98599874

@@ -9863,6 +9878,8 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
98639878
struct hclge_vport_vlan_cfg *vlan, *tmp;
98649879
struct hclge_dev *hdev = vport->back;
98659880

9881+
mutex_lock(&hdev->vport_lock);
9882+
98669883
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
98679884
if (vlan->vlan_id == vlan_id) {
98689885
if (is_write_tbl && vlan->hd_tbl_status)
@@ -9877,13 +9894,17 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
98779894
break;
98789895
}
98799896
}
9897+
9898+
mutex_unlock(&hdev->vport_lock);
98809899
}
98819900

98829901
void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list)
98839902
{
98849903
struct hclge_vport_vlan_cfg *vlan, *tmp;
98859904
struct hclge_dev *hdev = vport->back;
98869905

9906+
mutex_lock(&hdev->vport_lock);
9907+
98879908
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
98889909
if (vlan->hd_tbl_status)
98899910
hclge_set_vlan_filter_hw(hdev,
@@ -9899,6 +9920,7 @@ void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list)
98999920
}
99009921
}
99019922
clear_bit(vport->vport_id, hdev->vf_vlan_full);
9923+
mutex_unlock(&hdev->vport_lock);
99029924
}
99039925

99049926
void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev)
@@ -9907,13 +9929,17 @@ void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev)
99079929
struct hclge_vport *vport;
99089930
int i;
99099931

9932+
mutex_lock(&hdev->vport_lock);
9933+
99109934
for (i = 0; i < hdev->num_alloc_vport; i++) {
99119935
vport = &hdev->vport[i];
99129936
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
99139937
list_del(&vlan->node);
99149938
kfree(vlan);
99159939
}
99169940
}
9941+
9942+
mutex_unlock(&hdev->vport_lock);
99179943
}
99189944

99199945
void hclge_restore_vport_port_base_vlan_config(struct hclge_dev *hdev)
@@ -9953,6 +9979,8 @@ void hclge_restore_vport_vlan_table(struct hclge_vport *vport)
99539979
struct hclge_dev *hdev = vport->back;
99549980
int ret;
99559981

9982+
mutex_lock(&hdev->vport_lock);
9983+
99569984
if (vport->port_base_vlan_cfg.state == HNAE3_PORT_BASE_VLAN_DISABLE) {
99579985
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
99589986
ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q),
@@ -9963,6 +9991,8 @@ void hclge_restore_vport_vlan_table(struct hclge_vport *vport)
99639991
vlan->hd_tbl_status = true;
99649992
}
99659993
}
9994+
9995+
mutex_unlock(&hdev->vport_lock);
99669996
}
99679997

99689998
/* For global reset and imp reset, hardware will clear the mac table,
@@ -11861,8 +11891,8 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
1186111891
hclge_misc_irq_uninit(hdev);
1186211892
hclge_devlink_uninit(hdev);
1186311893
hclge_pci_uninit(hdev);
11864-
mutex_destroy(&hdev->vport_lock);
1186511894
hclge_uninit_vport_vlan_table(hdev);
11895+
mutex_destroy(&hdev->vport_lock);
1186611896
ae_dev->priv = NULL;
1186711897
}
1186811898

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,7 @@ struct hclge_vport {
10331033
spinlock_t mac_list_lock; /* protect mac address need to add/detele */
10341034
struct list_head uc_mac_list; /* Store VF unicast table */
10351035
struct list_head mc_mac_list; /* Store VF multicast table */
1036+
10361037
struct list_head vlan_list; /* Store VF vlan table */
10371038
};
10381039

0 commit comments

Comments
 (0)