diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2017-01-19 21:51:50 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-20 16:48:03 +0300 |
commit | e810e48c0c9a1a1ebb90cfe966bce6dc80ce08e7 (patch) | |
tree | 8fbbcdd8b1297e8968c78bb5f697f058923a4401 /arch/x86/include/asm/mshyperv.h | |
parent | 73638cddaad861a5ebb2b119d8b318d4bded8f8d (diff) | |
download | linux-e810e48c0c9a1a1ebb90cfe966bce6dc80ce08e7.tar.xz |
Drivers: hv: vmbus: Move the code to signal end of message
As part of the effort to separate out architecture specific code, move the
code for signaling end of message.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/x86/include/asm/mshyperv.h')
-rw-r--r-- | arch/x86/include/asm/mshyperv.h | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index c843ef64defe..b57b470ac2a7 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -99,6 +99,43 @@ static inline __u64 generate_guest_id(__u64 d_info1, __u64 kernel_version, return guest_id; } + +/* Free the message slot and signal end-of-message if required */ +static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type) +{ + /* + * On crash we're reading some other CPU's message page and we need + * to be careful: this other CPU may already had cleared the header + * and the host may already had delivered some other message there. + * In case we blindly write msg->header.message_type we're going + * to lose it. We can still lose a message of the same type but + * we count on the fact that there can only be one + * CHANNELMSG_UNLOAD_RESPONSE and we don't care about other messages + * on crash. + */ + if (cmpxchg(&msg->header.message_type, old_msg_type, + HVMSG_NONE) != old_msg_type) + return; + + /* + * Make sure the write to MessageType (ie set to + * HVMSG_NONE) happens before we read the + * MessagePending and EOMing. Otherwise, the EOMing + * will not deliver any more messages since there is + * no empty slot + */ + mb(); + + if (msg->header.message_flags.msg_pending) { + /* + * This will cause message queue rescan to + * possibly deliver another msg from the + * hypervisor + */ + wrmsrl(HV_X64_MSR_EOM, 0); + } +} + void hyperv_callback_vector(void); #ifdef CONFIG_TRACING #define trace_hyperv_callback_vector hyperv_callback_vector |