Drivers: hv: Manage signaling state on a per-connection basis
authorK. Y. Srinivasan <kys@microsoft.com>
Sat, 1 Dec 2012 14:46:45 +0000 (06:46 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Jan 2013 19:34:37 +0000 (11:34 -0800)
The current code has a global handle for supporting signaling of the host
from guest. Make this a per-channel attribute as on some versions of the
host we can signal on per-channel handle.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/hv/channel_mgmt.c
drivers/hv/hyperv_vmbus.h
include/linux/hyperv.h

index 7bf59177aaf8e8883a36e17d918936469863c88c..f4d990285d99b602e68737667a83515a1bf7be13 100644 (file)
@@ -282,6 +282,26 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
         */
        newchannel->batched_reading = true;
 
+       /*
+        * Setup state for signalling the host.
+        */
+       newchannel->sig_event = (struct hv_input_signal_event *)
+                               (ALIGN((unsigned long)
+                               &newchannel->sig_buf,
+                               HV_HYPERCALL_PARAM_ALIGN));
+
+       newchannel->sig_event->connectionid.asu32 = 0;
+       newchannel->sig_event->connectionid.u.id = VMBUS_EVENT_CONNECTION_ID;
+       newchannel->sig_event->flag_number = 0;
+       newchannel->sig_event->rsvdz = 0;
+
+       if (vmbus_proto_version != VERSION_WS2008) {
+               newchannel->is_dedicated_interrupt =
+                               (offer->is_dedicated_interrupt != 0);
+               newchannel->sig_event->connectionid.u.id =
+                               offer->connection_id;
+       }
+
        memcpy(&newchannel->offermsg, offer,
               sizeof(struct vmbus_channel_offer_channel));
        newchannel->monitor_grp = (u8)offer->monitorid / 32;
index cd48ac331708a2d0846338dcf327f2ded4bd411a..1bc7500fb84c6a1fea3a635252940160bbc9223b 100644 (file)
@@ -101,15 +101,6 @@ enum hv_message_type {
 /* Define invalid partition identifier. */
 #define HV_PARTITION_ID_INVALID                ((u64)0x0)
 
-/* Define connection identifier type. */
-union hv_connection_id {
-       u32 asu32;
-       struct {
-               u32 id:24;
-               u32 reserved:8;
-       } u;
-};
-
 /* Define port identifier type. */
 union hv_port_id {
        u32 asu32;
@@ -338,13 +329,6 @@ struct hv_input_post_message {
        u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
 };
 
-/* Definition of the hv_signal_event hypercall input structure. */
-struct hv_input_signal_event {
-       union hv_connection_id connectionid;
-       u16 flag_number;
-       u16 rsvdz;
-};
-
 /*
  * Versioning definitions used for guests reporting themselves to the
  * hypervisor, and visa versa.
@@ -498,11 +482,6 @@ static const uuid_le VMBUS_SERVICE_ID = {
 
 
 
-struct hv_input_signal_event_buffer {
-       u64 align8;
-       struct hv_input_signal_event event;
-};
-
 struct hv_context {
        /* We only support running on top of Hyper-V
        * So at this point this really can only contain the Hyper-V ID
index e72502689cdcff3468757329ffff0666f6d0e81b..c6e2c44a1be9fab78d5aa85f5fbee08457c4d7e0 100644 (file)
@@ -897,6 +897,27 @@ struct vmbus_close_msg {
        struct vmbus_channel_close_channel msg;
 };
 
+/* Define connection identifier type. */
+union hv_connection_id {
+       u32 asu32;
+       struct {
+               u32 id:24;
+               u32 reserved:8;
+       } u;
+};
+
+/* Definition of the hv_signal_event hypercall input structure. */
+struct hv_input_signal_event {
+       union hv_connection_id connectionid;
+       u16 flag_number;
+       u16 rsvdz;
+};
+
+struct hv_input_signal_event_buffer {
+       u64 align8;
+       struct hv_input_signal_event event;
+};
+
 struct vmbus_channel {
        struct list_head listentry;
 
@@ -946,6 +967,10 @@ struct vmbus_channel {
         */
 
        bool batched_reading;
+
+       bool is_dedicated_interrupt;
+       struct hv_input_signal_event_buffer sig_buf;
+       struct hv_input_signal_event *sig_event;
 };
 
 static inline void set_channel_read_state(struct vmbus_channel *c, bool state)