Skip to content

Commit ae9e63b

Browse files
haiyangzdavem330
authored andcommitted
hyperv: Move wait completion msg code into rndis_filter_halt_device()
We need to wait for send_completion msg before put_rndis_request() at the end of rndis_filter_halt_device(). Otherwise, netvsc_send_completion() may reference freed memory which is overwritten, and cause panic. Reported-by: Long Li <[email protected]> Reported-by: Jason Wang <[email protected]> Signed-off-by: Haiyang Zhang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2207b60 commit ae9e63b

File tree

2 files changed

+11
-7
lines changed

2 files changed

+11
-7
lines changed

drivers/net/hyperv/netvsc.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -383,13 +383,6 @@ int netvsc_device_remove(struct hv_device *device)
383383
unsigned long flags;
384384

385385
net_device = hv_get_drvdata(device);
386-
spin_lock_irqsave(&device->channel->inbound_lock, flags);
387-
net_device->destroy = true;
388-
spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
389-
390-
/* Wait for all send completions */
391-
wait_event(net_device->wait_drain,
392-
atomic_read(&net_device->num_outstanding_sends) == 0);
393386

394387
netvsc_disconnect_vsp(net_device);
395388

drivers/net/hyperv/rndis_filter.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,9 @@ static void rndis_filter_halt_device(struct rndis_device *dev)
718718
{
719719
struct rndis_request *request;
720720
struct rndis_halt_request *halt;
721+
struct netvsc_device *nvdev = dev->net_dev;
722+
struct hv_device *hdev = nvdev->dev;
723+
ulong flags;
721724

722725
/* Attempt to do a rndis device halt */
723726
request = get_rndis_request(dev, RNDIS_MSG_HALT,
@@ -735,6 +738,14 @@ static void rndis_filter_halt_device(struct rndis_device *dev)
735738
dev->state = RNDIS_DEV_UNINITIALIZED;
736739

737740
cleanup:
741+
spin_lock_irqsave(&hdev->channel->inbound_lock, flags);
742+
nvdev->destroy = true;
743+
spin_unlock_irqrestore(&hdev->channel->inbound_lock, flags);
744+
745+
/* Wait for all send completions */
746+
wait_event(nvdev->wait_drain,
747+
atomic_read(&nvdev->num_outstanding_sends) == 0);
748+
738749
if (request)
739750
put_rndis_request(dev, request);
740751
return;

0 commit comments

Comments
 (0)