[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [RFC PATCH 09/16] xen/evtchn: support evtchn in xenhost_t



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@xxxxxxxxxx>
---
 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@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.