Xen-Devel Archive on lore.kernel.org
 help / color / Atom feed
From: Ankur Arora <ankur.a.arora@oracle.com>
To: linux-kernel@vger.kernel.org, xen-devel@lists.xenproject.org
Cc: jgross@suse.com, sstabellini@kernel.org, konrad.wilk@oracle.com,
	ankur.a.arora@oracle.com, pbonzini@redhat.com,
	boris.ostrovsky@oracle.com, joao.m.martins@oracle.com
Subject: [RFC PATCH 09/16] xen/evtchn: support evtchn in xenhost_t
Date: Thu,  9 May 2019 10:25:33 -0700
Message-ID: <20190509172540.12398-10-ankur.a.arora__12801.2626942777$1557422821$gmane$org@oracle.com> (raw)
In-Reply-To: <20190509172540.12398-1-ankur.a.arora@oracle.com>

Largely mechanical patch that adds a new param, xenhost_t * to the
evtchn interfaces. The evtchn port instead of being domain unique, is
now scoped to xenhost_t.

As part of upcall handling we now look at all the xenhosts and, for
evtchn_2l, the xenhost's shared_info and vcpu_info. Other than this
event handling is largley unchanged.

Note that the IPI, timer, VIRQ, FUNCTION, PMU etc vectors remain
attached to xh_default. Only interdomain evtchns are allowable as
xh_remote.

TODO:
  - to minimize the changes, evtchn FIFO is disabled for now.

Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com>
---
 arch/x86/pci/xen.c                         |  16 +-
 arch/x86/xen/enlighten_hvm.c               |   2 +-
 arch/x86/xen/irq.c                         |   2 +-
 arch/x86/xen/smp.c                         |  16 +-
 arch/x86/xen/smp_pv.c                      |   4 +-
 arch/x86/xen/time.c                        |   5 +-
 arch/x86/xen/xen-ops.h                     |   1 +
 arch/x86/xen/xenhost.c                     |  16 +
 drivers/block/xen-blkback/xenbus.c         |   2 +-
 drivers/block/xen-blkfront.c               |   2 +-
 drivers/input/misc/xen-kbdfront.c          |   2 +-
 drivers/net/xen-netback/interface.c        |   8 +-
 drivers/net/xen-netfront.c                 |   6 +-
 drivers/pci/xen-pcifront.c                 |   2 +-
 drivers/xen/acpi.c                         |   2 +
 drivers/xen/balloon.c                      |   2 +-
 drivers/xen/events/Makefile                |   1 -
 drivers/xen/events/events_2l.c             | 188 +++++-----
 drivers/xen/events/events_base.c           | 379 ++++++++++++---------
 drivers/xen/events/events_fifo.c           |   2 +-
 drivers/xen/events/events_internal.h       |  78 ++---
 drivers/xen/evtchn.c                       |  22 +-
 drivers/xen/fallback.c                     |   1 +
 drivers/xen/gntalloc.c                     |   8 +-
 drivers/xen/gntdev.c                       |   8 +-
 drivers/xen/mcelog.c                       |   2 +-
 drivers/xen/pcpu.c                         |   2 +-
 drivers/xen/preempt.c                      |   1 +
 drivers/xen/privcmd.c                      |   1 +
 drivers/xen/sys-hypervisor.c               |   2 +-
 drivers/xen/time.c                         |   2 +-
 drivers/xen/xen-pciback/xenbus.c           |   2 +-
 drivers/xen/xen-scsiback.c                 |   5 +-
 drivers/xen/xenbus/xenbus_client.c         |   2 +-
 drivers/xen/xenbus/xenbus_comms.c          |   6 +-
 drivers/xen/xenbus/xenbus_probe.c          |   1 +
 drivers/xen/xenbus/xenbus_probe_backend.c  |   1 +
 drivers/xen/xenbus/xenbus_probe_frontend.c |   1 +
 drivers/xen/xenbus/xenbus_xs.c             |   1 +
 include/xen/events.h                       |  45 +--
 include/xen/xenhost.h                      |  17 +
 41 files changed, 483 insertions(+), 383 deletions(-)

diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index d1a3b9f08289..9aa591b5fa3b 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -19,6 +19,8 @@
 #include <asm/pci_x86.h>
 
 #include <asm/xen/hypervisor.h>
+#include <xen/interface/xen.h>
+#include <xen/xenhost.h>
 
 #include <xen/features.h>
 #include <xen/events.h>
@@ -46,7 +48,7 @@ static int xen_pcifront_enable_irq(struct pci_dev *dev)
 	if (gsi < nr_legacy_irqs())
 		share = 0;
 
