Exemplo n.º 1
0
void unbind_all_ports(void)
{
    int i;
    int cpu = 0;
    shared_info_t *s = HYPERVISOR_shared_info;
    vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
    int rc;

    for ( i = 0; i < NR_EVS; i++ )
    {
        if ( i == start_info.console.domU.evtchn ||
             i == start_info.store_evtchn)
            continue;

        if ( test_and_clear_bit(i, bound_ports) )
        {
            struct evtchn_close close;
            printk("port %d still bound!\n", i);
            mask_evtchn(i);
            close.port = i;
            rc = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
            if ( rc )
                printk("WARN: close_port %s failed rc=%d. ignored\n", i, rc);
            clear_evtchn(i);
        }
    }
    vcpu_info->evtchn_upcall_pending = 0;
    vcpu_info->evtchn_pending_sel = 0;
}
Exemplo n.º 2
0
/* Set up event channel for xenstored which is run as a local process
 * (this is normally used only in dom0)
 */
static int __init xenstored_local_init(void)
{
	int err = 0;
	unsigned long page = 0;
	struct evtchn_alloc_unbound alloc_unbound;

	/* Allocate Xenstore page */
	page = get_zeroed_page(GFP_KERNEL);
	if (!page)
		goto out_err;

	xen_store_gfn = xen_start_info->store_mfn = virt_to_gfn((void *)page);

	/* Next allocate a local port which xenstored can bind to */
	alloc_unbound.dom        = DOMID_SELF;
	alloc_unbound.remote_dom = DOMID_SELF;

	err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
					  &alloc_unbound);
	if (err == -ENOSYS)
		goto out_err;

	BUG_ON(err);
	xen_store_evtchn = xen_start_info->store_evtchn =
		alloc_unbound.port;

	return 0;

 out_err:
	if (page != 0)
		free_page(page);
	return err;
}
Exemplo n.º 3
0
static int 
bind_virq_to_irq(unsigned int virq, unsigned int cpu)
{
	struct evtchn_bind_virq bind_virq;
	int evtchn = 0, irq;

	mtx_lock_spin(&irq_mapping_update_lock);

	if ((irq = pcpu_find(cpu)->pc_virq_to_irq[virq]) == -1) {
		if ((irq = find_unbound_irq()) < 0)
			goto out;

		bind_virq.virq = virq;
		bind_virq.vcpu = cpu;
		HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &bind_virq);

		evtchn = bind_virq.port;

		evtchn_to_irq[evtchn] = irq;
		irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);

		pcpu_find(cpu)->pc_virq_to_irq[virq] = irq;

		bind_evtchn_to_cpu(evtchn, cpu);
	}

	irq_bindcount[irq]++;
	unmask_evtchn(evtchn);
out:
	mtx_unlock_spin(&irq_mapping_update_lock);

	return irq;
}
Exemplo n.º 4
0
static int
bind_local_port_to_irq(unsigned int local_port)
{
        int irq;

        mtx_lock_spin(&irq_mapping_update_lock);

        KASSERT(evtchn_to_irq[local_port] == -1,
	    ("evtchn_to_irq inconsistent"));
	
        if ((irq = find_unbound_irq()) < 0) {
                struct evtchn_close close = { .port = local_port };
                HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
		
                goto out;
        }

        evtchn_to_irq[local_port] = irq;
        irq_info[irq] = mk_irq_info(IRQT_LOCAL_PORT, 0, local_port);
        irq_bindcount[irq]++;
	unmask_evtchn(local_port);

 out:
        mtx_unlock_spin(&irq_mapping_update_lock);
        return irq;
}
Exemplo n.º 5
0
int 
bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
{
	struct evtchn_bind_ipi bind_ipi;
	int irq;
	int evtchn = 0;

	mtx_lock_spin(&irq_mapping_update_lock);
	
	if ((irq = pcpu_find(cpu)->pc_ipi_to_irq[ipi]) == -1) {
		if ((irq = find_unbound_irq()) < 0)
			goto out;

		bind_ipi.vcpu = cpu;
		HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, &bind_ipi);
		evtchn = bind_ipi.port;

		evtchn_to_irq[evtchn] = irq;
		irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);

		pcpu_find(cpu)->pc_ipi_to_irq[ipi] = irq;

		bind_evtchn_to_cpu(evtchn, cpu);
	}
	irq_bindcount[irq]++;
	unmask_evtchn(evtchn);
