summaryrefslogtreecommitdiff
path: root/drivers/hv/hyperv_vmbus.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hv/hyperv_vmbus.h')
-rw-r--r--drivers/hv/hyperv_vmbus.h23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 12321b93a756..718b5c72f0c8 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -36,6 +36,11 @@
#define HV_UTIL_TIMEOUT 30
/*
+ * Timeout for guest-host handshake for services.
+ */
+#define HV_UTIL_NEGO_TIMEOUT 60
+
+/*
* The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
* is set by CPUID(HVCPUID_VERSION_FEATURES).
*/
@@ -620,9 +625,21 @@ extern struct vmbus_channel_message_table_entry
channel_message_table[CHANNELMSG_COUNT];
/* Free the message slot and signal end-of-message if required */
-static inline void vmbus_signal_eom(struct hv_message *msg)
+static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type)
{
- msg->header.message_type = HVMSG_NONE;
+ /*
+ * 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
@@ -667,8 +684,6 @@ void vmbus_disconnect(void);
int vmbus_post_msg(void *buffer, size_t buflen);
-void vmbus_set_event(struct vmbus_channel *channel);
-
void vmbus_on_event(unsigned long data);
void vmbus_on_msg_dpc(unsigned long data);