Example #1
0
File: mem_event.c Project: CPFL/xen
/* Registered with Xen-bound event channel for incoming notifications. */
static void mem_access_notification(struct vcpu *v, unsigned int port)
{
    if ( likely(v->domain->mem_event->access.ring_page != NULL) )
        mem_access_resume(v->domain);
}
Example #2
0
/*
 * Pull all responses from the given ring and unpause the corresponding vCPU
 * if required. Based on the response type, here we can also call custom
 * handlers.
 *
 * Note: responses are handled the same way regardless of which ring they
 * arrive on.
 */
void vm_event_resume(struct domain *d, struct vm_event_domain *ved)
{
    vm_event_response_t rsp;

    /* Pull all responses off the ring. */
    while ( vm_event_get_response(d, ved, &rsp) )
    {
        struct vcpu *v;

        if ( rsp.version != VM_EVENT_INTERFACE_VERSION )
        {
            printk(XENLOG_G_WARNING "vm_event interface version mismatch\n");
            continue;
        }

        /* Validate the vcpu_id in the response. */
        if ( (rsp.vcpu_id >= d->max_vcpus) || !d->vcpu[rsp.vcpu_id] )
            continue;

        v = d->vcpu[rsp.vcpu_id];

        /*
         * In some cases the response type needs extra handling, so here
         * we call the appropriate handlers.
         */
        switch ( rsp.reason )
        {
        case VM_EVENT_REASON_MOV_TO_MSR:
        case VM_EVENT_REASON_WRITE_CTRLREG:
            vm_event_register_write_resume(v, &rsp);
            break;

#ifdef CONFIG_HAS_MEM_ACCESS
        case VM_EVENT_REASON_MEM_ACCESS:
            mem_access_resume(v, &rsp);
            break;
#endif

#ifdef CONFIG_HAS_MEM_PAGING
        case VM_EVENT_REASON_MEM_PAGING:
            p2m_mem_paging_resume(d, &rsp);
            break;
#endif

        };

        /* Check for altp2m switch */
        if ( rsp.flags & VM_EVENT_FLAG_ALTERNATE_P2M )
            p2m_altp2m_check(v, rsp.altp2m_idx);

        if ( rsp.flags & VM_EVENT_FLAG_VCPU_PAUSED )
        {
            if ( rsp.flags & VM_EVENT_FLAG_SET_REGISTERS )
                vm_event_set_registers(v, &rsp);

            if ( rsp.flags & VM_EVENT_FLAG_TOGGLE_SINGLESTEP )
                vm_event_toggle_singlestep(d, v);

            vm_event_vcpu_unpause(v);
        }
    }
}