aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2016-12-22 19:54:01 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-12 00:41:49 -0500
commitd4d5b507c6427b417f4ff5411649e55af4447c84 (patch)
tree1d4bb1741f6e79e3eb864c65b035857d0c07d77a /drivers/hv
parent728fe696fd3ee551c24e02e7826dd9bdb89f1d47 (diff)
Drivers: hv: util: kvp: Fix a rescind processing issue
commit 5a66fecbf6aa528e375cbebccb1061cc58d80c84 upstream. KVP may use a char device to support the communication between the user level daemon and the driver. When the KVP channel is rescinded we need to make sure that the char device is fully cleaned up before we can process a new KVP offer from the host. Implement this logic. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/hv_kvp.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 5e1fdc8d32ab..3abfc5983c97 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -88,6 +88,7 @@ static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
88static const char kvp_devname[] = "vmbus/hv_kvp"; 88static const char kvp_devname[] = "vmbus/hv_kvp";
89static u8 *recv_buffer; 89static u8 *recv_buffer;
90static struct hvutil_transport *hvt; 90static struct hvutil_transport *hvt;
91static struct completion release_event;
91/* 92/*
92 * Register the kernel component with the user-level daemon. 93 * Register the kernel component with the user-level daemon.
93 * As part of this registration, pass the LIC version number. 94 * As part of this registration, pass the LIC version number.
@@ -716,6 +717,7 @@ static void kvp_on_reset(void)
716 if (cancel_delayed_work_sync(&kvp_timeout_work)) 717 if (cancel_delayed_work_sync(&kvp_timeout_work))
717 kvp_respond_to_host(NULL, HV_E_FAIL); 718 kvp_respond_to_host(NULL, HV_E_FAIL);
718 kvp_transaction.state = HVUTIL_DEVICE_INIT; 719 kvp_transaction.state = HVUTIL_DEVICE_INIT;
720 complete(&release_event);
719} 721}
720 722
721int 723int
@@ -724,6 +726,7 @@ hv_kvp_init(struct hv_util_service *srv)
724 recv_buffer = srv->recv_buffer; 726 recv_buffer = srv->recv_buffer;
725 kvp_transaction.recv_channel = srv->channel; 727 kvp_transaction.recv_channel = srv->channel;
726 728
729 init_completion(&release_event);
727 /* 730 /*
728 * When this driver loads, the user level daemon that 731 * When this driver loads, the user level daemon that
729 * processes the host requests may not yet be running. 732 * processes the host requests may not yet be running.
@@ -747,4 +750,5 @@ void hv_kvp_deinit(void)
747 cancel_delayed_work_sync(&kvp_timeout_work); 750 cancel_delayed_work_sync(&kvp_timeout_work);
748 cancel_work_sync(&kvp_sendkey_work); 751 cancel_work_sync(&kvp_sendkey_work);
749 hvutil_transport_destroy(hvt); 752 hvutil_transport_destroy(hvt);
753 wait_for_completion(&release_event);
750} 754}