Skip to content
This repository has been archived by the owner on Dec 14, 2022. It is now read-only.

Commit

Permalink
Drivers: hv: util: Pass the channel information during the init call
Browse files Browse the repository at this point in the history
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 3cace4a ("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 <[email protected]>
Reported-by: Vitaly Kuznetsov <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
kattisrinivasan authored and gregkh committed Mar 2, 2016
1 parent d452ab7 commit b9830d1
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 @@ -251,7 +251,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 @@ -317,6 +316,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;

/*
* When this driver loads, the user level daemon that
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 @@ -639,7 +639,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 @@ -688,6 +687,7 @@ int
hv_kvp_init(struct hv_util_service *srv)
{
recv_buffer = srv->recv_buffer;
kvp_transaction.recv_channel = srv->channel;

/*
* When this driver loads, the user level daemon that
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 @@ -263,7 +263,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 @@ -337,6 +336,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 @@ -322,6 +322,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 @@ -1251,6 +1251,7 @@ u64 hv_do_hypercall(u64 control, void *input, void *output);

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 b9830d1

Please sign in to comment.