summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaiyang Zhang <haiyangz@microsoft.com>2011-09-01 12:19:43 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-09-06 11:56:18 -0700
commit692e084e773b76c30a3e5d823db131ed1a15924a (patch)
tree6955946fe66f2214d08d9d2cf26bdd4f55f011e9
parentc4b6a2eaf1c14810a4803d658f68614365978738 (diff)
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.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
index e6513be00c4..b49a08f4ed5 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;
}