out:
	
	mtx_unlock_spin(&irq_mapping_update_lock);

	return irq;
}
Exemplo n.º 6
0
static long evtchn_ioctl(struct file *file,
			 unsigned int cmd, unsigned long arg)
{
	int rc;
	struct per_user_data *u = file->private_data;
	void __user *uarg = (void __user *) arg;

	/* Prevent bind from racing with unbind */
	mutex_lock(&u->bind_mutex);

	switch (cmd) {
	case IOCTL_EVTCHN_BIND_VIRQ: {
		struct ioctl_evtchn_bind_virq bind;
		struct evtchn_bind_virq bind_virq;

		rc = -EFAULT;
		if (copy_from_user(&bind, uarg, sizeof(bind)))
			break;

		bind_virq.virq = bind.virq;
		bind_virq.vcpu = 0;
		rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
						 &bind_virq);
		if (rc != 0)
			break;

		rc = evtchn_bind_to_user(u, bind_v
Exemplo n.º 7
0
static void 
unbind_from_irq(int irq)
{
	struct evtchn_close close;
	int evtchn = evtchn_from_irq(irq);
	int cpu;

	mtx_lock_spin(&irq_mapping_update_lock);

	if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
		close.port = evtchn;
		HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);

		switch (type_from_irq(irq)) {
		case IRQT_VIRQ:
			cpu = cpu_from_evtchn(evtchn);
			pcpu_find(cpu)->pc_virq_to_irq[index_from_irq(irq)] = -1;
			break;
		case IRQT_IPI:
			cpu = cpu_from_evtchn(evtchn);
			pcpu_find(cpu)->pc_ipi_to_irq[index_from_irq(irq)] = -1;
			break;
		default:
			break;
		}

		/* Closed ports are implicitly re-bound to VCPU0. */
		bind_evtchn_to_cpu(evtchn, 0);

		evtchn_to_irq[evtchn] = -1;
		irq_info[irq] = IRQ_UNBOUND;
	}

	mtx_unlock_spin(&irq_mapping_update_lock);
}
Exemplo n.º 8
0
void unmask_evtchn(int port)
{
	shared_info_t *s = HYPERVISOR_shared_info;
	unsigned int cpu = smp_processor_id();
	vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];

	BUG_ON(!irqs_disabled());

	/* Slow path (hypercall) if this is a non-local port. */
	if (unlikely(cpu != cpu_from_evtchn(port))) {
		struct evtchn_unmask unmask = { .port = port };
		(void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
		return;
	}

	synch_clear_bit(port, &s->evtchn_mask[0]);

	/*
	 * The following is basically the equivalent of 'hw_resend_irq'. Just
	 * like a real IO-APIC we 'lose the interrupt edge' if the channel is
	 * masked.
	 */
	if (synch_test_bit(port, &s->evtchn_pending[0]) &&
	    !synch_test_and_set_bit(port / BITS_PER_LONG,
				    &vcpu_info->evtchn_pending_sel)) {
		vcpu_info->evtchn_upcall_pending = 1;
		if (!vcpu_info->evtchn_upcall_mask)
			force_evtchn_callback();
	}
}
Exemplo n.º 9
0
static unsigned int startup_pirq(unsigned int irq)
{
	struct evtchn_bind_pirq bind_pirq;
	int evtchn = evtchn_from_irq(irq);

	if (VALID_EVTCHN(evtchn))
		goto out;

	bind_pirq.pirq  = irq;
	/* NB. We are happy to share unless we are probing. */
	bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
	if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq) != 0) {
		if (!probing_irq(irq))
			printk(KERN_INFO "Failed to obtain physical IRQ %d\n",
			       irq);
		return 0;
	}
	evtchn = bind_pirq.port;

	pirq_query_unmask(irq_to_pirq(irq));

	evtchn_to_irq[evtchn] = irq;
	bind_evtchn_to_cpu(evtchn, 0);
	irq_info[irq] = mk_irq_info(IRQT_PIRQ, irq, evtchn);

 out:
	unmask_evtchn(evtchn);
	pirq_unmask_notify(irq_to_pirq(irq));

	return 0;
}
Exemplo n.º 10
0
static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
{
	struct evtchn_bind_ipi bind_ipi;
	int evtchn, irq;

	spin_lock(&irq_mapping_update_lock);

	if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) {
		if ((irq = find_unbound_irq()) < 0)
			goto out;

		bind_ipi.vcpu = cpu;
		if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
						&bind_ipi) != 0)
			BUG();
		evtchn = bind_ipi.port;

		evtchn_to_irq[evtchn] = irq;
		irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);

		per_cpu(ipi_to_irq, cpu)[ipi] = irq;

		bind_evtchn_to_cpu(evtchn, cpu);
	}

	irq_bindcount[irq]++;

 out:
	spin_unlock(&irq_mapping_update_lock);
	return irq;
}
Exemplo n.º 11
0
static int evtchn_bind_to_user(struct per_user_data *u, int port)
{
	int rc = 0;

	/*
	 * Ports are never reused, so every caller should pass in a
	 * unique port.
	 *
	 * (Locking not necessary because we haven't registered the
	 * interrupt handler yet, and our caller has already
	 * serialized bind operations.)
	 */
	BUG_ON(get_port_user(port) != NULL);
	set_port_user(port, u);
	set_port_enabled(port, true); /* start enabled */

	rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, IRQF_DISABLED,
				       u->name, (void *)(unsigned long)port);
	if (rc >= 0)
		rc = evtchn_make_refcounted(port);
	else {
		/* bind failed, should close the port now */
		struct evtchn_close close;
		close.port = port;
		if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
			BUG();
		set_port_user(port, NULL);
	}

	return rc;
}
Exemplo n.º 12
0
static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
{
	struct evtchn_bind_virq bind_virq;
	int evtchn, irq;

	spin_lock(&irq_mapping_update_lock);

	if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
		bind_virq.virq = virq;
		bind_virq.vcpu = cpu;
		if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
						&bind_virq) != 0)
			BUG();
		evtchn = bind_virq.port;

		irq = find_unbound_irq();
		evtchn_to_irq[evtchn] = irq;
		irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);

		per_cpu(virq_to_irq, cpu)[virq] = irq;

		bind_evtchn_to_cpu(evtchn, cpu);
	}

	irq_bindcount[irq]++;

	spin_unlock(&irq_mapping_update_lock);

	return irq;
}
Exemplo n.º 13
0
static void
xenevt_free(struct xenevt_d *d)
{
	int i;
	KASSERT(mutex_owned(&devevent_lock));
	KASSERT(mutex_owned(&d->lock));

	for (i = 0; i < NR_EVENT_CHANNELS; i++ ) {
		if (devevent[i] == d) {
			evtchn_op_t op = { .cmd = 0 };
			int error;

			hypervisor_mask_event(i);
			xen_atomic_clear_bit(&d->ci->ci_evtmask[0], i);
			devevent[i] = NULL;

			op.cmd = EVTCHNOP_close;
			op.u.close.port = i;
			if ((error = HYPERVISOR_event_channel_op(&op))) {
				printf("xenevt_fclose: error %d from "
				    "hypervisor\n", -error);
			}
		}
	}
	mutex_exit(&d->lock);
	seldestroy(&d->sel);
	cv_destroy(&d->cv);
	mutex_destroy(&d->lock);
	free(d, M_DEVBUF);
}
Exemplo n.º 14
0
static void unbind_from_irq(unsigned int irq)
{
	struct evtchn_close close;
	int evtchn = evtchn_from_irq(irq);

	spin_lock(&irq_mapping_update_lock);

	if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
		close.port = evtchn;
		if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
			BUG();

		switch (type_from_irq(irq)) {
		case IRQT_VIRQ:
			per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))
				[index_from_irq(irq)] = -1;
			break;
		case IRQT_IPI:
			per_cpu(ipi_to_irq, cpu_from_evtchn(evtchn))
				[index_from_irq(irq)] = -1;
			break;
		default:
			break;
		}

		/* Closed ports are implicitly re-bound to VCPU0. */
		bind_evtchn_to_cpu(evtchn, 0);

		evtchn_to_irq[evtchn] = -1;
		irq_info[irq] = IRQ_UNBOUND;
	}

	spin_unlock(&irq_mapping_update_lock);
}
Exemplo n.º 15
0
static int evtchn_release(struct inode *inode, struct file *filp)
{
	int i;
	struct per_user_data *u = filp->private_data;
	struct evtchn_close close;

	spin_lock_irq(&port_user_lock);

	free_page((unsigned long)u->ring);

	for (i = 0; i < NR_EVENT_CHANNELS; i++) {
		int ret;
		if (port_user[i] != u)
			continue;

		port_user[i] = NULL;
		mask_evtchn(i);
		rebind_evtchn_to_cpu(i, 0);

		close.port = i;
		ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
		BUG_ON(ret);
	}

	spin_unlock_irq(&port_user_lock);

	kfree(u);

	return 0;
}
Exemplo n.º 16
0
void rebind_evtchn_to_cpu(int port, unsigned int cpu)
{
	struct evtchn_bind_vcpu ebv = { .port = port, .vcpu = cpu };
	int masked;

	masked = test_and_set_evtchn_mask(port);
	if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &ebv) == 0)
		bind_evtchn_to_cpu(port, cpu);
	if (!masked)
		unmask_evtchn(port);
}
Exemplo n.º 17
0
static int bind_listening_port_to_irq(unsigned int remote_domain)
{
	struct evtchn_alloc_unbound alloc_unbound;
	int err;

	alloc_unbound.dom        = DOMID_SELF;
	alloc_unbound.remote_dom = remote_domain;

	err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
					  &alloc_unbound);

	return err ? : bind_local_port_to_irq(alloc_unbound.port);
}
Exemplo n.º 18
0
void unbind_evtchn(evtchn_port_t port)
{
    struct evtchn_close close;
    int rc;

    mask_evtchn(port);
    clear_evtchn(port);

    close.port = port;
    rc = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
    if ( rc )
        printk("WARN: close_port %s failed rc=%d. ignored\n", port, rc);
}
Exemplo n.º 19
0
/**
 * Free an existing event channel. Returns 0 on success or -errno on error.
 */
