Commit f2fa0e5e authored by Juergen Gross's avatar Juergen Gross Committed by David S. Miller
Browse files

xen/events: link interdomain events to associated xenbus device



In order to support the possibility of per-device event channel
settings (e.g. lateeoi spurious event thresholds) add a xenbus device
pointer to struct irq_info() and modify the related event channel
binding interfaces to take the pointer to the xenbus device as a
parameter instead of the domain id of the other side.

While at it remove the stale prototype of bind_evtchn_to_irq_lateeoi().

Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
Reviewed-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
Reviewed-by: default avatarWei Liu <wei.liu@kernel.org>
Reviewed-by: default avatarPaul Durrant <paul@xen.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a3daf3d3
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -245,7 +245,7 @@ static int xen_blkif_map(struct xen_blkif_ring *ring, grant_ref_t *gref,
	if (req_prod - rsp_prod > size)
		goto fail;

	err = bind_interdomain_evtchn_to_irqhandler_lateeoi(blkif->domid,
	err = bind_interdomain_evtchn_to_irqhandler_lateeoi(blkif->be->dev,
			evtchn, xen_blkif_be_int, 0, "blkif-backend", ring);
	if (err < 0)
		goto fail;
+8 −8
Original line number Diff line number Diff line
@@ -630,13 +630,13 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t ring_ref,
			unsigned int evtchn)
{
	struct net_device *dev = vif->dev;
	struct xenbus_device *xendev = xenvif_to_xenbus_device(vif);
	void *addr;
	struct xen_netif_ctrl_sring *shared;
	RING_IDX rsp_prod, req_prod;
	int err;

	err = xenbus_map_ring_valloc(xenvif_to_xenbus_device(vif),
				     &ring_ref, 1, &addr);
	err = xenbus_map_ring_valloc(xendev, &ring_ref, 1, &addr);
	if (err)
		goto err;

@@ -650,7 +650,7 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t ring_ref,
	if (req_prod - rsp_prod > RING_SIZE(&vif->ctrl))
		goto err_unmap;

	err = bind_interdomain_evtchn_to_irq_lateeoi(vif->domid, evtchn);
	err = bind_interdomain_evtchn_to_irq_lateeoi(xendev, evtchn);
	if (err < 0)
		goto err_unmap;

@@ -673,8 +673,7 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t ring_ref,
	vif->ctrl_irq = 0;

err_unmap:
	xenbus_unmap_ring_vfree(xenvif_to_xenbus_device(vif),
				vif->ctrl.sring);
	xenbus_unmap_ring_vfree(xendev, vif->ctrl.sring);
	vif->ctrl.sring = NULL;

err:
@@ -719,6 +718,7 @@ int xenvif_connect_data(struct xenvif_queue *queue,
			unsigned int tx_evtchn,
			unsigned int rx_evtchn)
{
	struct xenbus_device *dev = xenvif_to_xenbus_device(queue->vif);
	struct task_struct *task;
	int err;

@@ -755,7 +755,7 @@ int xenvif_connect_data(struct xenvif_queue *queue,
	if (tx_evtchn == rx_evtchn) {
		/* feature-split-event-channels == 0 */
		err = bind_interdomain_evtchn_to_irqhandler_lateeoi(
			queue->vif->domid, tx_evtchn, xenvif_interrupt, 0,
			dev, tx_evtchn, xenvif_interrupt, 0,
			queue->name, queue);
		if (err < 0)
			goto err;
@@ -766,7 +766,7 @@ int xenvif_connect_data(struct xenvif_queue *queue,
		snprintf(queue->tx_irq_name, sizeof(queue->tx_irq_name),
			 "%s-tx", queue->name);
		err = bind_interdomain_evtchn_to_irqhandler_lateeoi(
			queue->vif->domid, tx_evtchn, xenvif_tx_interrupt, 0,
			dev, tx_evtchn, xenvif_tx_interrupt, 0,
			queue->tx_irq_name, queue);
		if (err < 0)
			goto err;
@@ -776,7 +776,7 @@ int xenvif_connect_data(struct xenvif_queue *queue,
		snprintf(queue->rx_irq_name, sizeof(queue->rx_irq_name),
			 "%s-rx", queue->name);
		err = bind_interdomain_evtchn_to_irqhandler_lateeoi(
			queue->vif->domid, rx_evtchn, xenvif_rx_interrupt, 0,
			dev, rx_evtchn, xenvif_rx_interrupt, 0,
			queue->rx_irq_name, queue);
		if (err < 0)
			goto err;
+24 −17
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@
#include <xen/interface/physdev.h>
#include <xen/interface/sched.h>
#include <xen/interface/vcpu.h>
#include <xen/xenbus.h>
#include <asm/hw_irq.h>

#include "events_internal.h"
@@ -115,6 +116,7 @@ struct irq_info {
			unsigned char flags;
			uint16_t domid;
		} pirq;
		struct xenbus_device *interdomain;
	} u;
};

@@ -313,11 +315,16 @@ static int xen_irq_info_common_setup(struct irq_info *info,
}

static int xen_irq_info_evtchn_setup(unsigned irq,
				     evtchn_port_t evtchn)
				     evtchn_port_t evtchn,
				     struct xenbus_device *dev)
{
	struct irq_info *info = info_for_irq(irq);
	int ret;

	return xen_irq_info_common_setup(info, irq, IRQT_EVTCHN, evtchn, 0);
	ret = xen_irq_info_common_setup(info, irq, IRQT_EVTCHN, evtchn, 0);
	info->u.interdomain = dev;

	return ret;
}

static int xen_irq_info_ipi_setup(unsigned cpu,
@@ -1116,7 +1123,8 @@ int xen_pirq_from_irq(unsigned irq)
}
EXPORT_SYMBOL_GPL(xen_pirq_from_irq);

static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip)
static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip,
				   struct xenbus_device *dev)
{
	int irq;
	int ret;
@@ -1136,7 +1144,7 @@ static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip)
		irq_set_chip_and_handler_name(irq, chip,
					      handle_edge_irq, "event");

		ret = xen_irq_info_evtchn_setup(irq, evtchn);
		ret = xen_irq_info_evtchn_setup(irq, evtchn, dev);
		if (ret < 0) {
			__unbind_from_irq(irq);
			irq = ret;
@@ -1163,7 +1171,7 @@ static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip)

int bind_evtchn_to_irq(evtchn_port_t evtchn)
{
	return bind_evtchn_to_irq_chip(evtchn, &xen_dynamic_chip);
	return bind_evtchn_to_irq_chip(evtchn, &xen_dynamic_chip, NULL);
}
EXPORT_SYMBOL_GPL(bind_evtchn_to_irq);

@@ -1212,27 +1220,27 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
	return irq;
}

static int bind_interdomain_evtchn_to_irq_chip(unsigned int remote_domain,
static int bind_interdomain_evtchn_to_irq_chip(struct xenbus_device *dev,
					       evtchn_port_t remote_port,
					       struct irq_chip *chip)
{
	struct evtchn_bind_interdomain bind_interdomain;
	int err;

	bind_interdomain.remote_dom  = remote_domain;
	bind_interdomain.remote_dom  = dev->otherend_id;
	bind_interdomain.remote_port = remote_port;

	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
					  &bind_interdomain);

	return err ? : bind_evtchn_to_irq_chip(bind_interdomain.local_port,
					       chip);
					       chip, dev);
}

int bind_interdomain_evtchn_to_irq_lateeoi(unsigned int remote_domain,
int bind_interdomain_evtchn_to_irq_lateeoi(struct xenbus_device *dev,
					   evtchn_port_t remote_port)
{
	return bind_interdomain_evtchn_to_irq_chip(remote_domain, remote_port,
	return bind_interdomain_evtchn_to_irq_chip(dev, remote_port,
						   &xen_lateeoi_chip);
}
EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irq_lateeoi);
@@ -1345,7 +1353,7 @@ static int bind_evtchn_to_irqhandler_chip(evtchn_port_t evtchn,
{
	int irq, retval;

	irq = bind_evtchn_to_irq_chip(evtchn, chip);
	irq = bind_evtchn_to_irq_chip(evtchn, chip, NULL);
	if (irq < 0)
		return irq;
	retval = request_irq(irq, handler, irqflags, devname, dev_id);
@@ -1380,14 +1388,13 @@ int bind_evtchn_to_irqhandler_lateeoi(evtchn_port_t evtchn,
EXPORT_SYMBOL_GPL(bind_evtchn_to_irqhandler_lateeoi);

static int bind_interdomain_evtchn_to_irqhandler_chip(
		unsigned int remote_domain, evtchn_port_t remote_port,
		struct xenbus_device *dev, evtchn_port_t remote_port,
		irq_handler_t handler, unsigned long irqflags,
		const char *devname, void *dev_id, struct irq_chip *chip)
{
	int irq, retval;

	irq = bind_interdomain_evtchn_to_irq_chip(remote_domain, remote_port,
						  chip);
	irq = bind_interdomain_evtchn_to_irq_chip(dev, remote_port, chip);
	if (irq < 0)
		return irq;

@@ -1400,14 +1407,14 @@ static int bind_interdomain_evtchn_to_irqhandler_chip(
	return irq;
}

int bind_interdomain_evtchn_to_irqhandler_lateeoi(unsigned int remote_domain,
int bind_interdomain_evtchn_to_irqhandler_lateeoi(struct xenbus_device *dev,
						  evtchn_port_t remote_port,
						  irq_handler_t handler,
						  unsigned long irqflags,
						  const char *devname,
						  void *dev_id)
{
	return bind_interdomain_evtchn_to_irqhandler_chip(remote_domain,
	return bind_interdomain_evtchn_to_irqhandler_chip(dev,
				remote_port, handler, irqflags, devname,
				dev_id, &xen_lateeoi_chip);
}
@@ -1679,7 +1686,7 @@ void rebind_evtchn_irq(evtchn_port_t evtchn, int irq)
	   so there should be a proper type */
	BUG_ON(info->type == IRQT_UNBOUND);

	(void)xen_irq_info_evtchn_setup(irq, evtchn);
	(void)xen_irq_info_evtchn_setup(irq, evtchn, NULL);

	mutex_unlock(&irq_mapping_update_lock);

+2 −2
Original line number Diff line number Diff line
@@ -348,7 +348,7 @@ static struct sock_mapping *pvcalls_new_active_socket(
	map->bytes = page;

	ret = bind_interdomain_evtchn_to_irqhandler_lateeoi(
			fedata->dev->otherend_id, evtchn,
			fedata->dev, evtchn,
			pvcalls_back_conn_event, 0, "pvcalls-backend", map);
	if (ret < 0)
		goto out;
@@ -948,7 +948,7 @@ static int backend_connect(struct xenbus_device *dev)
		goto error;
	}

	err = bind_interdomain_evtchn_to_irq_lateeoi(dev->otherend_id, evtchn);
	err = bind_interdomain_evtchn_to_irq_lateeoi(dev, evtchn);
	if (err < 0)
		goto error;
	fedata->irq = err;
+1 −1
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ static int xen_pcibk_do_attach(struct xen_pcibk_device *pdev, int gnt_ref,
	pdev->sh_info = vaddr;

	err = bind_interdomain_evtchn_to_irqhandler_lateeoi(
		pdev->xdev->otherend_id, remote_evtchn, xen_pcibk_handle_event,
		pdev->xdev, remote_evtchn, xen_pcibk_handle_event,
		0, DRV_NAME, pdev);
	if (err < 0) {
		xenbus_dev_fatal(pdev->xdev, err,
Loading