/* VmbusOnMsgDPC - DPC routine to handle messages from the hypervisior  */
static void VmbusOnMsgDPC(struct hv_driver *drv)
/* VmbusOnMsgDPC - DPC routine to handle messages from the hypervisior  */
static void VmbusOnMsgDPC(struct hv_driver *drv)
{
	int cpu = smp_processor_id();
	void *page_addr = gHvContext.synICMessagePage[cpu];
	struct hv_message *msg = (struct hv_message *)page_addr +
				  VMBUS_MESSAGE_SINT;
	struct hv_message *copied;
	while (1) {
		if (msg->Header.MessageType == HvMessageTypeNone) {
			break;
		} else {
			copied = kmalloc(sizeof(*copied), GFP_ATOMIC);
			if (copied == NULL)
				continue;
			memcpy(copied, msg, sizeof(*copied));
			osd_schedule_callback(gVmbusConnection.WorkQueue,
					      VmbusOnChannelMessage,
					      (void *)copied);
		}
		msg->Header.MessageType = HvMessageTypeNone;
		mb();
		if (msg->Header.MessageFlags.MessagePending) {
			wrmsrl(HV_X64_MSR_EOM, 0);
		}
	}
}