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: Juergen Gross <jgross@suse.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Reviewed-by: Wei Liu <wei.liu@kernel.org> Reviewed-by: Paul Durrant <paul@xen.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a3daf3d391
commit
f2fa0e5e9f
|
@ -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;
|
||||
|
|
|
@ -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 @@ err_deinit:
|
|||
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;
|
||||
|
|
|
@ -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 @@ out:
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -799,7 +799,7 @@ static int scsiback_init_sring(struct vscsibk_info *info, grant_ref_t ring_ref,
|
|||
sring = (struct vscsiif_sring *)area;
|
||||
BACK_RING_INIT(&info->ring, sring, PAGE_SIZE);
|
||||
|
||||
err = bind_interdomain_evtchn_to_irq_lateeoi(info->domid, evtchn);
|
||||
err = bind_interdomain_evtchn_to_irq_lateeoi(info->dev, evtchn);
|
||||
if (err < 0)
|
||||
goto unmap_page;
|
||||
|
||||
|
|
|
@ -12,10 +12,11 @@
|
|||
#include <asm/xen/hypercall.h>
|
||||
#include <asm/xen/events.h>
|
||||
|
||||
struct xenbus_device;
|
||||
|
||||
unsigned xen_evtchn_nr_channels(void);
|
||||
|
||||
int bind_evtchn_to_irq(evtchn_port_t evtchn);
|
||||
int bind_evtchn_to_irq_lateeoi(evtchn_port_t evtchn);
|
||||
int bind_evtchn_to_irqhandler(evtchn_port_t evtchn,
|
||||
irq_handler_t handler,
|
||||
unsigned long irqflags, const char *devname,
|
||||
|
@ -35,9 +36,9 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi,
|
|||
unsigned long irqflags,
|
||||
const char *devname,
|
||||
void *dev_id);
|
||||
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);
|
||||
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,
|
||||
|
|
Loading…
Reference in New Issue