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

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
...@@ -245,7 +245,7 @@ static int xen_blkif_map(struct xen_blkif_ring *ring, grant_ref_t *gref, ...@@ -245,7 +245,7 @@ static int xen_blkif_map(struct xen_blkif_ring *ring, grant_ref_t *gref,
if (req_prod - rsp_prod > size) if (req_prod - rsp_prod > size)
goto fail; 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); evtchn, xen_blkif_be_int, 0, "blkif-backend", ring);
if (err < 0) if (err < 0)
goto fail; goto fail;
......
...@@ -630,13 +630,13 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t ring_ref, ...@@ -630,13 +630,13 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t ring_ref,
unsigned int evtchn) unsigned int evtchn)
{ {
struct net_device *dev = vif->dev; struct net_device *dev = vif->dev;
struct xenbus_device *xendev = xenvif_to_xenbus_device(vif);
void *addr; void *addr;
struct xen_netif_ctrl_sring *shared; struct xen_netif_ctrl_sring *shared;
RING_IDX rsp_prod, req_prod; RING_IDX rsp_prod, req_prod;
int err; int err;
err = xenbus_map_ring_valloc(xenvif_to_xenbus_device(vif), err = xenbus_map_ring_valloc(xendev, &ring_ref, 1, &addr);
&ring_ref, 1, &addr);
if (err) if (err)
goto err; goto err;
...@@ -650,7 +650,7 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t ring_ref, ...@@ -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)) if (req_prod - rsp_prod > RING_SIZE(&vif->ctrl))
goto err_unmap; 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) if (err < 0)
goto err_unmap; goto err_unmap;
...@@ -673,8 +673,7 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t ring_ref, ...@@ -673,8 +673,7 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t ring_ref,
vif->ctrl_irq = 0; vif->ctrl_irq = 0;
err_unmap: err_unmap:
xenbus_unmap_ring_vfree(xenvif_to_xenbus_device(vif), xenbus_unmap_ring_vfree(xendev, vif->ctrl.sring);
vif->ctrl.sring);
vif->ctrl.sring = NULL; vif->ctrl.sring = NULL;
err: err:
...@@ -719,6 +718,7 @@ int xenvif_connect_data(struct xenvif_queue *queue, ...@@ -719,6 +718,7 @@ int xenvif_connect_data(struct xenvif_queue *queue,
unsigned int tx_evtchn, unsigned int tx_evtchn,
unsigned int rx_evtchn) unsigned int rx_evtchn)
{ {
struct xenbus_device *dev = xenvif_to_xenbus_device(queue->vif);
struct task_struct *task; struct task_struct *task;
int err; int err;
...@@ -755,7 +755,7 @@ int xenvif_connect_data(struct xenvif_queue *queue, ...@@ -755,7 +755,7 @@ int xenvif_connect_data(struct xenvif_queue *queue,
if (tx_evtchn == rx_evtchn) { if (tx_evtchn == rx_evtchn) {
/* feature-split-event-channels == 0 */ /* feature-split-event-channels == 0 */
err = bind_interdomain_evtchn_to_irqhandler_lateeoi( err = bind_interdomain_evtchn_to_irqhandler_lateeoi(
queue->vif->domid, tx_evtchn, xenvif_interrupt, 0, dev, tx_evtchn, xenvif_interrupt, 0,
queue->name, queue); queue->name, queue);
if (err < 0) if (err < 0)
goto err; goto err;
...@@ -766,7 +766,7 @@ int xenvif_connect_data(struct xenvif_queue *queue, ...@@ -766,7 +766,7 @@ int xenvif_connect_data(struct xenvif_queue *queue,
snprintf(queue->tx_irq_name, sizeof(queue->tx_irq_name), snprintf(queue->tx_irq_name, sizeof(queue->tx_irq_name),
"%s-tx", queue->name); "%s-tx", queue->name);
err = bind_interdomain_evtchn_to_irqhandler_lateeoi( 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); queue->tx_irq_name, queue);
if (err < 0) if (err < 0)
goto err; goto err;
...@@ -776,7 +776,7 @@ int xenvif_connect_data(struct xenvif_queue *queue, ...@@ -776,7 +776,7 @@ int xenvif_connect_data(struct xenvif_queue *queue,
snprintf(queue->rx_irq_name, sizeof(queue->rx_irq_name), snprintf(queue->rx_irq_name, sizeof(queue->rx_irq_name),
"%s-rx", queue->name); "%s-rx", queue->name);
err = bind_interdomain_evtchn_to_irqhandler_lateeoi( 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); queue->rx_irq_name, queue);
if (err < 0) if (err < 0)
goto err; goto err;
......
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
#include <xen/interface/physdev.h> #include <xen/interface/physdev.h>
#include <xen/interface/sched.h> #include <xen/interface/sched.h>
#include <xen/interface/vcpu.h> #include <xen/interface/vcpu.h>
#include <xen/xenbus.h>
#include <asm/hw_irq.h> #include <asm/hw_irq.h>
#include "events_internal.h" #include "events_internal.h"
...@@ -115,6 +116,7 @@ struct irq_info { ...@@ -115,6 +116,7 @@ struct irq_info {
unsigned char flags; unsigned char flags;
uint16_t domid; uint16_t domid;
} pirq; } pirq;
struct xenbus_device *interdomain;
} u; } u;
}; };
...@@ -313,11 +315,16 @@ static int xen_irq_info_common_setup(struct irq_info *info, ...@@ -313,11 +315,16 @@ static int xen_irq_info_common_setup(struct irq_info *info,
} }
static int xen_irq_info_evtchn_setup(unsigned irq, 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); 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, static int xen_irq_info_ipi_setup(unsigned cpu,
...@@ -1116,7 +1123,8 @@ int xen_pirq_from_irq(unsigned irq) ...@@ -1116,7 +1123,8 @@ int xen_pirq_from_irq(unsigned irq)
} }
EXPORT_SYMBOL_GPL(xen_pirq_from_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 irq;
int ret; int ret;
...@@ -1136,7 +1144,7 @@ static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip) ...@@ -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, irq_set_chip_and_handler_name(irq, chip,
handle_edge_irq, "event"); handle_edge_irq, "event");
ret = xen_irq_info_evtchn_setup(irq, evtchn); ret = xen_irq_info_evtchn_setup(irq, evtchn, dev);
if (ret < 0) { if (ret < 0) {
__unbind_from_irq(irq); __unbind_from_irq(irq);
irq = ret; irq = ret;
...@@ -1163,7 +1171,7 @@ static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip) ...@@ -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) 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); EXPORT_SYMBOL_GPL(bind_evtchn_to_irq);
...@@ -1212,27 +1220,27 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) ...@@ -1212,27 +1220,27 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
return irq; 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, evtchn_port_t remote_port,
struct irq_chip *chip) struct irq_chip *chip)
{ {
struct evtchn_bind_interdomain bind_interdomain; struct evtchn_bind_interdomain bind_interdomain;
int err; int err;
bind_interdomain.remote_dom = remote_domain; bind_interdomain.remote_dom = dev->otherend_id;
bind_interdomain.remote_port = remote_port; bind_interdomain.remote_port = remote_port;
err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
&bind_interdomain); &bind_interdomain);
return err ? : bind_evtchn_to_irq_chip(bind_interdomain.local_port, 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) 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); &xen_lateeoi_chip);
} }
EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irq_lateeoi); EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irq_lateeoi);
...@@ -1345,7 +1353,7 @@ static int bind_evtchn_to_irqhandler_chip(evtchn_port_t evtchn, ...@@ -1345,7 +1353,7 @@ static int bind_evtchn_to_irqhandler_chip(evtchn_port_t evtchn,
{ {
int irq, retval; int irq, retval;
irq = bind_evtchn_to_irq_chip(evtchn, chip); irq = bind_evtchn_to_irq_chip(evtchn, chip, NULL);
if (irq < 0) if (irq < 0)
return irq; return irq;
retval = request_irq(irq, handler, irqflags, devname, dev_id); retval = request_irq(irq, handler, irqflags, devname, dev_id);
...@@ -1380,14 +1388,13 @@ int bind_evtchn_to_irqhandler_lateeoi(evtchn_port_t evtchn, ...@@ -1380,14 +1388,13 @@ int bind_evtchn_to_irqhandler_lateeoi(evtchn_port_t evtchn,
EXPORT_SYMBOL_GPL(bind_evtchn_to_irqhandler_lateeoi); EXPORT_SYMBOL_GPL(bind_evtchn_to_irqhandler_lateeoi);
static int bind_interdomain_evtchn_to_irqhandler_chip( 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, irq_handler_t handler, unsigned long irqflags,
const char *devname, void *dev_id, struct irq_chip *chip) const char *devname, void *dev_id, struct irq_chip *chip)
{ {
int irq, retval; int irq, retval;
irq = bind_interdomain_evtchn_to_irq_chip(remote_domain, remote_port, irq = bind_interdomain_evtchn_to_irq_chip(dev, remote_port, chip);
chip);
if (irq < 0) if (irq < 0)
return irq; return irq;
...@@ -1400,14 +1407,14 @@ static int bind_interdomain_evtchn_to_irqhandler_chip( ...@@ -1400,14 +1407,14 @@ static int bind_interdomain_evtchn_to_irqhandler_chip(
return irq; 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, evtchn_port_t remote_port,
irq_handler_t handler, irq_handler_t handler,
unsigned long irqflags, unsigned long irqflags,
const char *devname, const char *devname,
void *dev_id) 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, remote_port, handler, irqflags, devname,
dev_id, &xen_lateeoi_chip); dev_id, &xen_lateeoi_chip);
} }
...@@ -1679,7 +1686,7 @@ void rebind_evtchn_irq(evtchn_port_t evtchn, int irq) ...@@ -1679,7 +1686,7 @@ void rebind_evtchn_irq(evtchn_port_t evtchn, int irq)
so there should be a proper type */ so there should be a proper type */
BUG_ON(info->type == IRQT_UNBOUND); 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); mutex_unlock(&irq_mapping_update_lock);
......
...@@ -348,7 +348,7 @@ static struct sock_mapping *pvcalls_new_active_socket( ...@@ -348,7 +348,7 @@ static struct sock_mapping *pvcalls_new_active_socket(
map->bytes = page; map->bytes = page;
ret = bind_interdomain_evtchn_to_irqhandler_lateeoi( ret = bind_interdomain_evtchn_to_irqhandler_lateeoi(
fedata->dev->otherend_id, evtchn, fedata->dev, evtchn,
pvcalls_back_conn_event, 0, "pvcalls-backend", map); pvcalls_back_conn_event, 0, "pvcalls-backend", map);
if (ret < 0) if (ret < 0)
goto out; goto out;
...@@ -948,7 +948,7 @@ static int backend_connect(struct xenbus_device *dev) ...@@ -948,7 +948,7 @@ static int backend_connect(struct xenbus_device *dev)
goto error; 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) if (err < 0)
goto error; goto error;
fedata->irq = err; fedata->irq = err;
......
...@@ -124,7 +124,7 @@ static int xen_pcibk_do_attach(struct xen_pcibk_device *pdev, int gnt_ref, ...@@ -124,7 +124,7 @@ static int xen_pcibk_do_attach(struct xen_pcibk_device *pdev, int gnt_ref,
pdev->sh_info = vaddr; pdev->sh_info = vaddr;
err = bind_interdomain_evtchn_to_irqhandler_lateeoi( 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); 0, DRV_NAME, pdev);
if (err < 0) { if (err < 0) {
xenbus_dev_fatal(pdev->xdev, err, xenbus_dev_fatal(pdev->xdev, err,
......
...@@ -799,7 +799,7 @@ static int scsiback_init_sring(struct vscsibk_info *info, grant_ref_t ring_ref, ...@@ -799,7 +799,7 @@ static int scsiback_init_sring(struct vscsibk_info *info, grant_ref_t ring_ref,
sring = (struct vscsiif_sring *)area; sring = (struct vscsiif_sring *)area;
BACK_RING_INIT(&info->ring, sring, PAGE_SIZE); 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) if (err < 0)
goto unmap_page; goto unmap_page;
......
...@@ -12,10 +12,11 @@ ...@@ -12,10 +12,11 @@
#include <asm/xen/hypercall.h> #include <asm/xen/hypercall.h>
#include <asm/xen/events.h> #include <asm/xen/events.h>
struct xenbus_device;
unsigned xen_evtchn_nr_channels(void); unsigned xen_evtchn_nr_channels(void);
int bind_evtchn_to_irq(evtchn_port_t evtchn); 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, int bind_evtchn_to_irqhandler(evtchn_port_t evtchn,
irq_handler_t handler, irq_handler_t handler,
unsigned long irqflags, const char *devname, unsigned long irqflags, const char *devname,
...@@ -35,9 +36,9 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi, ...@@ -35,9 +36,9 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi,
unsigned long irqflags, unsigned long irqflags,
const char *devname, const char *devname,
void *dev_id); 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); 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, evtchn_port_t remote_port,
irq_handler_t handler, irq_handler_t handler,
unsigned long irqflags, unsigned long irqflags,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment