Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 354992
b: refs/heads/master
c: 6552ecd
h: refs/heads/master
v: v3
  • Loading branch information
K. Y. Srinivasan authored and Greg Kroah-Hartman committed Jan 17, 2013
1 parent eb23bc0 commit f14ea31
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: abbf3b2aa090b4a6bf22c935924b6467990266da
refs/heads/master: 6552ecd70cc6f31f4bb9d63f36a7dd023db3e519
26 changes: 24 additions & 2 deletions trunk/drivers/hv/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
27 changes: 22 additions & 5 deletions trunk/drivers/hv/vmbus_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,15 +460,32 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id)
* Hyper-V, and the Windows team suggested we do the same.
*/

page_addr = hv_context.synic_event_page[cpu];
event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
if ((vmbus_proto_version == VERSION_WS2008) ||
(vmbus_proto_version == VERSION_WIN7)) {

/* Since we are a child, we only need to check bit 0 */
if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) {
page_addr = hv_context.synic_event_page[cpu];
event = (union hv_synic_event_flags *)page_addr +
VMBUS_MESSAGE_SINT;

/* Since we are a child, we only need to check bit 0 */
if (sync_test_and_clear_bit(0,
(unsigned long *) &event->flags32[0])) {
handled = true;
}
} else {
/*
* Our host is win8 or above. The signaling mechanism
* has changed and we can directly look at the event page.
* If bit n is set then we have an interrup on the channel
* whose id is n.
*/
handled = true;
tasklet_schedule(&event_dpc);
}

if (handled)
tasklet_schedule(&event_dpc);


page_addr = hv_context.synic_message_page[cpu];
msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;

Expand Down

0 comments on commit f14ea31

Please sign in to comment.