Skip to content

Commit 3b49d79

Browse files
haiyangzNipaLocal
authored andcommitted
hv_netvsc: Switch VF namespace in netvsc_open instead
The existing code move the VF NIC to new namespace when NETDEV_REGISTER is received on netvsc NIC. During deletion of the namespace, default_device_exit_batch() >> default_device_exit_net() is called. When netvsc NIC is moved back and registered to the default namespace, it automatically brings VF NIC back to the default namespace. This will cause the default_device_exit_net() >> for_each_netdev_safe loop unable to detect the list end, and hit NULL ptr: [ 231.449420] mana 7870:00:00.0 enP30832s1: Moved VF to namespace with: eth0 [ 231.449656] BUG: kernel NULL pointer dereference, address: 0000000000000010 [ 231.450246] #PF: supervisor read access in kernel mode [ 231.450579] #PF: error_code(0x0000) - not-present page [ 231.450916] PGD 17b8a8067 P4D 0 [ 231.451163] Oops: Oops: 0000 [kernel-patches#1] SMP NOPTI [ 231.451450] CPU: 82 UID: 0 PID: 1394 Comm: kworker/u768:1 Not tainted 6.16.0-rc4+ kernel-patches#3 VOLUNTARY [ 231.452042] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 11/21/2024 [ 231.452692] Workqueue: netns cleanup_net [ 231.452947] RIP: 0010:default_device_exit_batch+0x16c/0x3f0 [ 231.453326] Code: c0 0c f5 b3 e8 d5 db fe ff 48 85 c0 74 15 48 c7 c2 f8 fd ca b2 be 10 00 00 00 48 8d 7d c0 e8 7b 77 25 00 49 8b 86 28 01 00 00 <48> 8b 50 10 4c 8b 2a 4c 8d 62 f0 49 83 ed 10 4c 39 e0 0f 84 d6 00 [ 231.454294] RSP: 0018:ff75fc7c9bf9fd00 EFLAGS: 00010246 [ 231.454610] RAX: 0000000000000000 RBX: 0000000000000002 RCX: 61c8864680b583eb [ 231.455094] RDX: ff1fa9f71462d800 RSI: ff75fc7c9bf9fd38 RDI: 0000000030766564 [ 231.455686] RBP: ff75fc7c9bf9fd78 R08: 0000000000000000 R09: 0000000000000000 [ 231.456126] R10: 0000000000000001 R11: 0000000000000004 R12: ff1fa9f70088e340 [ 231.456621] R13: ff1fa9f70088e340 R14: ffffffffb3f50c20 R15: ff1fa9f7103e6340 [ 231.457161] FS: 0000000000000000(0000) GS:ff1faa6783a08000(0000) knlGS:0000000000000000 [ 231.457707] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 231.458031] CR2: 0000000000000010 CR3: 0000000179ab2006 CR4: 0000000000b73ef0 [ 231.458434] Call Trace: [ 231.458600] <TASK> [ 231.458777] ops_undo_list+0x100/0x220 [ 231.459015] cleanup_net+0x1b8/0x300 [ 231.459285] process_one_work+0x184/0x340 To fix it, move the VF namespace switching code from the NETDEV_REGISTER event handler to netvsc_open(). Cc: [email protected] Cc: [email protected] Fixes: 4c26280 ("hv_netvsc: Fix VF namespace also in synthetic NIC NETDEV_REGISTER event") Signed-off-by: Haiyang Zhang <[email protected]> Signed-off-by: NipaLocal <nipa@local>
1 parent feca61c commit 3b49d79

File tree

1 file changed

+13
-30
lines changed

1 file changed

+13
-30
lines changed

drivers/net/hyperv/netvsc_drv.c

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,19 @@ static int netvsc_open(struct net_device *net)
135135
}
136136

137137
if (vf_netdev) {
138+
if (!net_eq(dev_net(net), dev_net(vf_netdev))) {
139+
ret = dev_change_net_namespace(vf_netdev, dev_net(net),
140+
"eth%d");
141+
if (ret)
142+
netdev_err(vf_netdev,
143+
"Cannot move to same ns as %s: %d\n",
144+
net->name, ret);
145+
else
146+
netdev_info(vf_netdev,
147+
"Moved VF to namespace with: %s\n",
148+
net->name);
149+
}
150+
138151
/* Setting synthetic device up transparently sets
139152
* slave as up. If open fails, then slave will be
140153
* still be offline (and not used).
@@ -2772,31 +2785,6 @@ static struct hv_driver netvsc_drv = {
27722785
},
27732786
};
27742787

2775-
/* Set VF's namespace same as the synthetic NIC */
2776-
static void netvsc_event_set_vf_ns(struct net_device *ndev)
2777-
{
2778-
struct net_device_context *ndev_ctx = netdev_priv(ndev);
2779-
struct net_device *vf_netdev;
2780-
int ret;
2781-
2782-
vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
2783-
if (!vf_netdev)
2784-
return;
2785-
2786-
if (!net_eq(dev_net(ndev), dev_net(vf_netdev))) {
2787-
ret = dev_change_net_namespace(vf_netdev, dev_net(ndev),
2788-
"eth%d");
2789-
if (ret)
2790-
netdev_err(vf_netdev,
2791-
"Cannot move to same namespace as %s: %d\n",
2792-
ndev->name, ret);
2793-
else
2794-
netdev_info(vf_netdev,
2795-
"Moved VF to namespace with: %s\n",
2796-
ndev->name);
2797-
}
2798-
}
2799-
28002788
/*
28012789
* On Hyper-V, every VF interface is matched with a corresponding
28022790
* synthetic interface. The synthetic interface is presented first
@@ -2809,11 +2797,6 @@ static int netvsc_netdev_event(struct notifier_block *this,
28092797
struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
28102798
int ret = 0;
28112799

2812-
if (event_dev->netdev_ops == &device_ops && event == NETDEV_REGISTER) {
2813-
netvsc_event_set_vf_ns(event_dev);
2814-
return NOTIFY_DONE;
2815-
}
2816-
28172800
ret = check_dev_is_matching_vf(event_dev);
28182801
if (ret != 0)
28192802
return NOTIFY_DONE;

0 commit comments

Comments
 (0)