-	rc = xen_bind_pirq_gsi_to_irq(gsi, pirq, share, "pcifront");
+	rc = xen_bind_pirq_gsi_to_irq(xh_default, gsi, pirq, share, "pcifront");
 	if (rc < 0) {
 		dev_warn(&dev->dev, "Xen PCI: failed to bind GSI%d (PIRQ%d) to IRQ: %d\n",
 			 gsi, pirq, rc);
@@ -96,7 +98,7 @@ static int xen_register_pirq(u32 gsi, int gsi_override, int triggering,
 	if (gsi_override >= 0)
 		gsi = gsi_override;
 
-	irq = xen_bind_pirq_gsi_to_irq(gsi, map_irq.pirq, shareable, name);
+	irq = xen_bind_pirq_gsi_to_irq(xh_default, gsi, map_irq.pirq, shareable, name);
 	if (irq < 0)
 		goto out;
 
@@ -180,7 +182,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 		goto error;
 	i = 0;
 	for_each_pci_msi_entry(msidesc, dev) {
-		irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i],
+		irq = xen_bind_pirq_msi_to_irq(xh_default, dev, msidesc, v[i],
 					       (type == PCI_CAP_ID_MSI) ? nvec : 1,
 					       (type == PCI_CAP_ID_MSIX) ?
 					       "pcifront-msi-x" :
@@ -234,7 +236,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 		return 1;
 
 	for_each_pci_msi_entry(msidesc, dev) {
-		pirq = xen_allocate_pirq_msi(dev, msidesc);
+		pirq = xen_allocate_pirq_msi(xh_default, dev, msidesc);
 		if (pirq < 0) {
 			irq = -ENODEV;
 			goto error;
@@ -242,7 +244,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 		xen_msi_compose_msg(dev, pirq, &msg);
 		__pci_write_msi_msg(msidesc, &msg);
 		dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
-		irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq,
+		irq = xen_bind_pirq_msi_to_irq(xh_default, dev, msidesc, pirq,
 					       (type == PCI_CAP_ID_MSI) ? nvec : 1,
 					       (type == PCI_CAP_ID_MSIX) ?
 					       "msi-x" : "msi",
@@ -337,7 +339,7 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 			goto out;
 		}
 
-		ret = xen_bind_pirq_msi_to_irq(dev, msidesc, map_irq.pirq,
+		ret = xen_bind_pirq_msi_to_irq(xh_default, dev, msidesc, map_irq.pirq,
 		                               (type == PCI_CAP_ID_MSI) ? nvec : 1,
 		                               (type == PCI_CAP_ID_MSIX) ? "msi-x" : "msi",
 		                               domid);
@@ -496,7 +498,7 @@ int __init pci_xen_initial_domain(void)
 	}
 	if (0 == nr_ioapics) {
 		for (irq = 0; irq < nr_legacy_irqs(); irq++)
-			xen_bind_pirq_gsi_to_irq(irq, irq, 0, "xt-pic");
+			xen_bind_pirq_gsi_to_irq(xh_default, irq, irq, 0, "xt-pic");
 	}
 	return 0;
 }
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index c1981a3e4989..efe483ceeb9a 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -266,7 +266,7 @@ static void __init xen_hvm_guest_init(void)
 	xen_hvm_smp_init();
 	WARN_ON(xen_cpuhp_setup(xen_cpu_up_prepare_hvm, xen_cpu_dead_hvm));
 	xen_unplug_emulated_devices();
-	x86_init.irqs.intr_init = xen_init_IRQ;
+	x86_init.irqs.intr_init = xenhost_init_IRQ;
 	xen_hvm_init_time_ops();
 	xen_hvm_init_mmu_ops();
 
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index f760a6abfb1e..3267c3505a64 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -170,5 +170,5 @@ static const struct pv_irq_ops xen_irq_ops __initconst = {
 void __init xen_init_irq_ops(void)
 {
 	pv_ops.irq = xen_irq_ops;
-	x86_init.irqs.intr_init = xen_init_IRQ;
+	x86_init.irqs.intr_init = xenhost_init_IRQ;
 }
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 867524be0065..c186d868dc5c 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -66,7 +66,7 @@ int xen_smp_intr_init(unsigned int cpu)
 	char *resched_name, *callfunc_name, *debug_name;
 
 	resched_name = kasprintf(GFP_KERNEL, "resched%d", cpu);
-	rc = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR,
+	rc = bind_ipi_to_irqhandler(xh_default, XEN_RESCHEDULE_VECTOR,
 				    cpu,
 				    xen_reschedule_interrupt,
 				    IRQF_PERCPU|IRQF_NOBALANCING,
@@ -78,7 +78,7 @@ int xen_smp_intr_init(unsigned int cpu)
 	per_cpu(xen_resched_irq, cpu).name = resched_name;
 
 	callfunc_name = kasprintf(GFP_KERNEL, "callfunc%d", cpu);
-	rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_VECTOR,
+	rc = bind_ipi_to_irqhandler(xh_default, XEN_CALL_FUNCTION_VECTOR,
 				    cpu,
 				    xen_call_function_interrupt,
 				    IRQF_PERCPU|IRQF_NOBALANCING,
@@ -90,7 +90,7 @@ int xen_smp_intr_init(unsigned int cpu)
 	per_cpu(xen_callfunc_irq, cpu).name = callfunc_name;
 
 	debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu);
-	rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu, xen_debug_interrupt,
+	rc = bind_virq_to_irqhandler(xh_default, VIRQ_DEBUG, cpu, xen_debug_interrupt,
 				     IRQF_PERCPU | IRQF_NOBALANCING,
 				     debug_name, NULL);
 	if (rc < 0)
@@ -99,7 +99,7 @@ int xen_smp_intr_init(unsigned int cpu)
 	per_cpu(xen_debug_irq, cpu).name = debug_name;
 
 	callfunc_name = kasprintf(GFP_KERNEL, "callfuncsingle%d", cpu);
-	rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_SINGLE_VECTOR,
+	rc = bind_ipi_to_irqhandler(xh_default, XEN_CALL_FUNCTION_SINGLE_VECTOR,
 				    cpu,
 				    xen_call_function_single_interrupt,
 				    IRQF_PERCPU|IRQF_NOBALANCING,
@@ -155,7 +155,7 @@ void __init xen_smp_cpus_done(unsigned int max_cpus)
 
 void xen_smp_send_reschedule(int cpu)
 {
-	xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR);
+	xen_send_IPI_one(xh_default, cpu, XEN_RESCHEDULE_VECTOR);
 }
 
 static void __xen_send_IPI_mask(const struct cpumask *mask,
@@ -164,7 +164,7 @@ static void __xen_send_IPI_mask(const struct cpumask *mask,
 	unsigned cpu;
 
 	for_each_cpu_and(cpu, mask, cpu_online_mask)
-		xen_send_IPI_one(cpu, vector);
+		xen_send_IPI_one(xh_default, cpu, vector);
 }
 
 void xen_smp_send_call_function_ipi(const struct cpumask *mask)
@@ -242,7 +242,7 @@ void xen_send_IPI_self(int vector)
 	int xen_vector = xen_map_vector(vector);
 
 	if (xen_vector >= 0)
-		xen_send_IPI_one(smp_processor_id(), xen_vector);
+		xen_send_IPI_one(xh_default, smp_processor_id(), xen_vector);
 }
 
 void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
@@ -259,7 +259,7 @@ void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
 		if (this_cpu == cpu)
 			continue;
 
-		xen_send_IPI_one(cpu, xen_vector);
+		xen_send_IPI_one(xh_default, cpu, xen_vector);
 	}
 }
 
diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c
index f4ea9eac8b6a..f8292be25d52 100644
--- a/arch/x86/xen/smp_pv.c
+++ b/arch/x86/xen/smp_pv.c
@@ -116,7 +116,7 @@ int xen_smp_intr_init_pv(unsigned int cpu)
 	char *callfunc_name, *pmu_name;
 
 	callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu);
-	rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR,
+	rc = bind_ipi_to_irqhandler(xh_default, XEN_IRQ_WORK_VECTOR,
 				    cpu,
 				    xen_irq_work_interrupt,
 				    IRQF_PERCPU|IRQF_NOBALANCING,
@@ -129,7 +129,7 @@ int xen_smp_intr_init_pv(unsigned int cpu)
 
 	if (is_xen_pmu(cpu)) {
 		pmu_name = kasprintf(GFP_KERNEL, "pmu%d", cpu);
-		rc = bind_virq_to_irqhandler(VIRQ_XENPMU, cpu,
+		rc = bind_virq_to_irqhandler(xh_default, VIRQ_XENPMU, cpu,
 					     xen_pmu_irq_handler,
 					     IRQF_PERCPU|IRQF_NOBALANCING,
 					     pmu_name, NULL);
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 217bc4de07ee..2f7ff3272d5d 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -340,11 +340,12 @@ void xen_setup_timer(int cpu)
 
 	snprintf(xevt->name, sizeof(xevt->name), "timer%d", cpu);
 
-	irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt,
+	irq = bind_virq_to_irqhandler(xh_default,
+				      VIRQ_TIMER, cpu, xen_timer_interrupt,
 				      IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER|
 				      IRQF_FORCE_RESUME|IRQF_EARLY_RESUME,
 				      xevt->name, NULL);
-	(void)xen_set_irq_priority(irq, XEN_IRQ_PRIORITY_MAX);
+	(void)xen_set_irq_priority(xh_default, irq, XEN_IRQ_PRIORITY_MAX);
 
 	memcpy(evt, xen_clockevent, sizeof(*evt));
 
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 96fd7edea7e9..4619808f1640 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -78,6 +78,7 @@ extern int xen_have_vcpu_info_placement;
 int xen_vcpu_setup(xenhost_t *xh, int cpu);
 void xen_vcpu_info_reset(xenhost_t *xh, int cpu);
 void xen_setup_vcpu_info_placement(void);
+void xenhost_init_IRQ(void);
 
 #ifdef CONFIG_SMP
 void xen_smp_init(void);
diff --git a/arch/x86/xen/xenhost.c b/arch/x86/xen/xenhost.c
index 3d8ccef89dcd..3bbfd0654833 100644
--- a/arch/x86/xen/xenhost.c
+++ b/arch/x86/xen/xenhost.c
@@ -2,6 +2,7 @@
 #include <linux/bug.h>
 #include <xen/xen.h>
 #include <xen/xenhost.h>
+#include <xen/events.h>
 #include "xen-ops.h"
 
 /*
@@ -84,3 +85,18 @@ void __xenhost_unregister(enum xenhost_type type)
 			BUG();
 	}
 }
+
+void xenhost_init_IRQ(void)
+{
+	xenhost_t **xh;
+	/*
+	 * xenhost_init_IRQ is called via x86_init.irq.intr_init().
+	 * For xenhost_r1 and xenhost_r2, the underlying state is
+	 * ready so we can go ahead and init both the variants.
+	 *
+	 * xenhost_r0, might be implemented via a loadable module
+	 * so that would do this initialization explicitly.
+	 */
+	for_each_xenhost(xh)
+		xen_init_IRQ(*xh);
+}
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index a4bc74e72c39..beea4272cfd3 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -228,7 +228,7 @@ static int xen_blkif_map(struct xen_blkif_ring *ring, grant_ref_t *gref,
 		BUG();
 	}
 
-	err = bind_interdomain_evtchn_to_irqhandler(blkif->domid, evtchn,
+	err = bind_interdomain_evtchn_to_irqhandler(xh_default, blkif->domid, evtchn,
 						    xen_blkif_be_int, 0,
 						    "blkif-backend", ring);
 	if (err < 0) {
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 0ed4b200fa58..a06716424023 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -1700,7 +1700,7 @@ static int setup_blkring(struct xenbus_device *dev,
 	if (err)
 		goto fail;
 
-	err = bind_evtchn_to_irqhandler(rinfo->evtchn, blkif_interrupt, 0,
+	err = bind_evtchn_to_irqhandler(xh_default, rinfo->evtchn, blkif_interrupt, 0,
 					"blkif", rinfo);
 	if (err <= 0) {
 		xenbus_dev_fatal(dev, err,
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c
index 24bc5c5d876f..47c6e499fe31 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -435,7 +435,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
 	ret = xenbus_alloc_evtchn(dev, &evtchn);
 	if (ret)
 		goto error_grant;
-	ret = bind_evtchn_to_irqhandler(evtchn, input_handler,
+	ret = bind_evtchn_to_irqhandler(xh_default, evtchn, input_handler,
 					0, dev->devicetype, info);
 	if (ret < 0) {
 		xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler");
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 182d6770f102..53d4e6351f1e 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -588,7 +588,7 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t ring_ref,
 	shared = (struct xen_netif_ctrl_sring *)addr;
 	BACK_RING_INIT(&vif->ctrl, shared, XEN_PAGE_SIZE);
 
-	err = bind_interdomain_evtchn_to_irq(vif->domid, evtchn);
+	err = bind_interdomain_evtchn_to_irq(xh_default, vif->domid, evtchn);
 	if (err < 0)
 		goto err_unmap;
 
@@ -646,7 +646,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(
+		err = bind_interdomain_evtchn_to_irqhandler(xh_default,
 			queue->vif->domid, tx_evtchn, xenvif_interrupt, 0,
 			queue->name, queue);
 		if (err < 0)
@@ -657,7 +657,7 @@ int xenvif_connect_data(struct xenvif_queue *queue,
 		/* feature-split-event-channels == 1 */
 		snprintf(queue->tx_irq_name, sizeof(queue->tx_irq_name),
 			 "%s-tx", queue->name);
-		err = bind_interdomain_evtchn_to_irqhandler(
+		err = bind_interdomain_evtchn_to_irqhandler(xh_default,
 			queue->vif->domid, tx_evtchn, xenvif_tx_interrupt, 0,
 			queue->tx_irq_name, queue);
 		if (err < 0)
@@ -667,7 +667,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(
+		err = bind_interdomain_evtchn_to_irqhandler(xh_default,
 			queue->vif->domid, rx_evtchn, xenvif_rx_interrupt, 0,
 			queue->rx_irq_name, queue);
 		if (err < 0)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index c914c24f880b..1cd0a2d2ba54 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1468,7 +1468,7 @@ static int setup_netfront_single(struct netfront_queue *queue)
 	if (err < 0)
 		goto fail;
 
-	err = bind_evtchn_to_irqhandler(queue->tx_evtchn,
+	err = bind_evtchn_to_irqhandler(xh_default, queue->tx_evtchn,
 					xennet_interrupt,
 					0, queue->info->netdev->name, queue);
 	if (err < 0)
@@ -1498,7 +1498,7 @@ static int setup_netfront_split(struct netfront_queue *queue)
 
 	snprintf(queue->tx_irq_name, sizeof(queue->tx_irq_name),
 		 "%s-tx", queue->name);
-	err = bind_evtchn_to_irqhandler(queue->tx_evtchn,
+	err = bind_evtchn_to_irqhandler(xh_default, queue->tx_evtchn,
 					xennet_tx_interrupt,
 					0, queue->tx_irq_name, queue);
 	if (err < 0)
@@ -1507,7 +1507,7 @@ static int setup_netfront_split(struct netfront_queue *queue)
 
 	snprintf(queue->rx_irq_name, sizeof(queue->rx_irq_name),
 		 "%s-rx", queue->name);
-	err = bind_evtchn_to_irqhandler(queue->rx_evtchn,
+	err = bind_evtchn_to_irqhandler(xh_default, queue->rx_evtchn,
 					xennet_rx_interrupt,
 					0, queue->rx_irq_name, queue);
 	if (err < 0)
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index eba6e33147a2..f894290e8b3a 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -800,7 +800,7 @@ static int pcifront_publish_info(struct pcifront_device *pdev)
 	if (err)
 		goto out;
 
-	err = bind_evtchn_to_irqhandler(pdev->evtchn, pcifront_handler_aer,
+	err = bind_evtchn_to_irqhandler(xh_default, pdev->evtchn, pcifront_handler_aer,
 		0, "pcifront", pdev);
 
 	if (err < 0)
diff --git a/drivers/xen/acpi.c b/drivers/xen/acpi.c
index 6893c79fd2a1..a959fce175f8 100644
--- a/drivers/xen/acpi.c
+++ b/drivers/xen/acpi.c
@@ -30,6 +30,8 @@
  * IN THE SOFTWARE.
  */
 
+#include <linux/types.h>
+#include <xen/interface/xen.h>
 #include <xen/acpi.h>
 #include <xen/interface/platform.h>
 #include <asm/xen/hypercall.h>
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index ceb5048de9a7..5ef4d6ad920d 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -62,11 +62,11 @@
 #include <asm/pgtable.h>
 #include <asm/tlb.h>
 
+#include <xen/interface/xen.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
 
 #include <xen/xen.h>
-#include <xen/interface/xen.h>
 #include <xen/interface/memory.h>
 #include <xen/balloon.h>
 #include <xen/features.h>
diff --git a/drivers/xen/events/Makefile b/drivers/xen/events/Makefile
index 62be55cd981d..08179fe04612 100644
--- a/drivers/xen/events/Makefile
+++ b/drivers/xen/events/Makefile
@@ -2,4 +2,3 @@ obj-y += events.o
 
 events-y += events_base.o
 events-y += events_2l.o
-events-y += events_fifo.o
diff --git a/drivers/xen/events/events_2l.c b/drivers/xen/events/events_2l.c
index f09dbe4e9c33..c69d7a5b3dff 100644
--- a/drivers/xen/events/events_2l.c
+++ b/drivers/xen/events/events_2l.c
@@ -40,50 +40,52 @@
 
 #define EVTCHN_MASK_SIZE (EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD)
 
-static DEFINE_PER_CPU(xen_ulong_t [EVTCHN_MASK_SIZE], cpu_evtchn_mask);
+static DEFINE_PER_CPU(xen_ulong_t [2][EVTCHN_MASK_SIZE], cpu_evtchn_mask);
 
-static unsigned evtchn_2l_max_channels(void)
+static unsigned evtchn_2l_max_channels(xenhost_t *xh)
 {
 	return EVTCHN_2L_NR_CHANNELS;
 }
 
 static void evtchn_2l_bind_to_cpu(struct irq_info *info, unsigned cpu)
 {
-	clear_bit(info->evtchn, BM(per_cpu(cpu_evtchn_mask, info->cpu)));
-	set_bit(info->evtchn, BM(per_cpu(cpu_evtchn_mask, cpu)));
+	clear_bit(info->evtchn,
+		BM(per_cpu(cpu_evtchn_mask, info->cpu))[info->xh - xenhosts]);
+	set_bit(info->evtchn,
+		BM(per_cpu(cpu_evtchn_mask, cpu))[info->xh - xenhosts]);
 }
 
-static void evtchn_2l_clear_pending(unsigned port)
+static void evtchn_2l_clear_pending(xenhost_t *xh, unsigned port)
 {
 	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
 	sync_clear_bit(port, BM(&s->evtchn_pending[0]));
 }
 
-static void evtchn_2l_set_pending(unsigned port)
+static void evtchn_2l_set_pending(xenhost_t *xh, unsigned port)
 {
 	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
 	sync_set_bit(port, BM(&s->evtchn_pending[0]));
 }
 
-static bool evtchn_2l_is_pending(unsigned port)
+static bool evtchn_2l_is_pending(xenhost_t *xh, unsigned port)
 {
-	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
+	struct shared_info *s = xh->HYPERVISOR_shared_info;
 	return sync_test_bit(port, BM(&s->evtchn_pending[0]));
 }
 
-static bool evtchn_2l_test_and_set_mask(unsigned port)
+static bool evtchn_2l_test_and_set_mask(xenhost_t *xh, unsigned port)
 {
-	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
+	struct shared_info *s = xh->HYPERVISOR_shared_info;
 	return sync_test_and_set_bit(port, BM(&s->evtchn_mask[0]));
 }
 
-static void evtchn_2l_mask(unsigned port)
+static void evtchn_2l_mask(xenhost_t *xh, unsigned port)
 {
 	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
 	sync_set_bit(port, BM(&s->evtchn_mask[0]));
 }
 
-static void evtchn_2l_unmask(unsigned port)
+static void evtchn_2l_unmask(xenhost_t *xh, unsigned port)
 {
 	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
 	unsigned int cpu = get_cpu();
@@ -91,7 +93,7 @@ static void evtchn_2l_unmask(unsigned port)
 
 	BUG_ON(!irqs_disabled());
 
-	if (unlikely((cpu != cpu_from_evtchn(port))))
+	if (unlikely((cpu != cpu_from_evtchn(xh, port))))
 		do_hypercall = 1;
 	else {
 		/*
@@ -116,9 +118,9 @@ static void evtchn_2l_unmask(unsigned port)
 	 * their own implementation of irq_enable). */
 	if (do_hypercall) {
 		struct evtchn_unmask unmask = { .port = port };
-		(void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
+		(void)hypervisor_event_channel_op(xh, EVTCHNOP_unmask, &unmask);
 	} else {
-		struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
+		struct vcpu_info *vcpu_info = xh->xen_vcpu[cpu];
 
 		/*
 		 * The following is basically the equivalent of
@@ -134,8 +136,8 @@ static void evtchn_2l_unmask(unsigned port)
 	put_cpu();
 }
 
-static DEFINE_PER_CPU(unsigned int, current_word_idx);
-static DEFINE_PER_CPU(unsigned int, current_bit_idx);
+static DEFINE_PER_CPU(unsigned int [2], current_word_idx);
+static DEFINE_PER_CPU(unsigned int [2], current_bit_idx);
 
 /*
  * Mask out the i least significant bits of w
@@ -143,11 +145,12 @@ static DEFINE_PER_CPU(unsigned int, current_bit_idx);
 #define MASK_LSBS(w, i) (w & ((~((xen_ulong_t)0UL)) << i))
 
 static inline xen_ulong_t active_evtchns(unsigned int cpu,
+					 xenhost_t *xh,
 					 struct shared_info *sh,
 					 unsigned int idx)
 {
 	return sh->evtchn_pending[idx] &
-		per_cpu(cpu_evtchn_mask, cpu)[idx] &
+		per_cpu(cpu_evtchn_mask, cpu)[xh - xenhosts][idx] &
 		~sh->evtchn_mask[idx];
 }
 
@@ -159,7 +162,7 @@ static inline xen_ulong_t active_evtchns(unsigned int cpu,
  * a bitset of words which contain pending event bits.  The second
  * level is a bitset of pending events themselves.
  */
-static void evtchn_2l_handle_events(unsigned cpu)
+static void evtchn_2l_handle_events(xenhost_t *xh, unsigned cpu)
 {
 	int irq;
 	xen_ulong_t pending_words;
@@ -167,8 +170,8 @@ static void evtchn_2l_handle_events(unsigned cpu)
 	int start_word_idx, start_bit_idx;
 	int word_idx, bit_idx;
 	int i;
-	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
-	struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
+	struct shared_info *s = xh->HYPERVISOR_shared_info;
+	struct vcpu_info *vcpu_info = xh->xen_vcpu[cpu];
 
 	/* Timer interrupt has highest priority. */
 	irq = irq_from_virq(cpu, VIRQ_TIMER);
@@ -176,7 +179,7 @@ static void evtchn_2l_handle_events(unsigned cpu)
 		unsigned int evtchn = evtchn_from_irq(irq);
 		word_idx = evtchn / BITS_PER_LONG;
 		bit_idx = evtchn % BITS_PER_LONG;
-		if (active_evtchns(cpu, s, word_idx) & (1ULL << bit_idx))
+		if (active_evtchns(cpu, xh, s, word_idx) & (1ULL << bit_idx))
 			generic_handle_irq(irq);
 	}
 
@@ -187,8 +190,8 @@ static void evtchn_2l_handle_events(unsigned cpu)
 	 */
 	pending_words = xchg_xen_ulong(&vcpu_info->evtchn_pending_sel, 0);
 
-	start_word_idx = __this_cpu_read(current_word_idx);
-	start_bit_idx = __this_cpu_read(current_bit_idx);
+	start_word_idx = __this_cpu_read(current_word_idx[xh - xenhosts]);
+	start_bit_idx = __this_cpu_read(current_bit_idx[xh - xenhosts]);
 
 	word_idx = start_word_idx;
 
@@ -207,7 +210,7 @@ static void evtchn_2l_handle_events(unsigned cpu)
 		}
 		word_idx = EVTCHN_FIRST_BIT(words);
 
-		pending_bits = active_evtchns(cpu, s, word_idx);
+		pending_bits = active_evtchns(cpu, xh, s, word_idx);
 		bit_idx = 0; /* usually scan entire word from start */
 		/*
 		 * We scan the starting word in two parts.
@@ -240,7 +243,7 @@ static void evtchn_2l_handle_events(unsigned cpu)
 
 			/* Process port. */
 			port = (word_idx * BITS_PER_EVTCHN_WORD) + bit_idx;
-			irq = get_evtchn_to_irq(port);
+			irq = get_evtchn_to_irq(xh, port);
 
 			if (irq != -1)
 				generic_handle_irq(irq);
@@ -248,10 +251,10 @@ static void evtchn_2l_handle_events(unsigned cpu)
 			bit_idx = (bit_idx + 1) % BITS_PER_EVTCHN_WORD;
 
 			/* Next caller starts at last processed + 1 */
-			__this_cpu_write(current_word_idx,
+			__this_cpu_write(current_word_idx[xh - xenhosts],
 					 bit_idx ? word_idx :
 					 (word_idx+1) % BITS_PER_EVTCHN_WORD);
-			__this_cpu_write(current_bit_idx, bit_idx);
+			__this_cpu_write(current_bit_idx[xh - xenhosts], bit_idx);
 		} while (bit_idx != 0);
 
 		/* Scan start_l1i twice; all others once. */
@@ -266,78 +269,81 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
 {
 	struct shared_info *sh = xh_default->HYPERVISOR_shared_info;
 	int cpu = smp_processor_id();
-	xen_ulong_t *cpu_evtchn = per_cpu(cpu_evtchn_mask, cpu);
+	xen_ulong_t *cpu_evtchn;
 	int i;
 	unsigned long flags;
 	static DEFINE_SPINLOCK(debug_lock);
 	struct vcpu_info *v;
+	xenhost_t **xh;
 
 	spin_lock_irqsave(&debug_lock, flags);
 
 	printk("\nvcpu %d\n  ", cpu);
 
-	for_each_online_cpu(i) {
-		int pending;
-		v = per_cpu(xen_vcpu, i);
-		pending = (get_irq_regs() && i == cpu)
-			? xen_irqs_disabled(get_irq_regs())
-			: v->evtchn_upcall_mask;
-		printk("%d: masked=%d pending=%d event_sel %0*"PRI_xen_ulong"\n  ", i,
-		       pending, v->evtchn_upcall_pending,
-		       (int)(sizeof(v->evtchn_pending_sel)*2),
-		       v->evtchn_pending_sel);
-	}
-	v = per_cpu(xen_vcpu, cpu);
+	for_each_xenhost(xh) {
+		cpu_evtchn = per_cpu(cpu_evtchn_mask, cpu)[(*xh) - xenhosts];
+		for_each_online_cpu(i) {
+			int pending;
+			v = (*xh)->xen_vcpu[i];
+			pending = (get_irq_regs() && i == cpu)
+				? xen_irqs_disabled(get_irq_regs())
+				: v->evtchn_upcall_mask;
+			printk("%d: masked=%d pending=%d event_sel %0*"PRI_xen_ulong"\n  ", i,
+			       pending, v->evtchn_upcall_pending,
+			       (int)(sizeof(v->evtchn_pending_sel)*2),
+			       v->evtchn_pending_sel);
+		}
+		v = (*xh)->xen_vcpu[cpu];
 
-	printk("\npending:\n   ");
-	for (i = ARRAY_SIZE(sh->evtchn_pending)-1; i >= 0; i--)
-		printk("%0*"PRI_xen_ulong"%s",
-		       (int)sizeof(sh->evtchn_pending[0])*2,
-		       sh->evtchn_pending[i],
-		       i % 8 == 0 ? "\n   " : " ");
-	printk("\nglobal mask:\n   ");
-	for (i = ARRAY_SIZE(sh->evtchn_mask)-1; i >= 0; i--)
-		printk("%0*"PRI_xen_ulong"%s",
-		       (int)(sizeof(sh->evtchn_mask[0])*2),
-		       sh->evtchn_mask[i],
-		       i % 8 == 0 ? "\n   " : " ");
+		printk("\npending:\n   ");
+		for (i = ARRAY_SIZE(sh->evtchn_pending)-1; i >= 0; i--)
+			printk("%0*"PRI_xen_ulong"%s",
+			       (int)sizeof(sh->evtchn_pending[0])*2,
+			       sh->evtchn_pending[i],
+			       i % 8 == 0 ? "\n   " : " ");
+		printk("\nglobal mask:\n   ");
+		for (i = ARRAY_SIZE(sh->evtchn_mask)-1; i >= 0; i--)
+			printk("%0*"PRI_xen_ulong"%s",
+			       (int)(sizeof(sh->evtchn_mask[0])*2),
+			       sh->evtchn_mask[i],
+			       i % 8 == 0 ? "\n   " : " ");
 
-	printk("\nglobally unmasked:\n   ");
-	for (i = ARRAY_SIZE(sh->evtchn_mask)-1; i >= 0; i--)
-		printk("%0*"PRI_xen_ulong"%s",
-		       (int)(sizeof(sh->evtchn_mask[0])*2),
-		       sh->evtchn_pending[i] & ~sh->evtchn_mask[i],
-		       i % 8 == 0 ? "\n   " : " ");
+		printk("\nglobally unmasked:\n   ");
+		for (i = ARRAY_SIZE(sh->evtchn_mask)-1; i >= 0; i--)
+			printk("%0*"PRI_xen_ulong"%s",
+			       (int)(sizeof(sh->evtchn_mask[0])*2),
+			       sh->evtchn_pending[i] & ~sh->evtchn_mask[i],
+			       i % 8 == 0 ? "\n   " : " ");
+		printk("\nlocal cpu%d mask:\n   ", cpu);
+		for (i = (EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD)-1; i >= 0; i--)
+			printk("%0*"PRI_xen_ulong"%s", (int)(sizeof(cpu_evtchn[0])*2),
+			       cpu_evtchn[i],
+			       i % 8 == 0 ? "\n   " : " ");
 
-	printk("\nlocal cpu%d mask:\n   ", cpu);
-	for (i = (EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD)-1; i >= 0; i--)
-		printk("%0*"PRI_xen_ulong"%s", (int)(sizeof(cpu_evtchn[0])*2),
-		       cpu_evtchn[i],
-		       i % 8 == 0 ? "\n   " : " ");
+		printk("\nlocally unmasked:\n   ");
+		for (i = ARRAY_SIZE(sh->evtchn_mask)-1; i >= 0; i--) {
+			xen_ulong_t pending = sh->evtchn_pending[i]
+				& ~sh->evtchn_mask[i]
+				& cpu_evtchn[i];
+			printk("%0*"PRI_xen_ulong"%s",
+			       (int)(sizeof(sh->evtchn_mask[0])*2),
+			       pending, i % 8 == 0 ? "\n   " : " ");
+		}
 
-	printk("\nlocally unmasked:\n   ");
-	for (i = ARRAY_SIZE(sh->evtchn_mask)-1; i >= 0; i--) {
-		xen_ulong_t pending = sh->evtchn_pending[i]
-			& ~sh->evtchn_mask[i]
-			& cpu_evtchn[i];
-		printk("%0*"PRI_xen_ulong"%s",
-		       (int)(sizeof(sh->evtchn_mask[0])*2),
-		       pending, i % 8 == 0 ? "\n   " : " ");
-	}
-
-	printk("\npending list:\n");
-	for (i = 0; i < EVTCHN_2L_NR_CHANNELS; i++) {
-		if (sync_test_bit(i, BM(sh->evtchn_pending))) {
-			int word_idx = i / BITS_PER_EVTCHN_WORD;
-			printk("  %d: event %d -> irq %d%s%s%s\n",
-			       cpu_from_evtchn(i), i,
-			       get_evtchn_to_irq(i),
-			       sync_test_bit(word_idx, BM(&v->evtchn_pending_sel))
-			       ? "" : " l2-clear",
-			       !sync_test_bit(i, BM(sh->evtchn_mask))
-			       ? "" : " globally-masked",
-			       sync_test_bit(i, BM(cpu_evtchn))
-			       ? "" : " locally-masked");
+		printk("\npending list:\n");
+		for (i = 0; i < EVTCHN_2L_NR_CHANNELS; i++) {
+			if (sync_test_bit(i, BM(sh->evtchn_pending))) {
+				int word_idx = i / BITS_PER_EVTCHN_WORD;
+				printk("  %d: event %d -> irq %d%s%s%s\n",
+				       cpu_from_evtchn(*xh, i), i,
+				       get_evtchn_to_irq(*xh, i),
+				       sync_test_bit(word_idx, BM(&v->evtchn_pending_sel))
+				       ? "" : " l2-clear",
+				       !sync_test_bit(i, BM(sh->evtchn_mask))
+				       ? "" : " globally-masked",
+				       sync_test_bit(i, BM(cpu_evtchn))
+				       ? "" : " locally-masked");
+			}
 		}
 	}
 
@@ -346,12 +352,12 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void evtchn_2l_resume(void)
+static void evtchn_2l_resume(xenhost_t *xh)
 {
 	int i;
 
 	for_each_online_cpu(i)
-		memset(per_cpu(cpu_evtchn_mask, i), 0, sizeof(xen_ulong_t) *
+		memset(per_cpu(cpu_evtchn_mask, i)[xh - xenhosts], 0, sizeof(xen_ulong_t) *
 				EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD);
 }
 
@@ -369,8 +375,8 @@ static const struct evtchn_ops evtchn_ops_2l = {
 	.resume	           = evtchn_2l_resume,
 };
 
-void __init xen_evtchn_2l_init(void)
+void xen_evtchn_2l_init(xenhost_t *xh)
 {
 	pr_info("Using 2-level ABI\n");
-	evtchn_ops = &evtchn_ops_2l;
+	xh->evtchn_ops = &evtchn_ops_2l;
 }
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index ae497876fe41..99b6b2c57d23 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -77,15 +77,14 @@ static DEFINE_PER_CPU(int [NR_VIRQS], virq_to_irq) = {[0 ... NR_VIRQS-1] = -1};
 /* IRQ <-> IPI mapping */
 static DEFINE_PER_CPU(int [XEN_NR_IPIS], ipi_to_irq) = {[0 ... XEN_NR_IPIS-1] = -1};
 
-int **evtchn_to_irq;
 #ifdef CONFIG_X86
 static unsigned long *pirq_eoi_map;
 #endif
 static bool (*pirq_needs_eoi)(unsigned irq);
 
-#define EVTCHN_ROW(e)  (e / (PAGE_SIZE/sizeof(**evtchn_to_irq)))
-#define EVTCHN_COL(e)  (e % (PAGE_SIZE/sizeof(**evtchn_to_irq)))
-#define EVTCHN_PER_ROW (PAGE_SIZE / sizeof(**evtchn_to_irq))
+#define EVTCHN_ROW(xh, e)  (e / (PAGE_SIZE/sizeof(**((xh)->evtchn_to_irq))))
+#define EVTCHN_COL(xh, e)  (e % (PAGE_SIZE/sizeof(**((xh)->evtchn_to_irq))))
+#define EVTCHN_PER_ROW(xh) (PAGE_SIZE / sizeof(**((xh)->evtchn_to_irq)))
 
 /* Xen will never allocate port zero for any purpose. */
 #define VALID_EVTCHN(chn)	((chn) != 0)
@@ -96,59 +95,62 @@ static struct irq_chip xen_pirq_chip;
 static void enable_dynirq(struct irq_data *data);
 static void disable_dynirq(struct irq_data *data);
 
-static void clear_evtchn_to_irq_row(unsigned row)
+static void clear_evtchn_to_irq_row(xenhost_t *xh, unsigned row)
 {
 	unsigned col;
 
-	for (col = 0; col < EVTCHN_PER_ROW; col++)
-		evtchn_to_irq[row][col] = -1;
+	for (col = 0; col < EVTCHN_PER_ROW(xh); col++)
+		xh->evtchn_to_irq[row][col] = -1;
 }
 
 static void clear_evtchn_to_irq_all(void)
 {
 	unsigned row;
+	xenhost_t **xh;
 
-	for (row = 0; row < EVTCHN_ROW(xen_evtchn_max_channels()); row++) {
-		if (evtchn_to_irq[row] == NULL)
-			continue;
-		clear_evtchn_to_irq_row(row);
+	for_each_xenhost(xh) {
+		for (row = 0; row < EVTCHN_ROW(*xh, xen_evtchn_max_channels(*xh)); row++) {
+			if ((*xh)->evtchn_to_irq[row] == NULL)
+				continue;
+			clear_evtchn_to_irq_row(*xh, row);
+		}
 	}
 }
 
-static int set_evtchn_to_irq(unsigned evtchn, unsigned irq)
+static int set_evtchn_to_irq(xenhost_t *xh, unsigned evtchn, unsigned irq)
 {
 	unsigned row;
 	unsigned col;
 
-	if (evtchn >= xen_evtchn_max_channels())
+	if (evtchn >= xen_evtchn_max_channels(xh))
 		return -EINVAL;
 
-	row = EVTCHN_ROW(evtchn);
-	col = EVTCHN_COL(evtchn);
+	row = EVTCHN_ROW(xh, evtchn);
+	col = EVTCHN_COL(xh, evtchn);
 
-	if (evtchn_to_irq[row] == NULL) {
+	if (xh->evtchn_to_irq[row] == NULL) {
 		/* Unallocated irq entries return -1 anyway */
 		if (irq == -1)
 			return 0;
 
-		evtchn_to_irq[row] = (int *)get_zeroed_page(GFP_KERNEL);
-		if (evtchn_to_irq[row] == NULL)
+		xh->evtchn_to_irq[row] = (int *)get_zeroed_page(GFP_KERNEL);
+		if (xh->evtchn_to_irq[row] == NULL)
 			return -ENOMEM;
 
-		clear_evtchn_to_irq_row(row);
+		clear_evtchn_to_irq_row(xh, row);
 	}
 
-	evtchn_to_irq[row][col] = irq;
+	xh->evtchn_to_irq[row][col] = irq;
 	return 0;
 }
 
-int get_evtchn_to_irq(unsigned evtchn)
+int get_evtchn_to_irq(xenhost_t *xh, unsigned evtchn)
 {
-	if (evtchn >= xen_evtchn_max_channels())
+	if (evtchn >= xen_evtchn_max_channels(xh))
 		return -1;
-	if (evtchn_to_irq[EVTCHN_ROW(evtchn)] == NULL)
+	if (xh->evtchn_to_irq[EVTCHN_ROW(xh, evtchn)] == NULL)
 		return -1;
-	return evtchn_to_irq[EVTCHN_ROW(evtchn)][EVTCHN_COL(evtchn)];
+	return xh->evtchn_to_irq[EVTCHN_ROW(xh, evtchn)][EVTCHN_COL(xh, evtchn)];
 }
 
 /* Get info for IRQ */
@@ -159,6 +161,7 @@ struct irq_info *info_for_irq(unsigned irq)
 
 /* Constructors for packed IRQ information. */
 static int xen_irq_info_common_setup(struct irq_info *info,
+				     xenhost_t *xh,
 				     unsigned irq,
 				     enum xen_irq_type type,
 				     unsigned evtchn,
@@ -173,7 +176,7 @@ static int xen_irq_info_common_setup(struct irq_info *info,
 	info->evtchn = evtchn;
 	info->cpu = cpu;
 
-	ret = set_evtchn_to_irq(evtchn, irq);
+	ret = set_evtchn_to_irq(xh, evtchn, irq);
 	if (ret < 0)
 		return ret;
 
@@ -182,29 +185,34 @@ static int xen_irq_info_common_setup(struct irq_info *info,
 	return xen_evtchn_port_setup(info);
 }
 
-static int xen_irq_info_evtchn_setup(unsigned irq,
+static int xen_irq_info_evtchn_setup(xenhost_t *xh,
+				     unsigned irq,
 				     unsigned evtchn)
 {
 	struct irq_info *info = info_for_irq(irq);
 
-	return xen_irq_info_common_setup(info, irq, IRQT_EVTCHN, evtchn, 0);
+	return xen_irq_info_common_setup(info, xh, irq, IRQT_EVTCHN, evtchn, 0);
 }
 
-static int xen_irq_info_ipi_setup(unsigned cpu,
+static int xen_irq_info_ipi_setup(xenhost_t *xh,
+				  unsigned cpu,
 				  unsigned irq,
 				  unsigned evtchn,
 				  enum ipi_vector ipi)
 {
 	struct irq_info *info = info_for_irq(irq);
 
+	BUG_ON(xh->type != xenhost_r1);
+
 	info->u.ipi = ipi;
 
 	per_cpu(ipi_to_irq, cpu)[ipi] = irq;
 
-	return xen_irq_info_common_setup(info, irq, IRQT_IPI, evtchn, 0);
+	return xen_irq_info_common_setup(info, xh, irq, IRQT_IPI, evtchn, 0);
 }
 
-static int xen_irq_info_virq_setup(unsigned cpu,
+static int xen_irq_info_virq_setup(xenhost_t *xh,
+				   unsigned cpu,
 				   unsigned irq,
 				   unsigned evtchn,
 				   unsigned virq)
@@ -215,10 +223,11 @@ static int xen_irq_info_virq_setup(unsigned cpu,
 
 	per_cpu(virq_to_irq, cpu)[virq] = irq;
 
-	return xen_irq_info_common_setup(info, irq, IRQT_VIRQ, evtchn, 0);
+	return xen_irq_info_common_setup(info, xh, irq, IRQT_VIRQ, evtchn, 0);
 }
 
-static int xen_irq_info_pirq_setup(unsigned irq,
+static int xen_irq_info_pirq_setup(xenhost_t *xh,
+				   unsigned irq,
 				   unsigned evtchn,
 				   unsigned pirq,
 				   unsigned gsi,
@@ -232,12 +241,12 @@ static int xen_irq_info_pirq_setup(unsigned irq,
 	info->u.pirq.domid = domid;
 	info->u.pirq.flags = flags;
 
-	return xen_irq_info_common_setup(info, irq, IRQT_PIRQ, evtchn, 0);
+	return xen_irq_info_common_setup(info, xh, irq, IRQT_PIRQ, evtchn, 0);
 }
 
 static void xen_irq_info_cleanup(struct irq_info *info)
 {
-	set_evtchn_to_irq(info->evtchn, -1);
+	set_evtchn_to_irq(info->xh, info->evtchn, -1);
 	info->evtchn = 0;
 }
 
@@ -252,9 +261,9 @@ unsigned int evtchn_from_irq(unsigned irq)
 	return info_for_irq(irq)->evtchn;
 }
 
-unsigned irq_from_evtchn(unsigned int evtchn)
+unsigned irq_from_evtchn(xenhost_t *xh, unsigned int evtchn)
 {
-	return get_evtchn_to_irq(evtchn);
+	return get_evtchn_to_irq(xh, evtchn);
 }
 EXPORT_SYMBOL_GPL(irq_from_evtchn);
 
@@ -303,9 +312,9 @@ unsigned cpu_from_irq(unsigned irq)
 	return info_for_irq(irq)->cpu;
 }
 
-unsigned int cpu_from_evtchn(unsigned int evtchn)
+unsigned int cpu_from_evtchn(xenhost_t *xh, unsigned int evtchn)
 {
-	int irq = get_evtchn_to_irq(evtchn);
+	int irq = get_evtchn_to_irq(xh, evtchn);
 	unsigned ret = 0;
 
 	if (irq != -1)
@@ -329,9 +338,9 @@ static bool pirq_needs_eoi_flag(unsigned irq)
 	return info->u.pirq.flags & PIRQ_NEEDS_EOI;
 }
 
-static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
+static void bind_evtchn_to_cpu(xenhost_t *xh, unsigned int chn, unsigned int cpu)
 {
-	int irq = get_evtchn_to_irq(chn);
+	int irq = get_evtchn_to_irq(xh, chn);
 	struct irq_info *info = info_for_irq(irq);
 
 	BUG_ON(irq == -1);
@@ -356,11 +365,11 @@ void notify_remote_via_irq(int irq)
 	int evtchn = evtchn_from_irq(irq);
 
 	if (VALID_EVTCHN(evtchn))
-		notify_remote_via_evtchn(evtchn);
+		notify_remote_via_evtchn(info_for_irq(irq)->xh, evtchn);
 }
 EXPORT_SYMBOL_GPL(notify_remote_via_irq);
 
-static void xen_irq_init(unsigned irq)
+static void xen_irq_init(xenhost_t *xh, unsigned irq)
 {
 	struct irq_info *info;
 #ifdef CONFIG_SMP
@@ -374,31 +383,32 @@ static void xen_irq_init(unsigned irq)
 
 	info->type = IRQT_UNBOUND;
 	info->refcnt = -1;
+	info->xh = xh;
 
 	irq_set_handler_data(irq, info);
 
 	list_add_tail(&info->list, &xen_irq_list_head);
 }
 
-static int __must_check xen_allocate_irqs_dynamic(int nvec)
+static int __must_check xen_allocate_irqs_dynamic(xenhost_t *xh, int nvec)
 {
 	int i, irq = irq_alloc_descs(-1, 0, nvec, -1);
 
 	if (irq >= 0) {
 		for (i = 0; i < nvec; i++)
-			xen_irq_init(irq + i);
+			xen_irq_init(xh, irq + i);
 	}
 
 	return irq;
 }
 
-static inline int __must_check xen_allocate_irq_dynamic(void)
+static inline int __must_check xen_allocate_irq_dynamic(xenhost_t *xh)
 {
 
-	return xen_allocate_irqs_dynamic(1);
+	return xen_allocate_irqs_dynamic(xh, 1);
 }
 
-static int __must_check xen_allocate_irq_gsi(unsigned gsi)
+static int __must_check xen_allocate_irq_gsi(xenhost_t *xh, unsigned gsi)
 {
 	int irq;
 
@@ -409,7 +419,7 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)
 	 * space.
 	 */
 	if (xen_pv_domain() && !xen_initial_domain())
-		return xen_allocate_irq_dynamic();
+		return xen_allocate_irq_dynamic(xh);
 
 	/* Legacy IRQ descriptors are already allocated by the arch. */
 	if (gsi < nr_legacy_irqs())
@@ -417,7 +427,7 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)
 	else
 		irq = irq_alloc_desc_at(gsi, -1);
 
-	xen_irq_init(irq);
+	xen_irq_init(xh, irq);
 
 	return irq;
 }
@@ -444,12 +454,12 @@ static void xen_free_irq(unsigned irq)
 	irq_free_desc(irq);
 }
 
-static void xen_evtchn_close(unsigned int port)
+static void xen_evtchn_close(xenhost_t *xh, unsigned int port)
 {
 	struct evtchn_close close;
 
 	close.port = port;
-	if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
+	if (hypervisor_event_channel_op(xh, EVTCHNOP_close, &close) != 0)
 		BUG();
 }
 
@@ -473,6 +483,7 @@ static void eoi_pirq(struct irq_data *data)
 {
 	int evtchn = evtchn_from_irq(data->irq);
 	struct physdev_eoi eoi = { .irq = pirq_from_irq(data->irq) };
+	xenhost_t *xh = info_for_irq(data->irq)->xh;
 	int rc = 0;
 
 	if (!VALID_EVTCHN(evtchn))
@@ -480,16 +491,16 @@ static void eoi_pirq(struct irq_data *data)
 
 	if (unlikely(irqd_is_setaffinity_pending(data)) &&
 	    likely(!irqd_irq_disabled(data))) {
-		int masked = test_and_set_mask(evtchn);
+		int masked = test_and_set_mask(xh, evtchn);
 
-		clear_evtchn(evtchn);
+		clear_evtchn(xh, evtchn);
 
 		irq_move_masked_irq(data);
 
 		if (!masked)
-			unmask_evtchn(evtchn);
+			unmask_evtchn(xh, evtchn);
 	} else
-		clear_evtchn(evtchn);
+		clear_evtchn(xh, evtchn);
 
 	if (pirq_needs_eoi(data->irq)) {
 		rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
@@ -519,7 +530,7 @@ static unsigned int __startup_pirq(unsigned int irq)
 	/* NB. We are happy to share unless we are probing. */
 	bind_pirq.flags = info->u.pirq.flags & PIRQ_SHAREABLE ?
 					BIND_PIRQ__WILL_SHARE : 0;
-	rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq);
+	rc = hypervisor_event_channel_op(info->xh, EVTCHNOP_bind_pirq, &bind_pirq);
 	if (rc != 0) {
 		pr_warn("Failed to obtain physical IRQ %d\n", irq);
 		return 0;
@@ -528,26 +539,26 @@ static unsigned int __startup_pirq(unsigned int irq)
 
 	pirq_query_unmask(irq);
 
-	rc = set_evtchn_to_irq(evtchn, irq);
+	rc = set_evtchn_to_irq(info->xh, evtchn, irq);
 	if (rc)
 		goto err;
 
 	info->evtchn = evtchn;
-	bind_evtchn_to_cpu(evtchn, 0);
+	bind_evtchn_to_cpu(info->xh, evtchn, 0);
 
 	rc = xen_evtchn_port_setup(info);
 	if (rc)
 		goto err;
 
 out:
-	unmask_evtchn(evtchn);
+	unmask_evtchn(info->xh, evtchn);
 	eoi_pirq(irq_get_irq_data(irq));
 
 	return 0;
 
 err:
 	pr_err("irq%d: Failed to set port to irq mapping (%d)\n", irq, rc);
-	xen_evtchn_close(evtchn);
+	xen_evtchn_close(info->xh, evtchn);
 	return 0;
 }
 
@@ -567,8 +578,8 @@ static void shutdown_pirq(struct irq_data *data)
 	if (!VALID_EVTCHN(evtchn))
 		return;
 
-	mask_evtchn(evtchn);
-	xen_evtchn_close(evtchn);
+	mask_evtchn(info->xh, evtchn);
+	xen_evtchn_close(info->xh, evtchn);
 	xen_irq_info_cleanup(info);
 }
 
@@ -612,7 +623,7 @@ static void __unbind_from_irq(unsigned int irq)
 	if (VALID_EVTCHN(evtchn)) {
 		unsigned int cpu = cpu_from_irq(irq);
 
-		xen_evtchn_close(evtchn);
+		xen_evtchn_close(info->xh, evtchn);
 
 		switch (type_from_irq(irq)) {
 		case IRQT_VIRQ:
@@ -641,13 +652,15 @@ static void __unbind_from_irq(unsigned int irq)
  * Shareable implies level triggered, not shareable implies edge
  * triggered here.
  */
-int xen_bind_pirq_gsi_to_irq(unsigned gsi,
+int xen_bind_pirq_gsi_to_irq(xenhost_t *xh, unsigned gsi,
 			     unsigned pirq, int shareable, char *name)
 {
 	int irq = -1;
 	struct physdev_irq irq_op;
 	int ret;
 
+	BUG_ON(xh->type != xenhost_r1);
+
 	mutex_lock(&irq_mapping_update_lock);
 
 	irq = xen_irq_from_gsi(gsi);
@@ -657,7 +670,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
 		goto out;
 	}
 
-	irq = xen_allocate_irq_gsi(gsi);
+	irq = xen_allocate_irq_gsi(xh, gsi);
 	if (irq < 0)
 		goto out;
 
@@ -668,13 +681,13 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
 	 * driver provides a PCI bus that does the call to do exactly
 	 * this in the priv domain. */
 	if (xen_initial_domain() &&
-	    HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) {
+	    hypervisor_physdev_op(xh, PHYSDEVOP_alloc_irq_vector, &irq_op)) {
 		xen_free_irq(irq);
 		irq = -ENOSPC;
 		goto out;
 	}
 
-	ret = xen_irq_info_pirq_setup(irq, 0, pirq, gsi, DOMID_SELF,
+	ret = xen_irq_info_pirq_setup(xh, irq, 0, pirq, gsi, DOMID_SELF,
 			       shareable ? PIRQ_SHAREABLE : 0);
 	if (ret < 0) {
 		__unbind_from_irq(irq);
@@ -712,13 +725,13 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
 }
 
 #ifdef CONFIG_PCI_MSI
-int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc)
+int xen_allocate_pirq_msi(xenhost_t *xh, struct pci_dev *dev, struct msi_desc *msidesc)
 {
 	int rc;
 	struct physdev_get_free_pirq op_get_free_pirq;
 
 	op_get_free_pirq.type = MAP_PIRQ_TYPE_MSI;
-	rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq);
+	rc = hypervisor_physdev_op(xh, PHYSDEVOP_get_free_pirq, &op_get_free_pirq);
 
 	WARN_ONCE(rc == -ENOSYS,
 		  "hypervisor does not support the PHYSDEVOP_get_free_pirq interface\n");
@@ -726,21 +739,21 @@ int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc)
 	return rc ? -1 : op_get_free_pirq.pirq;
 }
 
-int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
+int xen_bind_pirq_msi_to_irq(xenhost_t *xh, struct pci_dev *dev, struct msi_desc *msidesc,
 			     int pirq, int nvec, const char *name, domid_t domid)
 {
 	int i, irq, ret;
 
 	mutex_lock(&irq_mapping_update_lock);
 
-	irq = xen_allocate_irqs_dynamic(nvec);
+	irq = xen_allocate_irqs_dynamic(xh, nvec);
 	if (irq < 0)
 		goto out;
 
 	for (i = 0; i < nvec; i++) {
 		irq_set_chip_and_handler_name(irq + i, &xen_pirq_chip, handle_edge_irq, name);
 
-		ret = xen_irq_info_pirq_setup(irq + i, 0, pirq + i, 0, domid,
+		ret = xen_irq_info_pirq_setup(xh, irq + i, 0, pirq + i, 0, domid,
 					      i == 0 ? 0 : PIRQ_MSI_GROUP);
 		if (ret < 0)
 			goto error_irq;
@@ -776,7 +789,7 @@ int xen_destroy_irq(int irq)
 	if (xen_initial_domain() && !(info->u.pirq.flags & PIRQ_MSI_GROUP)) {
 		unmap_irq.pirq = info->u.pirq.pirq;
 		unmap_irq.domid = info->u.pirq.domid;
-		rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq);
+		rc = hypervisor_physdev_op(info->xh, PHYSDEVOP_unmap_pirq, &unmap_irq);
 		/* If another domain quits without making the pci_disable_msix
 		 * call, the Xen hypervisor takes care of freeing the PIRQs
 		 * (free_domain_pirqs).
@@ -826,34 +839,34 @@ int xen_pirq_from_irq(unsigned irq)
 }
 EXPORT_SYMBOL_GPL(xen_pirq_from_irq);
 
-int bind_evtchn_to_irq(unsigned int evtchn)
+int bind_evtchn_to_irq(xenhost_t *xh, unsigned int evtchn)
 {
 	int irq;
 	int ret;
 
-	if (evtchn >= xen_evtchn_max_channels())
+	if (evtchn >= xen_evtchn_max_channels(xh))
 		return -ENOMEM;
 
 	mutex_lock(&irq_mapping_update_lock);
 
-	irq = get_evtchn_to_irq(evtchn);
+	irq = get_evtchn_to_irq(xh, evtchn);
 
 	if (irq == -1) {
-		irq = xen_allocate_irq_dynamic();
+		irq = xen_allocate_irq_dynamic(xh);
 		if (irq < 0)
 			goto out;
 
 		irq_set_chip_and_handler_name(irq, &xen_dynamic_chip,
 					      handle_edge_irq, "event");
 
-		ret = xen_irq_info_evtchn_setup(irq, evtchn);
+		ret = xen_irq_info_evtchn_setup(xh, irq, evtchn);
 		if (ret < 0) {
 			__unbind_from_irq(irq);
 			irq = ret;
 			goto out;
 		}
 		/* New interdomain events are bound to VCPU 0. */
-		bind_evtchn_to_cpu(evtchn, 0);
+		bind_evtchn_to_cpu(xh, evtchn, 0);
 	} else {
 		struct irq_info *info = info_for_irq(irq);
 		WARN_ON(info == NULL || info->type != IRQT_EVTCHN);
@@ -866,37 +879,39 @@ int bind_evtchn_to_irq(unsigned int evtchn)
 }
 EXPORT_SYMBOL_GPL(bind_evtchn_to_irq);
 
-static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
+static int bind_ipi_to_irq(xenhost_t *xh, unsigned int ipi, unsigned int cpu)
 {
 	struct evtchn_bind_ipi bind_ipi;
 	int evtchn, irq;
 	int ret;
 
+	BUG_ON(xh->type == xenhost_r2);
+
 	mutex_lock(&irq_mapping_update_lock);
 
 	irq = per_cpu(ipi_to_irq, cpu)[ipi];
 
 	if (irq == -1) {
-		irq = xen_allocate_irq_dynamic();
+		irq = xen_allocate_irq_dynamic(xh);
 		if (irq < 0)
 			goto out;
 
 		irq_set_chip_and_handler_name(irq, &xen_percpu_chip,
 					      handle_percpu_irq, "ipi");
 
-		bind_ipi.vcpu = xen_vcpu_nr(xh_default, cpu);
-		if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
+		bind_ipi.vcpu = xen_vcpu_nr(xh, cpu);
+		if (hypervisor_event_channel_op(xh, EVTCHNOP_bind_ipi,
 						&bind_ipi) != 0)
 			BUG();
 		evtchn = bind_ipi.port;
 
-		ret = xen_irq_info_ipi_setup(cpu, irq, evtchn, ipi);
+		ret = xen_irq_info_ipi_setup(xh, cpu, irq, evtchn, ipi);
 		if (ret < 0) {
 			__unbind_from_irq(irq);
 			irq = ret;
 			goto out;
 		}
-		bind_evtchn_to_cpu(evtchn, cpu);
+		bind_evtchn_to_cpu(xh, evtchn, cpu);
 	} else {
 		struct irq_info *info = info_for_irq(irq);
 		WARN_ON(info == NULL || info->type != IRQT_IPI);
@@ -907,7 +922,7 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
 	return irq;
 }
 
-int bind_interdomain_evtchn_to_irq(unsigned int remote_domain,
+int bind_interdomain_evtchn_to_irq(xenhost_t *xh, unsigned int remote_domain,
 				   unsigned int remote_port)
 {
 	struct evtchn_bind_interdomain bind_interdomain;
@@ -916,28 +931,28 @@ int bind_interdomain_evtchn_to_irq(unsigned int remote_domain,
 	bind_interdomain.remote_dom  = remote_domain;
 	bind_interdomain.remote_port = remote_port;
 
-	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+	err = hypervisor_event_channel_op(xh, EVTCHNOP_bind_interdomain,
 					  &bind_interdomain);
 
-	return err ? : bind_evtchn_to_irq(bind_interdomain.local_port);
+	return err ? : bind_evtchn_to_irq(xh, bind_interdomain.local_port);
 }
 EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irq);
 
-static int find_virq(unsigned int virq, unsigned int cpu)
+static int find_virq(xenhost_t *xh, unsigned int virq, unsigned int cpu)
 {
 	struct evtchn_status status;
 	int port, rc = -ENOENT;
 
 	memset(&status, 0, sizeof(status));
-	for (port = 0; port < xen_evtchn_max_channels(); port++) {
+	for (port = 0; port < xen_evtchn_max_channels(xh); port++) {
 		status.dom = DOMID_SELF;
 		status.port = port;
-		rc = HYPERVISOR_event_channel_op(EVTCHNOP_status, &status);
+		rc = hypervisor_event_channel_op(xh, EVTCHNOP_status, &status);
 		if (rc < 0)
 			continue;
 		if (status.status != EVTCHNSTAT_virq)
 			continue;
-		if (status.u.virq == virq && status.vcpu == xen_vcpu_nr(xh_default, cpu)) {
+		if (status.u.virq == virq && status.vcpu == xen_vcpu_nr(xh, cpu)) {
 			rc = port;
 			break;
 		}
@@ -952,13 +967,13 @@ static int find_virq(unsigned int virq, unsigned int cpu)
  * hypervisor ABI. Use xen_evtchn_max_channels() for the maximum
  * supported.
  */
-unsigned xen_evtchn_nr_channels(void)
+unsigned xen_evtchn_nr_channels(xenhost_t *xh)
 {
-        return evtchn_ops->nr_channels();
+        return evtchn_ops->nr_channels(xh);
 }
 EXPORT_SYMBOL_GPL(xen_evtchn_nr_channels);
 
-int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu)
+int bind_virq_to_irq(xenhost_t *xh, unsigned int virq, unsigned int cpu, bool percpu)
 {
 	struct evtchn_bind_virq bind_virq;
 	int evtchn, irq, ret;
@@ -968,7 +983,7 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu)
 	irq = per_cpu(virq_to_irq, cpu)[virq];
 
 	if (irq == -1) {
-		irq = xen_allocate_irq_dynamic();
+		irq = xen_allocate_irq_dynamic(xh);
 		if (irq < 0)
 			goto out;
 
@@ -980,26 +995,26 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu)
 						      handle_edge_irq, "virq");
 
 		bind_virq.virq = virq;
-		bind_virq.vcpu = xen_vcpu_nr(xh_default, cpu);
-		ret = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+		bind_virq.vcpu = xen_vcpu_nr(xh, cpu);
+		ret = hypervisor_event_channel_op(xh, EVTCHNOP_bind_virq,
 						&bind_virq);
 		if (ret == 0)
 			evtchn = bind_virq.port;
 		else {
 			if (ret == -EEXIST)
-				ret = find_virq(virq, cpu);
+				ret = find_virq(xh, virq, cpu);
 			BUG_ON(ret < 0);
 			evtchn = ret;
 		}
 
-		ret = xen_irq_info_virq_setup(cpu, irq, evtchn, virq);
+		ret = xen_irq_info_virq_setup(xh, cpu, irq, evtchn, virq);
 		if (ret < 0) {
 			__unbind_from_irq(irq);
 			irq = ret;
 			goto out;
 		}
 
-		bind_evtchn_to_cpu(evtchn, cpu);
+		bind_evtchn_to_cpu(xh, evtchn, cpu);
 	} else {
 		struct irq_info *info = info_for_irq(irq);
 		WARN_ON(info == NULL || info->type != IRQT_VIRQ);
@@ -1018,14 +1033,15 @@ static void unbind_from_irq(unsigned int irq)
 	mutex_unlock(&irq_mapping_update_lock);
 }
 
-int bind_evtchn_to_irqhandler(unsigned int evtchn,
+int bind_evtchn_to_irqhandler(xenhost_t *xh,
+			      unsigned int evtchn,
 			      irq_handler_t handler,
 			      unsigned long irqflags,
 			      const char *devname, void *dev_id)
 {
 	int irq, retval;
 
-	irq = bind_evtchn_to_irq(evtchn);
+	irq = bind_evtchn_to_irq(xh, evtchn);
 	if (irq < 0)
 		return irq;
 	retval = request_irq(irq, handler, irqflags, devname, dev_id);
@@ -1038,7 +1054,8 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn,
 }
 EXPORT_SYMBOL_GPL(bind_evtchn_to_irqhandler);
 
-int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
+int bind_interdomain_evtchn_to_irqhandler(xenhost_t *xh,
+					  unsigned int remote_domain,
 					  unsigned int remote_port,
 					  irq_handler_t handler,
 					  unsigned long irqflags,
@@ -1047,7 +1064,7 @@ int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
 {
 	int irq, retval;
 
-	irq = bind_interdomain_evtchn_to_irq(remote_domain, remote_port);
+	irq = bind_interdomain_evtchn_to_irq(xh, remote_domain, remote_port);
 	if (irq < 0)
 		return irq;
 
@@ -1061,13 +1078,14 @@ int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
 }
 EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irqhandler);
 
-int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
+int bind_virq_to_irqhandler(xenhost_t *xh,
+			    unsigned int virq, unsigned int cpu,
 			    irq_handler_t handler,
 			    unsigned long irqflags, const char *devname, void *dev_id)
 {
 	int irq, retval;
 
-	irq = bind_virq_to_irq(virq, cpu, irqflags & IRQF_PERCPU);
+	irq = bind_virq_to_irq(xh, virq, cpu, irqflags & IRQF_PERCPU);
 	if (irq < 0)
 		return irq;
 	retval = request_irq(irq, handler, irqflags, devname, dev_id);
@@ -1080,7 +1098,8 @@ int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
 }
 EXPORT_SYMBOL_GPL(bind_virq_to_irqhandler);
 
-int bind_ipi_to_irqhandler(enum ipi_vector ipi,
+int bind_ipi_to_irqhandler(xenhost_t *xh,
+			   enum ipi_vector ipi,
 			   unsigned int cpu,
 			   irq_handler_t handler,
 			   unsigned long irqflags,
@@ -1089,7 +1108,7 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi,
 {
 	int irq, retval;
 
-	irq = bind_ipi_to_irq(ipi, cpu);
+	irq = bind_ipi_to_irq(xh, ipi, cpu);
 	if (irq < 0)
 		return irq;
 
@@ -1119,21 +1138,21 @@ EXPORT_SYMBOL_GPL(unbind_from_irqhandler);
  * @irq:irq bound to an event channel.
  * @priority: priority between XEN_IRQ_PRIORITY_MAX and XEN_IRQ_PRIORITY_MIN.
  */
-int xen_set_irq_priority(unsigned irq, unsigned priority)
+int xen_set_irq_priority(xenhost_t *xh, unsigned irq, unsigned priority)
 {
 	struct evtchn_set_priority set_priority;
 
 	set_priority.port = evtchn_from_irq(irq);
 	set_priority.priority = priority;
 
-	return HYPERVISOR_event_channel_op(EVTCHNOP_set_priority,
+	return hypervisor_event_channel_op(xh, EVTCHNOP_set_priority,
 					   &set_priority);
 }
 EXPORT_SYMBOL_GPL(xen_set_irq_priority);
 
-int evtchn_make_refcounted(unsigned int evtchn)
+int evtchn_make_refcounted(xenhost_t *xh, unsigned int evtchn)
 {
-	int irq = get_evtchn_to_irq(evtchn);
+	int irq = get_evtchn_to_irq(xh, evtchn);
 	struct irq_info *info;
 
 	if (irq == -1)
@@ -1152,18 +1171,18 @@ int evtchn_make_refcounted(unsigned int evtchn)
 }
 EXPORT_SYMBOL_GPL(evtchn_make_refcounted);
 
-int evtchn_get(unsigned int evtchn)
+int evtchn_get(xenhost_t *xh, unsigned int evtchn)
 {
 	int irq;
 	struct irq_info *info;
 	int err = -ENOENT;
 
-	if (evtchn >= xen_evtchn_max_channels())
+	if (evtchn >= xen_evtchn_max_channels(xh))
 		return -EINVAL;
 
 	mutex_lock(&irq_mapping_update_lock);
 
-	irq = get_evtchn_to_irq(evtchn);
+	irq = get_evtchn_to_irq(xh, evtchn);
 	if (irq == -1)
 		goto done;
 
@@ -1185,22 +1204,22 @@ int evtchn_get(unsigned int evtchn)
 }
 EXPORT_SYMBOL_GPL(evtchn_get);
 
-void evtchn_put(unsigned int evtchn)
+void evtchn_put(xenhost_t *xh, unsigned int evtchn)
 {
-	int irq = get_evtchn_to_irq(evtchn);
+	int irq = get_evtchn_to_irq(xh, evtchn);
 	if (WARN_ON(irq == -1))
 		return;
 	unbind_from_irq(irq);
 }
 EXPORT_SYMBOL_GPL(evtchn_put);
 
-void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector)
+void xen_send_IPI_one(xenhost_t *xh, unsigned int cpu, enum ipi_vector vector)
 {
 	int irq;
 
 #ifdef CONFIG_X86
 	if (unlikely(vector == XEN_NMI_VECTOR)) {
-		int rc =  HYPERVISOR_vcpu_op(VCPUOP_send_nmi, xen_vcpu_nr(xh_default, cpu),
+		int rc =  hypervisor_vcpu_op(xh, VCPUOP_send_nmi, xen_vcpu_nr(xh, cpu),
 					     NULL);
 		if (rc < 0)
 			printk(KERN_WARNING "Sending nmi to CPU%d failed (rc:%d)\n", cpu, rc);
@@ -1216,23 +1235,26 @@ static DEFINE_PER_CPU(unsigned, xed_nesting_count);
 
 static void __xen_evtchn_do_upcall(void)
 {
-	struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
 	int cpu = get_cpu();
 	unsigned count;
+	xenhost_t **xh;
 
-	do {
-		vcpu_info->evtchn_upcall_pending = 0;
+	for_each_xenhost(xh) {
+		struct vcpu_info *vcpu_info = (*xh)->xen_vcpu[cpu];
+		do {
+			vcpu_info->evtchn_upcall_pending = 0;
 
-		if (__this_cpu_inc_return(xed_nesting_count) - 1)
-			goto out;
+			if (__this_cpu_inc_return(xed_nesting_count) - 1)
+				goto out;
 
-		xen_evtchn_handle_events(cpu);
+			xen_evtchn_handle_events(*xh, cpu);
 
-		BUG_ON(!irqs_disabled());
+			BUG_ON(!irqs_disabled());
 
-		count = __this_cpu_read(xed_nesting_count);
-		__this_cpu_write(xed_nesting_count, 0);
-	} while (count != 1 || vcpu_info->evtchn_upcall_pending);
+			count = __this_cpu_read(xed_nesting_count);
+			__this_cpu_write(xed_nesting_count, 0);
+		} while (count != 1 || vcpu_info->evtchn_upcall_pending);
+	}
 
 out:
 
@@ -1275,16 +1297,16 @@ void rebind_evtchn_irq(int evtchn, int irq)
 	mutex_lock(&irq_mapping_update_lock);
 
 	/* After resume the irq<->evtchn mappings are all cleared out */
-	BUG_ON(get_evtchn_to_irq(evtchn) != -1);
+	BUG_ON(get_evtchn_to_irq(info->xh, evtchn) != -1);
 	/* Expect irq to have been bound before,
 	   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(info->xh, irq, evtchn);
 
 	mutex_unlock(&irq_mapping_update_lock);
 
-        bind_evtchn_to_cpu(evtchn, info->cpu);
+        bind_evtchn_to_cpu(info->xh, evtchn, info->cpu);
 	/* This will be deferred until interrupt is processed */
 	irq_set_affinity(irq, cpumask_of(info->cpu));
 
@@ -1293,7 +1315,7 @@ void rebind_evtchn_irq(int evtchn, int irq)
 }
 
 /* Rebind an evtchn so that it gets delivered to a specific cpu */
-int xen_rebind_evtchn_to_cpu(int evtchn, unsigned tcpu)
+int xen_rebind_evtchn_to_cpu(xenhost_t *xh, int evtchn, unsigned tcpu)
 {
 	struct evtchn_bind_vcpu bind_vcpu;
 	int masked;
@@ -1306,24 +1328,24 @@ int xen_rebind_evtchn_to_cpu(int evtchn, unsigned tcpu)
 
 	/* Send future instances of this interrupt to other vcpu. */
 	bind_vcpu.port = evtchn;
-	bind_vcpu.vcpu = xen_vcpu_nr(xh_default, tcpu);
+	bind_vcpu.vcpu = xen_vcpu_nr(xh, tcpu);
 
 	/*
 	 * Mask the event while changing the VCPU binding to prevent
 	 * it being delivered on an unexpected VCPU.
 	 */
-	masked = test_and_set_mask(evtchn);
+	masked = test_and_set_mask(xh, evtchn);
 
 	/*
 	 * If this fails, it usually just indicates that we're dealing with a
 	 * virq or IPI channel, which don't actually need to be rebound. Ignore
 	 * it, but don't do the xenlinux-level rebind in that case.
 	 */
-	if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
-		bind_evtchn_to_cpu(evtchn, tcpu);
+	if (hypervisor_event_channel_op(xh, EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
+		bind_evtchn_to_cpu(xh, evtchn, tcpu);
 
 	if (!masked)
-		unmask_evtchn(evtchn);
+		unmask_evtchn(xh, evtchn);
 
 	return 0;
 }
@@ -1333,7 +1355,10 @@ static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest,
 			    bool force)
 {
 	unsigned tcpu = cpumask_first_and(dest, cpu_online_mask);
-	int ret = xen_rebind_evtchn_to_cpu(evtchn_from_irq(data->irq), tcpu);
+	xenhost_t *xh = info_for_irq(data->irq)->xh;
+	int ret;
+
+	ret = xen_rebind_evtchn_to_cpu(xh, evtchn_from_irq(data->irq), tcpu);
 
 	if (!ret)
 		irq_data_update_effective_affinity(data, cpumask_of(tcpu));
@@ -1344,38 +1369,41 @@ static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest,
 static void enable_dynirq(struct irq_data *data)
 {
 	int evtchn = evtchn_from_irq(data->irq);
+	xenhost_t *xh = info_for_irq(data->irq)->xh;
 
 	if (VALID_EVTCHN(evtchn))
-		unmask_evtchn(evtchn);
+		unmask_evtchn(xh, evtchn);
 }
 
 static void disable_dynirq(struct irq_data *data)
 {
 	int evtchn = evtchn_from_irq(data->irq);
+	xenhost_t *xh = info_for_irq(data->irq)->xh;
 
 	if (VALID_EVTCHN(evtchn))
-		mask_evtchn(evtchn);
+		mask_evtchn(xh, evtchn);
 }
 
 static void ack_dynirq(struct irq_data *data)
 {
 	int evtchn = evtchn_from_irq(data->irq);
+	xenhost_t *xh = info_for_irq(data->irq)->xh;
 
 	if (!VALID_EVTCHN(evtchn))
 		return;
 
 	if (unlikely(irqd_is_setaffinity_pending(data)) &&
 	    likely(!irqd_irq_disabled(data))) {
-		int masked = test_and_set_mask(evtchn);
+		int masked = test_and_set_mask(xh, evtchn);
 
-		clear_evtchn(evtchn);
+		clear_evtchn(xh, evtchn);
 
 		irq_move_masked_irq(data);
 
 		if (!masked)
-			unmask_evtchn(evtchn);
+			unmask_evtchn(xh, evtchn);
 	} else
-		clear_evtchn(evtchn);
+		clear_evtchn(xh, evtchn);
 }
 
 static void mask_ack_dynirq(struct irq_data *data)
@@ -1387,15 +1415,16 @@ static void mask_ack_dynirq(struct irq_data *data)
 static int retrigger_dynirq(struct irq_data *data)
 {
 	unsigned int evtchn = evtchn_from_irq(data->irq);
+	xenhost_t *xh = info_for_irq(data->irq)->xh;
 	int masked;
 
 	if (!VALID_EVTCHN(evtchn))
 		return 0;
 
-	masked = test_and_set_mask(evtchn);
-	set_evtchn(evtchn);
+	masked = test_and_set_mask(xh, evtchn);
+	set_evtchn(xh, evtchn);
 	if (!masked)
-		unmask_evtchn(evtchn);
+		unmask_evtchn(xh, evtchn);
 
 	return 1;
 }
@@ -1442,24 +1471,26 @@ static void restore_cpu_virqs(unsigned int cpu)
 {
 	struct evtchn_bind_virq bind_virq;
 	int virq, irq, evtchn;
+	xenhost_t *xh;
 
 	for (virq = 0; virq < NR_VIRQS; virq++) {
 		if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1)
 			continue;
+		xh = info_for_irq(irq)->xh;
 
 		BUG_ON(virq_from_irq(irq) != virq);
 
 		/* Get a new binding from Xen. */
 		bind_virq.virq = virq;
 		bind_virq.vcpu = xen_vcpu_nr(xh_default, cpu);
-		if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+		if (hypervisor_event_channel_op(xh, EVTCHNOP_bind_virq,
 						&bind_virq) != 0)
 			BUG();
 		evtchn = bind_virq.port;
 
 		/* Record the new mapping. */
-		(void)xen_irq_info_virq_setup(cpu, irq, evtchn, virq);
-		bind_evtchn_to_cpu(evtchn, cpu);
+		(void)xen_irq_info_virq_setup(xh, cpu, irq, evtchn, virq);
+		bind_evtchn_to_cpu(xh, evtchn, cpu);
 	}
 }
 
@@ -1467,23 +1498,25 @@ static void restore_cpu_ipis(unsigned int cpu)
 {
 	struct evtchn_bind_ipi bind_ipi;
 	int ipi, irq, evtchn;
+	xenhost_t *xh;
 
 	for (ipi = 0; ipi < XEN_NR_IPIS; ipi++) {
 		if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1)
 			continue;
+		xh = info_for_irq(irq)->xh;
 
 		BUG_ON(ipi_from_irq(irq) != ipi);
 
 		/* Get a new binding from Xen. */
-		bind_ipi.vcpu = xen_vcpu_nr(xh_default, cpu);
-		if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
+		bind_ipi.vcpu = xen_vcpu_nr(xh, cpu);
+		if (hypervisor_event_channel_op(xh, EVTCHNOP_bind_ipi,
 						&bind_ipi) != 0)
 			BUG();
 		evtchn = bind_ipi.port;
 
 		/* Record the new mapping. */
-		(void)xen_irq_info_ipi_setup(cpu, irq, evtchn, ipi);
-		bind_evtchn_to_cpu(evtchn, cpu);
+		(void)xen_irq_info_ipi_setup(xh, cpu, irq, evtchn, ipi);
+		bind_evtchn_to_cpu(xh, evtchn, cpu);
 	}
 }
 
@@ -1491,26 +1524,29 @@ static void restore_cpu_ipis(unsigned int cpu)
 void xen_clear_irq_pending(int irq)
 {
 	int evtchn = evtchn_from_irq(irq);
+	xenhost_t *xh = info_for_irq(irq)->xh;
 
 	if (VALID_EVTCHN(evtchn))
-		clear_evtchn(evtchn);
+		clear_evtchn(xh, evtchn);
 }
 EXPORT_SYMBOL(xen_clear_irq_pending);
 void xen_set_irq_pending(int irq)
 {
 	int evtchn = evtchn_from_irq(irq);
+	xenhost_t *xh = info_for_irq(irq)->xh;
 
 	if (VALID_EVTCHN(evtchn))
-		set_evtchn(evtchn);
+		set_evtchn(xh, evtchn);
 }
 
 bool xen_test_irq_pending(int irq)
 {
 	int evtchn = evtchn_from_irq(irq);
+	xenhost_t *xh = info_for_irq(irq)->xh;
 	bool ret = false;
 
 	if (VALID_EVTCHN(evtchn))
-		ret = test_evtchn(evtchn);
+		ret = test_evtchn(xh, evtchn);
 
 	return ret;
 }
@@ -1520,10 +1556,13 @@ bool xen_test_irq_pending(int irq)
 void xen_poll_irq_timeout(int irq, u64 timeout)
 {
 	evtchn_port_t evtchn = evtchn_from_irq(irq);
+	xenhost_t *xh = info_for_irq(irq)->xh;
 
 	if (VALID_EVTCHN(evtchn)) {
 		struct sched_poll poll;
 
+		BUG_ON(xh->type != xenhost_r1);
+
 		poll.nr_ports = 1;
 		poll.timeout = timeout;
 		set_xen_guest_handle(poll.ports, &evtchn);
@@ -1665,26 +1704,30 @@ void xen_callback_vector(void) {}
 static bool fifo_events = true;
 module_param(fifo_events, bool, 0);
 
-void __init xen_init_IRQ(void)
+void xen_init_IRQ(xenhost_t *xh)
 {
 	int ret = -EINVAL;
 	unsigned int evtchn;
 
-	if (fifo_events)
-		ret = xen_evtchn_fifo_init();
 	if (ret < 0)
-		xen_evtchn_2l_init();
+		xen_evtchn_2l_init(xh);
 
-	evtchn_to_irq = kcalloc(EVTCHN_ROW(xen_evtchn_max_channels()),
-				sizeof(*evtchn_to_irq), GFP_KERNEL);
-	BUG_ON(!evtchn_to_irq);
+	xh->evtchn_to_irq = kcalloc(EVTCHN_ROW(xh, xen_evtchn_max_channels(xh)),
+				sizeof(*(xh->evtchn_to_irq)), GFP_KERNEL);
+	BUG_ON(!xh->evtchn_to_irq);
 
 	/* No event channels are 'live' right now. */
-	for (evtchn = 0; evtchn < xen_evtchn_nr_channels(); evtchn++)
-		mask_evtchn(evtchn);
+	for (evtchn = 0; evtchn < xen_evtchn_nr_channels(xh); evtchn++)
+		mask_evtchn(xh, evtchn);
 
 	pirq_needs_eoi = pirq_needs_eoi_flag;
 
+	/*
+	 * Callback vectors, HW irqs are only for xenhost_r1
+	 */
+	if (xh->type != xenhost_r1)
+		return;
+
 #ifdef CONFIG_X86
 	if (xen_pv_domain()) {
 		irq_ctx_init(smp_processor_id());
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
index eed766219dd0..38ce98f96fbb 100644
--- a/drivers/xen/events/events_fifo.c
+++ b/drivers/xen/events/events_fifo.c
@@ -324,7 +324,7 @@ static void consume_one_event(unsigned cpu,
 	q->head[priority] = head;
 }
 
-static void __evtchn_fifo_handle_events(unsigned cpu, bool drop)
+static void __evtchn_fifo_handle_events(xenhost_t *xh, unsigned cpu, bool drop)
 {
 	struct evtchn_fifo_control_block *control_block;
 	unsigned long ready;
diff --git a/drivers/xen/events/events_internal.h b/drivers/xen/events/events_internal.h
index 50c2050a1e32..9293c2593846 100644
--- a/drivers/xen/events/events_internal.h
+++ b/drivers/xen/events/events_internal.h
@@ -21,6 +21,7 @@ enum xen_irq_type {
 /*
  * Packed IRQ information:
  * type - enum xen_irq_type
+ * xh - xenhost_t *
  * event channel - irq->event channel mapping
  * cpu - cpu this event channel is bound to
  * index - type-specific information:
@@ -32,6 +33,7 @@ enum xen_irq_type {
  */
 struct irq_info {
 	struct list_head list;
+	xenhost_t *xh;
 	int refcnt;
 	enum xen_irq_type type;	/* type */
 	unsigned irq;
@@ -56,35 +58,32 @@ struct irq_info {
 #define PIRQ_MSI_GROUP	(1 << 2)
 
 struct evtchn_ops {
-	unsigned (*max_channels)(void);
-	unsigned (*nr_channels)(void);
+	unsigned (*max_channels)(xenhost_t *xh);
+	unsigned (*nr_channels)(xenhost_t *xh);
 
 	int (*setup)(struct irq_info *info);
 	void (*bind_to_cpu)(struct irq_info *info, unsigned cpu);
 
-	void (*clear_pending)(unsigned port);
-	void (*set_pending)(unsigned port);
-	bool (*is_pending)(unsigned port);
-	bool (*test_and_set_mask)(unsigned port);
-	void (*mask)(unsigned port);
-	void (*unmask)(unsigned port);
+	void (*clear_pending)(xenhost_t *xh, unsigned port);
+	void (*set_pending)(xenhost_t *xh, unsigned port);
+	bool (*is_pending)(xenhost_t *xh, unsigned port);
+	bool (*test_and_set_mask)(xenhost_t *xh, unsigned port);
+	void (*mask)(xenhost_t *xh, unsigned port);
+	void (*unmask)(xenhost_t *xh, unsigned port);
 
-	void (*handle_events)(unsigned cpu);
-	void (*resume)(void);
+	void (*handle_events)(xenhost_t *xh, unsigned cpu);
+	void (*resume)(xenhost_t *xh);
 };
 
-extern const struct evtchn_ops *evtchn_ops;
-
-extern int **evtchn_to_irq;
-int get_evtchn_to_irq(unsigned int evtchn);
+int get_evtchn_to_irq(xenhost_t *xh, unsigned int evtchn);
 
 struct irq_info *info_for_irq(unsigned irq);
 unsigned cpu_from_irq(unsigned irq);
-unsigned cpu_from_evtchn(unsigned int evtchn);
+unsigned cpu_from_evtchn(xenhost_t *xh, unsigned int evtchn);
 
-static inline unsigned xen_evtchn_max_channels(void)
+static inline unsigned xen_evtchn_max_channels(xenhost_t *xh)
 {
-	return evtchn_ops->max_channels();
+	return xh->evtchn_ops->max_channels(xh);
 }
 
 /*
@@ -93,59 +92,62 @@ static inline unsigned xen_evtchn_max_channels(void)
  */
 static inline int xen_evtchn_port_setup(struct irq_info *info)
 {
-	if (evtchn_ops->setup)
-		return evtchn_ops->setup(info);
+	if (info->xh->evtchn_ops->setup)
+		return info->xh->evtchn_ops->setup(info);
 	return 0;
 }
 
 static inline void xen_evtchn_port_bind_to_cpu(struct irq_info *info,
 					       unsigned cpu)
 {
-	evtchn_ops->bind_to_cpu(info, cpu);
+	info->xh->evtchn_ops->bind_to_cpu(info, cpu);
 }
 
-static inline void clear_evtchn(unsigned port)
+static inline void clear_evtchn(xenhost_t *xh, unsigned port)
 {
-	evtchn_ops->clear_pending(port);
+	xh->evtchn_ops->clear_pending(xh, port);
 }
 
-static inline void set_evtchn(unsigned port)
+static inline void set_evtchn(xenhost_t *xh, unsigned port)
 {
-	evtchn_ops->set_pending(port);
+	xh->evtchn_ops->set_pending(xh, port);
 }
 
-static inline bool test_evtchn(unsigned port)
+static inline bool test_evtchn(xenhost_t *xh, unsigned port)
 {
-	return evtchn_ops->is_pending(port);
+	return xh->evtchn_ops->is_pending(xh, port);
 }
 
-static inline bool test_and_set_mask(unsigned port)
+static inline bool test_and_set_mask(xenhost_t *xh, unsigned port)
 {
-	return evtchn_ops->test_and_set_mask(port);
+	return xh->evtchn_ops->test_and_set_mask(xh, port);
 }
 
-static inline void mask_evtchn(unsigned port)
+static inline void mask_evtchn(xenhost_t *xh, unsigned port)
 {
-	return evtchn_ops->mask(port);
+	return xh->evtchn_ops->mask(xh, port);
 }
 
-static inline void unmask_evtchn(unsigned port)
+static inline void unmask_evtchn(xenhost_t *xh, unsigned port)
 {
-	return evtchn_ops->unmask(port);
+	return xh->evtchn_ops->unmask(xh, port);
 }
 
-static inline void xen_evtchn_handle_events(unsigned cpu)
+static inline void xen_evtchn_handle_events(xenhost_t *xh, unsigned cpu)
 {
-	return evtchn_ops->handle_events(cpu);
+	return xh->evtchn_ops->handle_events(xh, cpu);
 }
 
 static inline void xen_evtchn_resume(void)
 {
-	if (evtchn_ops->resume)
-		evtchn_ops->resume();
+	xenhost_t **xh;
+
+	for_each_xenhost(xh)
+		if ((*xh)->evtchn_ops->resume)
+			(*xh)->evtchn_ops->resume(*xh);
 }
 
-void xen_evtchn_2l_init(void);
-int xen_evtchn_fifo_init(void);
+void xen_evtchn_2l_init(xenhost_t *xh);
+int xen_evtchn_fifo_init(xenhost_t *xh);
 
 #endif /* #ifndef __EVENTS_INTERNAL_H__ */
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index 66622109f2be..b868816874fd 100644
--- a/drivers/xen/evtchn.c
+++ b/drivers/xen/evtchn.c
@@ -292,7 +292,7 @@ static ssize_t evtchn_write(struct file *file, const char __user *buf,
 		evtchn = find_evtchn(u, port);
 		if (evtchn && !evtchn->enabled) {
 			evtchn->enabled = true;
-			enable_irq(irq_from_evtchn(port));
+			enable_irq(irq_from_evtchn(xh_default, port));
 		}
 	}
 
@@ -392,18 +392,18 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port)
 	if (rc < 0)
 		goto err;
 
-	rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, 0,
+	rc = bind_evtchn_to_irqhandler(xh_default, port, evtchn_interrupt, 0,
 				       u->name, evtchn);
 	if (rc < 0)
 		goto err;
 
-	rc = evtchn_make_refcounted(port);
+	rc = evtchn_make_refcounted(xh_default, port);
 	return rc;
 
 err:
 	/* bind failed, should close the port now */
 	close.port = port;
-	if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
+	if (hypervisor_event_channel_op(xh_default, EVTCHNOP_close, &close) != 0)
 		BUG();
 	del_evtchn(u, evtchn);
 	return rc;
@@ -412,7 +412,7 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port)
 static void evtchn_unbind_from_user(struct per_user_data *u,
 				    struct user_evtchn *evtchn)
 {
-	int irq = irq_from_evtchn(evtchn->port);
+	int irq = irq_from_evtchn(xh_default, evtchn->port);
 
 	BUG_ON(irq < 0);
 
@@ -429,7 +429,7 @@ static void evtchn_bind_interdom_next_vcpu(int evtchn)
 	struct irq_desc *desc;
 	unsigned long flags;
 
-	irq = irq_from_evtchn(evtchn);
+	irq = irq_from_evtchn(xh_default, evtchn);
 	desc = irq_to_desc(irq);
 
 	if (!desc)
@@ -447,7 +447,7 @@ static void evtchn_bind_interdom_next_vcpu(int evtchn)
 	this_cpu_write(bind_last_selected_cpu, selected_cpu);
 
 	/* unmask expects irqs to be disabled */
-	xen_rebind_evtchn_to_cpu(evtchn, selected_cpu);
+	xen_rebind_evtchn_to_cpu(xh_default, evtchn, selected_cpu);
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
@@ -549,7 +549,7 @@ static long evtchn_ioctl(struct file *file,
 			break;
 
 		rc = -EINVAL;
-		if (unbind.port >= xen_evtchn_nr_channels())
+		if (unbind.port >= xen_evtchn_nr_channels(xh_default))
 			break;
 
 		rc = -ENOTCONN;
@@ -557,7 +557,7 @@ static long evtchn_ioctl(struct file *file,
 		if (!evtchn)
 			break;
 
-		disable_irq(irq_from_evtchn(unbind.port));
+		disable_irq(irq_from_evtchn(xh_default, unbind.port));
 		evtchn_unbind_from_user(u, evtchn);
 		rc = 0;
 		break;
@@ -574,7 +574,7 @@ static long evtchn_ioctl(struct file *file,
 		rc = -ENOTCONN;
 		evtchn = find_evtchn(u, notify.port);
 		if (evtchn) {
-			notify_remote_via_evtchn(notify.port);
+			notify_remote_via_evtchn(xh_default, notify.port);
 			rc = 0;
 		}
 		break;
@@ -676,7 +676,7 @@ static int evtchn_release(struct inode *inode, struct file *filp)
 		struct user_evtchn *evtchn;
 
 		evtchn = rb_entry(node, struct user_evtchn, node);
-		disable_irq(irq_from_evtchn(evtchn->port));
+		disable_irq(irq_from_evtchn(xh_default, evtchn->port));
 		evtchn_unbind_from_user(u, evtchn);
 	}
 
diff --git a/drivers/xen/fallback.c b/drivers/xen/fallback.c
index ae81cf75ae5f..9f54fb8cf96d 100644
--- a/drivers/xen/fallback.c
+++ b/drivers/xen/fallback.c
@@ -2,6 +2,7 @@
 #include <linux/string.h>
 #include <linux/bug.h>
 #include <linux/export.h>
+#include <xen/interface/xen.h>
 #include <asm/hypervisor.h>
 #include <asm/xen/hypercall.h>
 
diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c
index 3fa40c723e8e..e07823886fa8 100644
--- a/drivers/xen/gntalloc.c
+++ b/drivers/xen/gntalloc.c
@@ -189,8 +189,8 @@ static void __del_gref(struct gntalloc_gref *gref)
 		kunmap(gref->page);
 	}
 	if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT) {
-		notify_remote_via_evtchn(gref->notify.event);
-		evtchn_put(gref->notify.event);
+		notify_remote_via_evtchn(xh_default, gref->notify.event);
+		evtchn_put(xh_default, gref->notify.event);
 	}
 
 	gref->notify.flags = 0;
@@ -418,14 +418,14 @@ static long gntalloc_ioctl_unmap_notify(struct gntalloc_file_private_data *priv,
 	 * reference to that event channel.
 	 */
 	if (op.action & UNMAP_NOTIFY_SEND_EVENT) {
-		if (evtchn_get(op.event_channel_port)) {
+		if (evtchn_get(xh_default, op.event_channel_port)) {
 			rc = -EINVAL;
 			goto unlock_out;
 		}
 	}
 
 	if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT)
-		evtchn_put(gref->notify.event);
+		evtchn_put(xh_default, gref->notify.event);
 
 	gref->notify.flags = op.action;
 	gref->notify.pgoff = pgoff;
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 5efc5eee9544..0f0c951cd5b1 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -247,8 +247,8 @@ void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map)
 	atomic_sub(map->count, &pages_mapped);
 
 	if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) {
-		notify_remote_via_evtchn(map->notify.event);
-		evtchn_put(map->notify.event);
+		notify_remote_via_evtchn(xh_default, map->notify.event);
+		evtchn_put(xh_default, map->notify.event);
 	}
 
 	if (populate_freeable_maps && priv) {
@@ -790,7 +790,7 @@ static long gntdev_ioctl_notify(struct gntdev_priv *priv, void __user *u)
 	 * reference to that event channel.
 	 */
 	if (op.action & UNMAP_NOTIFY_SEND_EVENT) {
-		if (evtchn_get(op.event_channel_port))
+		if (evtchn_get(xh_default, op.event_channel_port))
 			return -EINVAL;
 	}
 
@@ -829,7 +829,7 @@ static long gntdev_ioctl_notify(struct gntdev_priv *priv, void __user *u)
 
 	/* Drop the reference to the event channel we did not save in the map */
 	if (out_flags & UNMAP_NOTIFY_SEND_EVENT)
-		evtchn_put(out_event);
+		evtchn_put(xh_default, out_event);
 
 	return rc;
 }
diff --git a/drivers/xen/mcelog.c b/drivers/xen/mcelog.c
index b8bf61abb65b..45be85960f53 100644
--- a/drivers/xen/mcelog.c
+++ b/drivers/xen/mcelog.c
@@ -378,7 +378,7 @@ static int bind_virq_for_mce(void)
 		return ret;
 	}
 
-	ret  = bind_virq_to_irqhandler(VIRQ_MCA, 0,
+	ret  = bind_virq_to_irqhandler(xh_default, VIRQ_MCA, 0,
 				       xen_mce_interrupt, 0, "mce", NULL);
 	if (ret < 0) {
 		pr_err("Failed to bind virq\n");
diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c
index cdc6daa7a9f6..d0807f8fbd8b 100644
--- a/drivers/xen/pcpu.c
+++ b/drivers/xen/pcpu.c
@@ -387,7 +387,7 @@ static int __init xen_pcpu_init(void)
 	if (!xen_initial_domain())
 		return -ENODEV;
 
-	irq = bind_virq_to_irqhandler(VIRQ_PCPU_STATE, 0,
+	irq = bind_virq_to_irqhandler(xh_default, VIRQ_PCPU_STATE, 0,
 				      xen_pcpu_interrupt, 0,
 				      "xen-pcpu", NULL);
 	if (irq < 0) {
diff --git a/drivers/xen/preempt.c b/drivers/xen/preempt.c
index 08cb419eb4e6..b5f16a98414b 100644
--- a/drivers/xen/preempt.c
+++ b/drivers/xen/preempt.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/sched.h>
+#include <xen/interface/xen.h>
 #include <xen/xen-ops.h>
 
 #ifndef CONFIG_PREEMPT
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index b24ddac1604b..b5541f862720 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -27,6 +27,7 @@
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/tlb.h>
+#include <xen/interface/xen.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
 
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c
index 9d314bba7c4e..005a898e7a23 100644
--- a/drivers/xen/sys-hypervisor.c
+++ b/drivers/xen/sys-hypervisor.c
@@ -13,12 +13,12 @@
 #include <linux/kobject.h>
 #include <linux/err.h>
 
+#include <xen/interface/xen.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
 
 #include <xen/xen.h>
 #include <xen/xenbus.h>
-#include <xen/interface/xen.h>
 #include <xen/interface/version.h>
 #ifdef CONFIG_XEN_HAVE_VPMU
 #include <xen/interface/xenpmu.h>
diff --git a/drivers/xen/time.c b/drivers/xen/time.c
index feee74bbab0a..73916766dcac 100644
--- a/drivers/xen/time.c
+++ b/drivers/xen/time.c
@@ -8,13 +8,13 @@
 #include <linux/gfp.h>
 #include <linux/slab.h>
 
+#include <xen/interface/xen.h>
 #include <asm/paravirt.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
 
 #include <xen/events.h>
 #include <xen/features.h>
-#include <xen/interface/xen.h>
 #include <xen/interface/vcpu.h>
 #include <xen/xen-ops.h>
 
diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c
index 581c4e1a8b82..b95dd65f3872 100644
--- a/drivers/xen/xen-pciback/xenbus.c
+++ b/drivers/xen/xen-pciback/xenbus.c
@@ -123,7 +123,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(
+	err = bind_interdomain_evtchn_to_irqhandler(xh_default,
 		pdev->xdev->otherend_id, remote_evtchn, xen_pcibk_handle_event,
 		0, DRV_NAME, pdev);
 	if (err < 0) {
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index c9e23a126218..8702b1ac92a8 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -54,8 +54,9 @@
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
 
+
+#include <xen/interface/xen.h>
 #include <asm/hypervisor.h>
-
 #include <xen/xen.h>
 #include <xen/balloon.h>
 #include <xen/events.h>
@@ -829,7 +830,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(info->domid, evtchn);
+	err = bind_interdomain_evtchn_to_irq(xh_default, info->domid, evtchn);
 	if (err < 0)
 		goto unmap_page;
 
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index e17ca8156171..f0cf47765726 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -36,9 +36,9 @@
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
 #include <linux/export.h>
-#include <asm/xen/hypervisor.h>
 #include <xen/page.h>
 #include <xen/interface/xen.h>
+#include <asm/xen/hypervisor.h>
 #include <xen/interface/event_channel.h>
 #include <xen/balloon.h>
 #include <xen/events.h>
diff --git a/drivers/xen/xenbus/xenbus_comms.c b/drivers/xen/xenbus/xenbus_comms.c
index d239fc3c5e3d..acbc366c1717 100644
--- a/drivers/xen/xenbus/xenbus_comms.c
+++ b/drivers/xen/xenbus/xenbus_comms.c
@@ -151,7 +151,7 @@ static int xb_write(const void *data, unsigned int len)
 
 		/* Implies mb(): other side will see the updated producer. */
 		if (prod <= intf->req_cons)
-			notify_remote_via_evtchn(xen_store_evtchn);
+			notify_remote_via_evtchn(xh_default, xen_store_evtchn);
 	}
 
 	return bytes;
@@ -204,7 +204,7 @@ static int xb_read(void *data, unsigned int len)
 
 		/* Implies mb(): other side will see the updated consumer. */
 		if (intf->rsp_prod - cons >= XENSTORE_RING_SIZE)
-			notify_remote_via_evtchn(xen_store_evtchn);
+			notify_remote_via_evtchn(xh_default, xen_store_evtchn);
 	}
 
 	return bytes;
@@ -461,7 +461,7 @@ int xb_init_comms(void)
 	} else {
 		int err;
 
-		err = bind_evtchn_to_irqhandler(xen_store_evtchn, wake_waiting,
+		err = bind_evtchn_to_irqhandler(xh_default, xen_store_evtchn, wake_waiting,
 						0, "xenbus", &xb_waitq);
 		if (err < 0) {
 			pr_err("request irq failed %i\n", err);
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 5b471889d723..049bd511f36e 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -52,6 +52,7 @@
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <xen/interface/xen.h>
 #include <asm/xen/hypervisor.h>
 
 #include <xen/xen.h>
diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c
index b0bed4faf44c..d3c53a9db5e3 100644
--- a/drivers/xen/xenbus/xenbus_probe_backend.c
+++ b/drivers/xen/xenbus/xenbus_probe_backend.c
@@ -48,6 +48,7 @@
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <xen/interface/xen.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/hypervisor.h>
 #include <xen/xenbus.h>
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c
index 07896f4b2736..3edab7cc03c3 100644
--- a/drivers/xen/xenbus/xenbus_probe_frontend.c
+++ b/drivers/xen/xenbus/xenbus_probe_frontend.c
@@ -19,6 +19,7 @@
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <xen/interface/xen.h>
 #include <asm/xen/hypervisor.h>
 #include <xen/xenbus.h>
 #include <xen/events.h>
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index 3236d1b1fa01..74c2b9416b88 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -46,6 +46,7 @@
 #include <linux/reboot.h>
 #include <linux/rwsem.h>
 #include <linux/mutex.h>
+#include <xen/interface/xen.h>
 #include <asm/xen/hypervisor.h>
 #include <xen/xenbus.h>
 #include <xen/xen.h>
diff --git a/include/xen/events.h b/include/xen/events.h
index a48897199975..138dbbbefc6d 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -11,27 +11,30 @@
 #include <asm/xen/hypercall.h>
 #include <asm/xen/events.h>
 
-unsigned xen_evtchn_nr_channels(void);
+unsigned xen_evtchn_nr_channels(xenhost_t *xh);
 
-int bind_evtchn_to_irq(unsigned int evtchn);
-int bind_evtchn_to_irqhandler(unsigned int evtchn,
+int bind_evtchn_to_irq(xenhost_t *xh, unsigned int evtchn);
+int bind_evtchn_to_irqhandler(xenhost_t *xh, unsigned int evtchn,
 			      irq_handler_t handler,
 			      unsigned long irqflags, const char *devname,
 			      void *dev_id);
-int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu);
-int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
+int bind_virq_to_irq(xenhost_t *xh, unsigned int virq, unsigned int cpu, bool percpu);
+int bind_virq_to_irqhandler(xenhost_t *xh, unsigned int virq, unsigned int cpu,
 			    irq_handler_t handler,
 			    unsigned long irqflags, const char *devname,
 			    void *dev_id);
-int bind_ipi_to_irqhandler(enum ipi_vector ipi,
+int bind_ipi_to_irqhandler(xenhost_t *xh,
+			   enum ipi_vector ipi,
 			   unsigned int cpu,
 			   irq_handler_t handler,
 			   unsigned long irqflags,
 			   const char *devname,
 			   void *dev_id);
-int bind_interdomain_evtchn_to_irq(unsigned int remote_domain,
+int bind_interdomain_evtchn_to_irq(xenhost_t *xh,
+				   unsigned int remote_domain,
 				   unsigned int remote_port);
-int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
+int bind_interdomain_evtchn_to_irqhandler(xenhost_t *xh,
+					  unsigned int remote_domain,
 					  unsigned int remote_port,
 					  irq_handler_t handler,
 					  unsigned long irqflags,
@@ -48,23 +51,23 @@ void unbind_from_irqhandler(unsigned int irq, void *dev_id);
 #define XEN_IRQ_PRIORITY_MAX     EVTCHN_FIFO_PRIORITY_MAX
 #define XEN_IRQ_PRIORITY_DEFAULT EVTCHN_FIFO_PRIORITY_DEFAULT
 #define XEN_IRQ_PRIORITY_MIN     EVTCHN_FIFO_PRIORITY_MIN
-int xen_set_irq_priority(unsigned irq, unsigned priority);
+int xen_set_irq_priority(xenhost_t *xh, unsigned irq, unsigned priority);
 
 /*
  * Allow extra references to event channels exposed to userspace by evtchn
  */
-int evtchn_make_refcounted(unsigned int evtchn);
-int evtchn_get(unsigned int evtchn);
-void evtchn_put(unsigned int evtchn);
+int evtchn_make_refcounted(xenhost_t *xh, unsigned int evtchn);
+int evtchn_get(xenhost_t *xh, unsigned int evtchn);
+void evtchn_put(xenhost_t *xh, unsigned int evtchn);
 
-void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector);
+void xen_send_IPI_one(xenhost_t *xh, unsigned int cpu, enum ipi_vector vector);
 void rebind_evtchn_irq(int evtchn, int irq);
-int xen_rebind_evtchn_to_cpu(int evtchn, unsigned tcpu);
+int xen_rebind_evtchn_to_cpu(xenhost_t *xh, int evtchn, unsigned tcpu);
 
-static inline void notify_remote_via_evtchn(int port)
+static inline void notify_remote_via_evtchn(xenhost_t *xh, int port)
 {
 	struct evtchn_send send = { .port = port };
-	(void)HYPERVISOR_event_channel_op(EVTCHNOP_send, &send);
+	(void)hypervisor_event_channel_op(xh, EVTCHNOP_send, &send);
 }
 
 void notify_remote_via_irq(int irq);
@@ -85,7 +88,7 @@ void xen_poll_irq(int irq);
 void xen_poll_irq_timeout(int irq, u64 timeout);
 
 /* Determine the IRQ which is bound to an event channel */
-unsigned irq_from_evtchn(unsigned int evtchn);
+unsigned irq_from_evtchn(xenhost_t *xh,unsigned int evtchn);
 int irq_from_virq(unsigned int cpu, unsigned int virq);
 unsigned int evtchn_from_irq(unsigned irq);
 
@@ -101,14 +104,14 @@ void xen_evtchn_do_upcall(struct pt_regs *regs);
 void xen_hvm_evtchn_do_upcall(void);
 
 /* Bind a pirq for a physical interrupt to an irq. */
-int xen_bind_pirq_gsi_to_irq(unsigned gsi,
+int xen_bind_pirq_gsi_to_irq(xenhost_t *xh, unsigned gsi,
 			     unsigned pirq, int shareable, char *name);
 
 #ifdef CONFIG_PCI_MSI
 /* Allocate a pirq for a MSI style physical interrupt. */
-int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc);
+int xen_allocate_pirq_msi(xenhost_t *xh, struct pci_dev *dev, struct msi_desc *msidesc);
 /* Bind an PSI pirq to an irq. */
-int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
+int xen_bind_pirq_msi_to_irq(xenhost_t *xh, struct pci_dev *dev, struct msi_desc *msidesc,
 			     int pirq, int nvec, const char *name, domid_t domid);
 #endif
 
@@ -128,5 +131,5 @@ int xen_irq_from_gsi(unsigned gsi);
 int xen_test_irq_shared(int irq);
 
 /* initialize Xen IRQ subsystem */
-void xen_init_IRQ(void);
+void xen_init_IRQ(xenhost_t *xh);
 #endif	/* _XEN_EVENTS_H */
diff --git a/include/xen/xenhost.h b/include/xen/xenhost.h
index f6092a8987f1..c9dabf739ff8 100644
--- a/include/xen/xenhost.h
+++ b/include/xen/xenhost.h
@@ -112,6 +112,23 @@ typedef struct {
 		 */
 		uint32_t xen_vcpu_id[NR_CPUS];
 	};
+
+	/*
+	 * evtchn: get init'd via x86_init.irqs.intr_init (xen_init_IRQ()).
+	 *
+	 * The common functionality for xenhost_* provided by xen_init_IRQ()
+	 * is the mapping between evtchn <-> irq.
+	 *
+	 * For all three of xenhost_r0/r1 and r2, post-init the evtchn logic
+	 * should just work using the evtchn_to_irq mapping and the vcpu_info,
+	 * shared_info state.
+	 * (Plus some state private to evtchn_2l/evtchn_fifo which for now
+	 * is defined locally.)
+	 */
+	struct {
+		const struct evtchn_ops *evtchn_ops;
+		int **evtchn_to_irq;
+	};
 } xenhost_t;
 
 typedef struct xenhost_ops {
-- 
2.20.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply index

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-09 17:25 [Xen-devel] [RFC PATCH 00/16] xenhost support Ankur Arora
2019-05-09 17:25 ` [Xen-devel] [RFC PATCH 01/16] x86/xen: add xenhost_t interface Ankur Arora
2019-06-07 15:04   ` Juergen Gross
2019-06-11  7:16     ` Ankur Arora
2019-06-14 11:52       ` Juergen Gross
2019-05-09 17:25 ` Ankur Arora
2019-05-09 17:25 ` [RFC PATCH 02/16] x86/xen: cpuid support in xenhost_t Ankur Arora
2019-05-09 17:25   ` [Xen-devel] " Ankur Arora
2019-06-12 21:09   ` Andrew Cooper
2019-05-09 17:25 ` [Xen-devel] [RFC PATCH 03/16] x86/xen: make hypercall_page generic Ankur Arora
2019-05-09 17:25 ` Ankur Arora
2019-05-09 17:25 ` [RFC PATCH 04/16] x86/xen: hypercall support for xenhost_t Ankur Arora
2019-05-09 17:25 ` [Xen-devel] " Ankur Arora
2019-06-12 21:15   ` Andrew Cooper
2019-06-14  7:20     ` Ankur Arora
2019-06-14  7:35       ` Juergen Gross
2019-06-14  8:00         ` Andrew Cooper
2019-05-09 17:25 ` [RFC PATCH 05/16] x86/xen: add feature support in xenhost_t Ankur Arora
2019-05-09 17:25 ` [Xen-devel] " Ankur Arora
2019-05-09 17:25 ` [Xen-devel] [RFC PATCH 06/16] x86/xen: add shared_info support to xenhost_t Ankur Arora
2019-06-07 15:08   ` Juergen Gross
2019-06-08  5:01     ` Ankur Arora
2019-05-09 17:25 ` Ankur Arora
2019-05-09 17:25 ` [RFC PATCH 07/16] x86/xen: make vcpu_info part of xenhost_t Ankur Arora
2019-05-09 17:25   ` [Xen-devel] " Ankur Arora
2019-06-14 11:53   ` Juergen Gross
2019-06-17  6:28     ` Ankur Arora
2019-05-09 17:25 ` [RFC PATCH 08/16] x86/xen: irq/upcall handling with multiple xenhosts Ankur Arora
2019-05-09 17:25 ` [Xen-devel] " Ankur Arora
2019-06-14 12:01   ` Juergen Gross
2019-05-09 17:25 ` Ankur Arora [this message]
2019-05-09 17:25 ` [Xen-devel] [RFC PATCH 09/16] xen/evtchn: support evtchn in xenhost_t Ankur Arora
2019-06-14 12:04   ` Juergen Gross
2019-06-17  6:09     ` Ankur Arora
2019-05-09 17:25 ` [RFC PATCH 10/16] xen/balloon: support ballooning " Ankur Arora
2019-05-09 17:25 ` [Xen-devel] " Ankur Arora
2019-06-17  9:28   ` Juergen Gross
2019-06-19  2:24     ` Ankur Arora
2019-05-09 17:25 ` [RFC PATCH 11/16] xen/grant-table: make grant-table xenhost aware Ankur Arora
2019-05-09 17:25   ` [Xen-devel] " Ankur Arora
2019-06-17  9:36   ` Juergen Gross
2019-06-19  2:25     ` Ankur Arora
2019-05-09 17:25 ` [RFC PATCH 12/16] xen/xenbus: support xenbus frontend/backend with xenhost_t Ankur Arora
2019-05-09 17:25 ` [Xen-devel] " Ankur Arora
2019-06-17  9:50   ` Juergen Gross
2019-06-19  2:38     ` Ankur Arora
2019-05-09 17:25 ` [Xen-devel] [RFC PATCH 13/16] drivers/xen: gnttab, evtchn, xenbus API changes Ankur Arora
2019-06-17 10:07   ` Juergen Gross
2019-06-19  2:55     ` Ankur Arora
2019-05-09 17:25 ` Ankur Arora
2019-05-09 17:25 ` [Xen-devel] [RFC PATCH 14/16] xen/blk: " Ankur Arora
2019-06-17 10:14   ` Juergen Gross
2019-06-19  2:59     ` Ankur Arora
2019-05-09 17:25 ` Ankur Arora
2019-05-09 17:25 ` [RFC PATCH 15/16] xen/net: " Ankur Arora
2019-05-09 17:25 ` [Xen-devel] " Ankur Arora
2019-06-17 10:14   ` Juergen Gross
2019-05-09 17:25 ` [Xen-devel] [RFC PATCH 16/16] xen/grant-table: host_addr fixup in mapping on xenhost_r0 Ankur Arora
2019-06-17 10:55   ` Juergen Gross
2019-06-19  3:02     ` Ankur Arora
2019-05-09 17:25 ` Ankur Arora
2019-06-07 14:51 ` [Xen-devel] [RFC PATCH 00/16] xenhost support Juergen Gross
2019-06-07 15:22   ` Joao Martins
2019-06-07 16:21     ` Juergen Gross
2019-06-08  5:50       ` Ankur Arora
2019-06-08  5:33   ` Ankur Arora

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='20190509172540.12398-10-ankur.a.arora__12801.2626942777$1557422821$gmane$org@oracle.com' \
    --to=ankur.a.arora@oracle.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=jgross@suse.com \
    --cc=joao.m.martins@oracle.com \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Xen-Devel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/xen-devel/0 xen-devel/git/0.git
	git clone --mirror https://lore.kernel.org/xen-devel/1 xen-devel/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 xen-devel xen-devel/ https://lore.kernel.org/xen-devel \
		xen-devel@lists.xenproject.org xen-devel@lists.xen.org xen-devel@archiver.kernel.org
	public-inbox-index xen-devel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.xenproject.lists.xen-devel


AGPL code for this site: git clone https://public-inbox.org/ public-inbox