Exemplo n.º 1
0
Arquivo: mem_event.c Projeto: CPFL/xen
static int mem_event_disable(struct domain *d, struct mem_event_domain *med)
{
    if ( med->ring_page )
    {
        struct vcpu *v;

        mem_event_ring_lock(med);

        if ( !list_empty(&med->wq.list) )
        {
            mem_event_ring_unlock(med);
            return -EBUSY;
        }

        /* Free domU's event channel and leave the other one unbound */
        free_xen_event_channel(d, med->xen_port);

        /* Unblock all vCPUs */
        for_each_vcpu ( d, v )
        {
            if ( test_and_clear_bit(med->pause_flag, &v->pause_flags) )
            {
                vcpu_unpause(v);
                med->blocked--;
            }
        }

        destroy_ring_for_helper(&med->ring_page,
                                med->ring_pg_struct);
        mem_event_ring_unlock(med);
    }

    return 0;
}
Exemplo n.º 2
0
Arquivo: vpl011.c Projeto: fdario/xen
void domain_vpl011_deinit(struct domain *d)
{
    struct vpl011 *vpl011 = &d->arch.vpl011;

    if ( !vpl011->ring_buf )
        return;

    free_xen_event_channel(d, vpl011->evtchn);
    destroy_ring_for_helper(&vpl011->ring_buf, vpl011->ring_page);
}
Exemplo n.º 3
0
Arquivo: vpl011.c Projeto: fdario/xen
int domain_vpl011_init(struct domain *d, struct vpl011_init_info *info)
{
    int rc;
    struct vpl011 *vpl011 = &d->arch.vpl011;

    if ( vpl011->ring_buf )
        return -EINVAL;

    /* Map the guest PFN to Xen address space. */
    rc =  prepare_ring_for_helper(d,
                                  gfn_x(info->gfn),
                                  &vpl011->ring_page,
                                  &vpl011->ring_buf);
    if ( rc < 0 )
        goto out;

    rc = vgic_reserve_virq(d, GUEST_VPL011_SPI);
    if ( !rc )
    {
        rc = -EINVAL;
        goto out1;
    }

    rc = alloc_unbound_xen_event_channel(d, 0, info->console_domid,
                                         vpl011_notification);
    if ( rc < 0 )
        goto out2;

    vpl011->evtchn = info->evtchn = rc;

    spin_lock_init(&vpl011->lock);

    register_mmio_handler(d, &vpl011_mmio_handler,
                          GUEST_PL011_BASE, GUEST_PL011_SIZE, NULL);

    return 0;

out2:
    vgic_free_virq(d, GUEST_VPL011_SPI);

out1:
    destroy_ring_for_helper(&vpl011->ring_buf, vpl011->ring_page);

out:
    return rc;
}
Exemplo n.º 4
0
Arquivo: mem_event.c Projeto: CPFL/xen
static int mem_event_enable(
    struct domain *d,
    xen_domctl_mem_event_op_t *mec,
    struct mem_event_domain *med,
    int pause_flag,
    int param,
    xen_event_channel_notification_t notification_fn)
{
    int rc;
    unsigned long ring_gfn = d->arch.hvm_domain.params[param];

    /* Only one helper at a time. If the helper crashed,
     * the ring is in an undefined state and so is the guest.
     */
    if ( med->ring_page )
        return -EBUSY;

    /* The parameter defaults to zero, and it should be
     * set to something */
    if ( ring_gfn == 0 )
        return -ENOSYS;

    mem_event_ring_lock_init(med);
    mem_event_ring_lock(med);

    rc = prepare_ring_for_helper(d, ring_gfn, &med->ring_pg_struct,
                                    &med->ring_page);
    if ( rc < 0 )
        goto err;

    /* Set the number of currently blocked vCPUs to 0. */
    med->blocked = 0;

    /* Allocate event channel */
    rc = alloc_unbound_xen_event_channel(d, 0, current->domain->domain_id,
                                         notification_fn);
    if ( rc < 0 )
        goto err;

    med->xen_port = mec->port = rc;

    /* Prepare ring buffer */
    FRONT_RING_INIT(&med->front_ring,
                    (mem_event_sring_t *)med->ring_page,
                    PAGE_SIZE);

    /* Save the pause flag for this particular ring. */
    med->pause_flag = pause_flag;

    /* Initialize the last-chance wait queue. */
    init_waitqueue_head(&med->wq);

    mem_event_ring_unlock(med);
    return 0;

 err:
    destroy_ring_for_helper(&med->ring_page,
                            med->ring_pg_struct);
    mem_event_ring_unlock(med);

    return rc;
}