Skip to content

Commit b3e7b3a

Browse files
Michal Swiatkowskianguy11
authored andcommitted
ice: prevent NULL pointer deref during reload
Calling ethtool during reload can lead to call trace, because VSI isn't configured for some time, but netdev is alive. To fix it add rtnl lock for VSI deconfig and config. Set ::num_q_vectors to 0 after freeing and add a check for ::tx/rx_rings in ring related ethtool ops. Add proper unroll of filters in ice_start_eth(). Reproduction: $watch -n 0.1 -d 'ethtool -g enp24s0f0np0' $devlink dev reload pci/0000:18:00.0 action driver_reinit Call trace before fix: [66303.926205] BUG: kernel NULL pointer dereference, address: 0000000000000000 [66303.926259] #PF: supervisor read access in kernel mode [66303.926286] #PF: error_code(0x0000) - not-present page [66303.926311] PGD 0 P4D 0 [66303.926332] Oops: 0000 [#1] PREEMPT SMP PTI [66303.926358] CPU: 4 PID: 933821 Comm: ethtool Kdump: loaded Tainted: G OE 6.4.0-rc5+ #1 [66303.926400] Hardware name: Intel Corporation S2600WFT/S2600WFT, BIOS SE5C620.86B.00.01.0014.070920180847 07/09/2018 [66303.926446] RIP: 0010:ice_get_ringparam+0x22/0x50 [ice] [66303.926649] Code: 90 90 90 90 90 90 90 90 f3 0f 1e fa 0f 1f 44 00 00 48 8b 87 c0 09 00 00 c7 46 04 e0 1f 00 00 c7 46 10 e0 1f 00 00 48 8b 50 20 <48> 8b 12 0f b7 52 3a 89 56 14 48 8b 40 28 48 8b 00 0f b7 40 58 48 [66303.926722] RSP: 0018:ffffad40472f39c8 EFLAGS: 00010246 [66303.926749] RAX: ffff98a8ada05828 RBX: ffff98a8c46dd060 RCX: ffffad40472f3b48 [66303.926781] RDX: 0000000000000000 RSI: ffff98a8c46dd068 RDI: ffff98a8b23c4000 [66303.926811] RBP: ffffad40472f3b48 R08: 00000000000337b0 R09: 0000000000000000 [66303.926843] R10: 0000000000000001 R11: 0000000000000100 R12: ffff98a8b23c4000 [66303.926874] R13: ffff98a8c46dd060 R14: 000000000000000f R15: ffffad40472f3a50 [66303.926906] FS: 00007f6397966740(0000) GS:ffff98b390900000(0000) knlGS:0000000000000000 [66303.926941] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [66303.926967] CR2: 0000000000000000 CR3: 000000011ac20002 CR4: 00000000007706e0 [66303.926999] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [66303.927029] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [66303.927060] PKRU: 55555554 [66303.927075] Call Trace: [66303.927094] <TASK> [66303.927111] ? __die+0x23/0x70 [66303.927140] ? page_fault_oops+0x171/0x4e0 [66303.927176] ? exc_page_fault+0x7f/0x180 [66303.927209] ? asm_exc_page_fault+0x26/0x30 [66303.927244] ? ice_get_ringparam+0x22/0x50 [ice] [66303.927433] rings_prepare_data+0x62/0x80 [66303.927469] ethnl_default_doit+0xe2/0x350 [66303.927501] genl_family_rcv_msg_doit.isra.0+0xe3/0x140 [66303.927538] genl_rcv_msg+0x1b1/0x2c0 [66303.927561] ? __pfx_ethnl_default_doit+0x10/0x10 [66303.927590] ? __pfx_genl_rcv_msg+0x10/0x10 [66303.927615] netlink_rcv_skb+0x58/0x110 [66303.927644] genl_rcv+0x28/0x40 [66303.927665] netlink_unicast+0x19e/0x290 [66303.927691] netlink_sendmsg+0x254/0x4d0 [66303.927717] sock_sendmsg+0x93/0xa0 [66303.927743] __sys_sendto+0x126/0x170 [66303.927780] __x64_sys_sendto+0x24/0x30 [66303.928593] do_syscall_64+0x5d/0x90 [66303.929370] ? __count_memcg_events+0x60/0xa0 [66303.930146] ? count_memcg_events.constprop.0+0x1a/0x30 [66303.930920] ? handle_mm_fault+0x9e/0x350 [66303.931688] ? do_user_addr_fault+0x258/0x740 [66303.932452] ? exc_page_fault+0x7f/0x180 [66303.933193] entry_SYSCALL_64_after_hwframe+0x72/0xdc Fixes: 5b246e5 ("ice: split probe into smaller functions") Reviewed-by: Przemek Kitszel <[email protected]> Signed-off-by: Michal Swiatkowski <[email protected]> Reviewed-by: Simon Horman <[email protected]> Tested-by: Pucha Himasekhar Reddy <[email protected]> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <[email protected]>
1 parent 24a3298 commit b3e7b3a