int xenbus_free_evtchn(struct xenbus_device *dev, int port)
{
	struct evtchn_close close;
	int err;

	close.port = port;

	err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
	if (err)
		xenbus_dev_error(dev, err, "freeing event channel %d", port);

	return err;
}
Exemplo n.º 20
0
int gnt_init(void)
{
	int mfn;
	int err;
	struct as_sring *sring;

	struct evtchn_alloc_unbound alloc_unbound;
	printk(KERN_INFO "gnt_init\n");

	page =  __get_free_pages(GFP_KERNEL, 0);
	if (page == 0) {
		printk(KERN_DEBUG "\nxen:DomU:could not get free page");
		return 0;
	}

	sring = (struct as_sring *)page;
	SHARED_RING_INIT(sring);
	FRONT_RING_INIT(&(info.ring), sring, PAGE_SIZE);
	mfn = virt_to_mfn(page);

	printk(KERN_INFO "grant foreign access\n");
	info.gref = gnttab_grant_foreign_access(DOM0_ID, mfn, 0);
	if (info.gref < 0) {
		printk(KERN_DEBUG "\nxen:could not grant foreign access");
		free_page((unsigned long)page);
		info.ring.sring = NULL;
		return 0;
	}
	printk(KERN_DEBUG "\n gref = %d", info.gref);
	alloc_unbound.dom = DOMID_SELF;
	alloc_unbound.remote_dom = DOM0_ID;
	err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &alloc_unbound);
	if (err) {
		printk(KERN_DEBUG "\nalloc unbound port failure");
		return err;
	}

	err = bind_evtchn_to_irqhandler(alloc_unbound.port, as_int, 0, "xen-eg", &info);
	if (err < 0) {
		printk(KERN_DEBUG "\nbind evtchn to irqhandler failure");
		return err;
	}

	info.irq = err;
	info.port = alloc_unbound.port;
	printk(KERN_DEBUG " interrupt = %d, local_port = %d", info.irq, info.port);
	printk("...\n...");
	create_procfs_entry();
	return 0;
}
Exemplo n.º 21
0
static int bind_interdomain_evtchn_to_irq(unsigned int remote_domain,
					  unsigned int remote_port)
{
	struct evtchn_bind_interdomain bind_interdomain;
	int err;

	bind_interdomain.remote_dom  = remote_domain;
	bind_interdomain.remote_port = remote_port;

	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
					  &bind_interdomain);

	return err ? : bind_local_port_to_irq(bind_interdomain.local_port);
}
Exemplo n.º 22
0
int evtchn_alloc_unbound(uint32_t pal, void *handler, void *data,
		evtchn_port_t *port) {
	int rc;
	evtchn_alloc_unbound_t op;
	op.dom = DOMID_SELF;
	op.remote_dom = pal;

	rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
	if (rc) {
		printk("ERROR: alloc_unbound failed with rc=%d", rc);
		return rc;
	}
	*port = bind_evtchn((uint32_t) op.port, handler, data);
	return rc;
}
Exemplo n.º 23
0
int
xenbus_free_evtchn(device_t dev, evtchn_port_t port)
{
	struct evtchn_close close;
	int err;

	close.port = port;

	err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
	if (err) {
		xenbus_dev_error(dev, -err, "freeing event channel %d", port);
		return (-err);
	}
	return (0);
}
Exemplo n.º 24
0
int xenbus_conn(domid_t remote_dom, unsigned long *grant_ref, evtchn_port_t *local_port)
{
	struct evtchn_alloc_unbound alloc_unbound;
	int rc, rc2;

	BUG_ON(atomic_read(&xenbus_xsd_state) != XENBUS_XSD_FOREIGN_INIT);
	BUG_ON(!is_initial_xendomain());

#if defined(CONFIG_PROC_FS) && defined(CONFIG_XEN_PRIVILEGED_GUEST)
	remove_xen_proc_entry("xsd_kva");
	remove_xen_proc_entry("xsd_port");
#endif

	rc = xb_free_port(xen_store_evtchn);
	if (rc != 0)
		goto fail0;

	alloc_unbound.dom = DOMID_SELF;
	alloc_unbound.remote_dom = remote_dom;
	rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
	                                 &alloc_unbound);
	if (rc != 0)
		goto fail0;
	*local_port = xen_store_evtchn = alloc_unbound.port;

	/* keep the old page (xen_store_mfn, xen_store_interface) */
	rc = gnttab_grant_foreign_access(remote_dom, xen_store_mfn,
	                                 GTF_permit_access);
	if (rc < 0)
		goto fail1;
	*grant_ref = rc;

	rc = xb_init_comms();
	if (rc != 0)
		goto fail1;

	return 0;

