Skip to content

Commit

Permalink
Drivers: hv: util: Pass the channel information during the init call
Browse files Browse the repository at this point in the history
commit b9830d120cbe155863399f25eaef6aa8353e767f upstream.

Pass the channel information to the util drivers that need to defer
reading the channel while they are processing a request. This would address
the following issue reported by Vitaly:

Commit 3cace4a61610 ("Drivers: hv: utils: run polling callback always in
interrupt context") removed direct *_transaction.state = HVUTIL_READY
assignments from *_handle_handshake() functions introducing the following
race: if a userspace daemon connects before we get first non-negotiation
request from the server hv_poll_channel() won't set transaction state to
HVUTIL_READY as (!channel) condition will fail, we set it to non-NULL on
the first real request from the server.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reported-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
kattisrinivasan authored and gregkh committed Oct 20, 2018
1 parent f91b8b1 commit eaee797
Show file tree
Hide file tree
Showing 5 changed files with 5 additions and 3 deletions.
2 changes: 1 addition & 1 deletion drivers/hv/hv_fcopy.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ void hv_fcopy_onchannelcallback(void *context)
*/

fcopy_transaction.recv_len = recvlen;
fcopy_transaction.recv_channel = channel;
fcopy_transaction.recv_req_id = requestid;
fcopy_transaction.fcopy_msg = fcopy_msg;

Expand Down Expand Up @@ -323,6 +322,7 @@ static void fcopy_on_reset(void)
int hv_fcopy_init(struct hv_util_service *srv)
{
recv_buffer = srv->recv_buffer;
fcopy_transaction.recv_channel = srv->channel;

init_completion(&release_event);
/*
Expand Down
2 changes: 1 addition & 1 deletion drivers/hv/hv_kvp.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,6 @@ void hv_kvp_onchannelcallback(void *context)
*/

kvp_transaction.recv_len = recvlen;
kvp_transaction.recv_channel = channel;
kvp_transaction.recv_req_id = requestid;
kvp_transaction.kvp_msg = kvp_msg;

Expand Down Expand Up @@ -690,6 +689,7 @@ int
hv_kvp_init(struct hv_util_service *srv)
{
recv_buffer = srv->recv_buffer;
kvp_transaction.recv_channel = srv->channel;

init_completion(&release_event);
/*
Expand Down
2 changes: 1 addition & 1 deletion drivers/hv/hv_snapshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ void hv_vss_onchannelcallback(void *context)
*/

vss_transaction.recv_len = recvlen;
vss_transaction.recv_channel = channel;
vss_transaction.recv_req_id = requestid;
vss_transaction.msg = (struct hv_vss_msg *)vss_msg;

Expand Down Expand Up @@ -340,6 +339,7 @@ hv_vss_init(struct hv_util_service *srv)
return -ENOTSUPP;
}
recv_buffer = srv->recv_buffer;
vss_transaction.recv_channel = srv->channel;

/*
* When this driver loads, the user level daemon that
Expand Down
1 change: 1 addition & 0 deletions drivers/hv/hv_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ static int util_probe(struct hv_device *dev,
srv->recv_buffer = kmalloc(PAGE_SIZE * 4, GFP_KERNEL);
if (!srv->recv_buffer)
return -ENOMEM;
srv->channel = dev->channel;
if (srv->util_init) {
ret = srv->util_init(srv);
if (ret) {
Expand Down
1 change: 1 addition & 0 deletions include/linux/hyperv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,7 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,

struct hv_util_service {
u8 *recv_buffer;
void *channel;
void (*util_cb)(void *);
int (*util_init)(struct hv_util_service *);
void (*util_deinit)(void);
Expand Down

0 comments on commit eaee797

Please sign in to comment.