File tree

3 files changed

+21
-4
lines changed

3 files changed

+21
-4
lines changed

drivers/net/ethernet/intel/ice/ice_base.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,8 @@ void ice_vsi_free_q_vectors(struct ice_vsi *vsi)
800800

801801
ice_for_each_q_vector(vsi, v_idx)
802802
ice_free_q_vector(vsi, v_idx);
803+
804+
vsi->num_q_vectors = 0;
803805
}
804806

805807
/**

drivers/net/ethernet/intel/ice/ice_ethtool.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2681,8 +2681,13 @@ ice_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring,
26812681

26822682
ring->rx_max_pending = ICE_MAX_NUM_DESC;
26832683
ring->tx_max_pending = ICE_MAX_NUM_DESC;
2684-
ring->rx_pending = vsi->rx_rings[0]->count;
2685-
ring->tx_pending = vsi->tx_rings[0]->count;
2684+
if (vsi->tx_rings && vsi->rx_rings) {
2685+
ring->rx_pending = vsi->rx_rings[0]->count;
2686+
ring->tx_pending = vsi->tx_rings[0]->count;
2687+
} else {
2688+
ring->rx_pending = 0;
2689+
ring->tx_pending = 0;
2690+
}
26862691

26872692
/* Rx mini and jumbo rings are not supported */
26882693
ring->rx_mini_max_pending = 0;
@@ -2716,6 +2721,10 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring,
27162721
return -EINVAL;
27172722
}
27182723

2724+
/* Return if there is no rings (device is reloading) */
2725+
if (!vsi->tx_rings || !vsi->rx_rings)
2726+
return -EBUSY;
2727+
27192728
new_tx_cnt = ALIGN(ring->tx_pending, ICE_REQ_DESC_MULTIPLE);
27202729
if (new_tx_cnt != ring->tx_pending)
27212730
netdev_info(netdev, "Requested Tx descriptor count rounded up to %d\n",

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4430,9 +4430,9 @@ static int ice_start_eth(struct ice_vsi *vsi)
44304430
if (err)
44314431
return err;
44324432

4433-
rtnl_lock();
44344433
err = ice_vsi_open(vsi);
4435-
rtnl_unlock();
4434+
if (err)
4435+
ice_fltr_remove_all(vsi);
44364436

44374437
return err;
44384438
}
@@ -4895,13 +4895,15 @@ int ice_load(struct ice_pf *pf)
48954895
params = ice_vsi_to_params(vsi);
48964896
params.flags = ICE_VSI_FLAG_INIT;
48974897

4898+
rtnl_lock();
48984899
err = ice_vsi_cfg(vsi, &params);
48994900
if (err)
49004901
goto err_vsi_cfg;
49014902

49024903
err = ice_start_eth(ice_get_main_vsi(pf));
49034904
if (err)
49044905
goto err_start_eth;
4906+
rtnl_unlock();
49054907

49064908
err = ice_init_rdma(pf);
49074909
if (err)
@@ -4916,9 +4918,11 @@ int ice_load(struct ice_pf *pf)
49164918

49174919
err_init_rdma:
49184920
ice_vsi_close(ice_get_main_vsi(pf));
4921+
rtnl_lock();
49194922
err_start_eth:
49204923
ice_vsi_decfg(ice_get_main_vsi(pf));
49214924
err_vsi_cfg:
4925+
rtnl_unlock();
49224926
ice_deinit_dev(pf);
49234927
return err;
49244928
}
@@ -4931,8 +4935,10 @@ void ice_unload(struct ice_pf *pf)
49314935
{
49324936
ice_deinit_features(pf);
49334937
ice_deinit_rdma(pf);
4938+
rtnl_lock();
49344939
ice_stop_eth(ice_get_main_vsi(pf));
49354940
ice_vsi_decfg(ice_get_main_vsi(pf));
4941+
rtnl_unlock();
49364942
ice_deinit_dev(pf);
49374943
}
49384944

0 commit comments

Comments
 (0)