summaryrefslogtreecommitdiff
path: root/arch/x86/include/asm/mshyperv.h
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2017-01-19 21:51:50 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-20 16:48:03 +0300
commite810e48c0c9a1a1ebb90cfe966bce6dc80ce08e7 (patch)
tree8fbbcdd8b1297e8968c78bb5f697f058923a4401 /arch/x86/include/asm/mshyperv.h
parent73638cddaad861a5ebb2b119d8b318d4bded8f8d (diff)
downloadlinux-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.h37
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