fail1:
	rc2 = xb_free_port(xen_store_evtchn);
	if (rc2 != 0)
		printk(KERN_WARNING
		       "XENBUS: Error freeing xenstore event channel: %d\n",
		       rc2);
fail0:
	xen_store_evtchn = -1;
	return rc;
}
Exemplo n.º 25
0
int evtchn_alloc_unbound(domid_t pal, evtchn_port_t *port)
{
    int rc;

    evtchn_alloc_unbound_t op;
    op.dom = DOMID_SELF;
    op.remote_dom = pal;
    rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
    if ( rc )
    {
        printk("ERROR: alloc_unbound failed with rc=%d", rc);
	return rc;
    }
    *port = op.port;
    return rc;
}
Exemplo n.º 26
0
int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
			    evtchn_port_t *local_port)
{
    int rc;
    evtchn_bind_interdomain_t op;
    op.remote_dom = pal;
    op.remote_port = remote_port;
    rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
    if ( rc )
    {
        printk("ERROR: bind_interdomain failed with rc=%d", rc);
		return rc;
    }
    *local_port = op.local_port;
    return rc;
}
Exemplo n.º 27
0
evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
{
	evtchn_bind_virq_t op;
    int rc;

	/* Try to bind the virq to a port */
	op.virq = virq;
	op.vcpu = smp_processor_id();

	if ( (rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &op)) != 0 )
	{
		printk("Failed to bind virtual IRQ %d with rc=%d\n", virq, rc);
		return -1;
    }
    bind_evtchn(op.port, handler, data);
	return op.port;
}
Exemplo n.º 28
0
/**
 * Allocate an event channel for the given xenbus_device, assigning the newly
 * created local port to *port.  Return 0 on success, or -errno on error.  On
 * error, the device will switch to XenbusStateClosing, and the error will be
 * saved in the store.
 */
