summaryrefslogtreecommitdiff
path: root/drivers/hv/connection.c
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2012-12-01 14:46:49 (GMT)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-17 19:39:15 (GMT)
commit6552ecd70cc6f31f4bb9d63f36a7dd023db3e519 (patch)
treec049853ac72d2720afcac4f896752657499a7aac /drivers/hv/connection.c
parentabbf3b2aa090b4a6bf22c935924b6467990266da (diff)
downloadlinux-fsl-qoriq-6552ecd70cc6f31f4bb9d63f36a7dd023db3e519.tar.xz
Drivers: hv: Modify the interrupt handling code to support win8 and beyond
Starting with Win8 (WS2012), the event page can be used to directly get the channel ID that needs servicing. Modify the channel event handling code to take advantage of this feature. 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>
Diffstat (limited to 'drivers/hv/connection.c')
-rw-r--r--drivers/hv/connection.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 114050d..ac71653 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -321,10 +321,32 @@ static void process_chn_event(u32 relid)
void vmbus_on_event(unsigned long data)
{
u32 dword;
- u32 maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5;
+ u32 maxdword;
int bit;
u32 relid;
- u32 *recv_int_page = vmbus_connection.recv_int_page;
+ u32 *recv_int_page = NULL;
+ void *page_addr;
+ int cpu = smp_processor_id();
+ union hv_synic_event_flags *event;
+
+ if ((vmbus_proto_version == VERSION_WS2008) ||
+ (vmbus_proto_version == VERSION_WIN7)) {
+ maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5;
+ recv_int_page = vmbus_connection.recv_int_page;
+ } else {
+ /*
+ * When the host is win8 and beyond, the event page
+ * can be directly checked to get the id of the channel
+ * that has the interrupt pending.
+ */
+ maxdword = HV_EVENT_FLAGS_DWORD_COUNT;
+ page_addr = hv_context.synic_event_page[cpu];
+ event = (union hv_synic_event_flags *)page_addr +
+ VMBUS_MESSAGE_SINT;
+ recv_int_page = event->flags32;
+ }
+
+
/* Check events */
if (!recv_int_page)