diff options
author | Haiyang Zhang <haiyangz@microsoft.com> | 2011-09-01 19:19:43 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-09-06 18:56:18 (GMT) |
commit | 692e084e773b76c30a3e5d823db131ed1a15924a (patch) | |
tree | 6955946fe66f2214d08d9d2cf26bdd4f55f011e9 | |
parent | c4b6a2eaf1c14810a4803d658f68614365978738 (diff) | |
download | linux-692e084e773b76c30a3e5d823db131ed1a15924a.tar.xz |
staging: hv: re-order the code in netvsc_probe()
Re-order the code in netvsc_probe() to prevent a guest crash caused by
packets possibly received from NetVSP before call to register_netdev().
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/staging/hv/netvsc_drv.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index e6513be..b49a08f 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -348,19 +348,6 @@ static int netvsc_probe(struct hv_device *dev) dev_set_drvdata(&dev->device, net); INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp); - /* Notify the netvsc driver of the new device */ - device_info.ring_size = ring_size; - ret = rndis_filter_device_add(dev, &device_info); - if (ret != 0) { - free_netdev(net); - dev_set_drvdata(&dev->device, NULL); - return ret; - } - - netif_carrier_on(net); - - memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); - net->netdev_ops = &device_ops; /* TODO: Add GSO and Checksum offload */ @@ -372,11 +359,26 @@ static int netvsc_probe(struct hv_device *dev) ret = register_netdev(net); if (ret != 0) { - /* Remove the device and release the resource */ - rndis_filter_device_remove(dev); + pr_err("Unable to register netdev.\n"); free_netdev(net); + goto out; } + /* Notify the netvsc driver of the new device */ + device_info.ring_size = ring_size; + ret = rndis_filter_device_add(dev, &device_info); + if (ret != 0) { + netdev_err(net, "unable to add netvsc device (ret %d)\n", ret); + unregister_netdev(net); + free_netdev(net); + dev_set_drvdata(&dev->device, NULL); + return ret; + } + memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); + + netif_carrier_on(net); + +out: return ret; } |