aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/hyperv
diff options
context:
space:
mode:
authorstephen hemminger <stephen@networkplumber.org>2017-01-11 12:16:32 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-02-04 03:47:08 -0500
commit5b3df4401064ef94cddac976aba1474a7050fa5e (patch)
treedbb347ccc3ff3c55b338f465a95e9713f562d78a /drivers/net/hyperv
parenta37f2311e63c8989675e297cdc9300cbec6e2217 (diff)
netvsc: add rcu_read locking to netvsc callback
[ Upstream commit 0719e72ccb801829a3d735d187ca8417f0930459 ] The receive callback (in tasklet context) is using RCU to get reference to associated VF network device but this is not safe. RCU read lock needs to be held. Found by running with full lockdep debugging enabled. Fixes: f207c10d9823 ("hv_netvsc: use RCU to protect vf_netdev") Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net/hyperv')
-rw-r--r--drivers/net/hyperv/netvsc_drv.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index c9140c3aeb67..ff038e507fd6 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -659,6 +659,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
659 * policy filters on the host). Deliver these via the VF 659 * policy filters on the host). Deliver these via the VF
660 * interface in the guest. 660 * interface in the guest.
661 */ 661 */
662 rcu_read_lock();
662 vf_netdev = rcu_dereference(net_device_ctx->vf_netdev); 663 vf_netdev = rcu_dereference(net_device_ctx->vf_netdev);
663 if (vf_netdev && (vf_netdev->flags & IFF_UP)) 664 if (vf_netdev && (vf_netdev->flags & IFF_UP))
664 net = vf_netdev; 665 net = vf_netdev;
@@ -667,6 +668,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
667 skb = netvsc_alloc_recv_skb(net, packet, csum_info, *data, vlan_tci); 668 skb = netvsc_alloc_recv_skb(net, packet, csum_info, *data, vlan_tci);
668 if (unlikely(!skb)) { 669 if (unlikely(!skb)) {
669 ++net->stats.rx_dropped; 670 ++net->stats.rx_dropped;
671 rcu_read_unlock();
670 return NVSP_STAT_FAIL; 672 return NVSP_STAT_FAIL;
671 } 673 }
672 674
@@ -696,6 +698,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
696 * TODO - use NAPI? 698 * TODO - use NAPI?
697 */ 699 */
698 netif_rx(skb); 700 netif_rx(skb);
701 rcu_read_unlock();
699 702
700 return 0; 703 return 0;
701} 704}