int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
{
	struct evtchn_alloc_unbound alloc_unbound;
	int err;

	alloc_unbound.dom = DOMID_SELF;
	alloc_unbound.remote_dom = dev->otherend_id;

	err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
					  &alloc_unbound);
	if (err)
		xenbus_dev_fatal(dev, err, "allocating event channel");
	else
		*port = alloc_unbound.port;

	return err;
}
Exemplo n.º 29
0
void unmask_evtchn(int port)
{
	unsigned int cpu;
	shared_info_t *s = shared_info_area;
	vcpu_info_t *vcpu_info;

	cpu = get_cpu();
	vcpu_info = &s->vcpu_info[cpu];

	/* Slow path (hypercall) if this is a non-local port.  We only
	   ever bind event channels to vcpu 0 in HVM guests. */
	if (unlikely(cpu != 0)) {
		evtchn_unmask_t op = { .port = port };
		(void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask,
						  &op);
		put_cpu();
		return;
	}
Exemplo n.º 30
0
evtchn_port_t bind_pirq(uint32_t pirq, int will_share,
                        evtchn_handler_t handler, void *data)
{
	evtchn_bind_pirq_t op;
    int rc;

	/* Try to bind the pirq to a port */
	op.pirq = pirq;
	op.flags = will_share ? BIND_PIRQ__WILL_SHARE : 0;

	if ( (rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &op)) != 0 )
	{
		printk("Failed to bind physical IRQ %d with rc=%d\n", pirq, rc);
		return -1;
	}
	bind_evtchn(op.port, handler, data);
	return op.port;
}