All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andre Przywara <andre.przywara@arm.com>
To: Stefano Stabellini <sstabellini@kernel.org>,
	Julien Grall <julien.grall@arm.com>
Cc: xen-devel@lists.xenproject.org, Vijay Kilari <vijay.kilari@gmail.com>
Subject: [PATCH 08/28] ARM: GICv3 ITS: introduce host LPI array
Date: Mon, 30 Jan 2017 18:31:33 +0000	[thread overview]
Message-ID: <20170130183153.28566-9-andre.przywara@arm.com> (raw)
In-Reply-To: <20170130183153.28566-1-andre.przywara@arm.com>

The number of LPIs on a host can be potentially huge (millions),
although in practise will be mostly reasonable. So prematurely allocating
an array of struct irq_desc's for each LPI is not an option.
However Xen itself does not care about LPIs, as every LPI will be injected
into a guest (Dom0 for now).
Create a dense data structure (8 Bytes) for each LPI which holds just
enough information to determine the virtual IRQ number and the VCPU into
which the LPI needs to be injected.
Also to not artificially limit the number of LPIs, we create a 2-level
table for holding those structures.
This patch introduces functions to initialize these tables and to
create, lookup and destroy entries for a given LPI.
We allocate and access LPI information in a way that does not require
a lock.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 xen/arch/arm/gic-v3-its.c        |  80 ++++++++++++++++-
 xen/arch/arm/gic-v3-lpi.c        | 187 ++++++++++++++++++++++++++++++++++++++-
 xen/include/asm-arm/atomic.h     |   6 +-
 xen/include/asm-arm/gic.h        |   5 ++
 xen/include/asm-arm/gic_v3_its.h |   9 ++
 5 files changed, 282 insertions(+), 5 deletions(-)

diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
index 4a3a394..f073ab5 100644
--- a/xen/arch/arm/gic-v3-its.c
+++ b/xen/arch/arm/gic-v3-its.c
@@ -83,6 +83,20 @@ static int its_send_cmd_sync(struct host_its *its, int cpu)
     return its_send_command(its, cmd);
 }
 
+static int its_send_cmd_mapti(struct host_its *its,
+                              uint32_t deviceid, uint32_t eventid,
+                              uint32_t pintid, uint16_t icid)
+{
+    uint64_t cmd[4];
+
+    cmd[0] = GITS_CMD_MAPTI | ((uint64_t)deviceid << 32);
+    cmd[1] = eventid | ((uint64_t)pintid << 32);
+    cmd[2] = icid;
+    cmd[3] = 0x00;
+
+    return its_send_command(its, cmd);
+}
+
 static int its_send_cmd_mapc(struct host_its *its, int collection_id, int cpu)
 {
     uint64_t cmd[4];
@@ -111,6 +125,19 @@ static int its_send_cmd_mapd(struct host_its *its, uint32_t deviceid,
     return its_send_command(its, cmd);
 }
 
+static int its_send_cmd_inv(struct host_its *its,
+                            uint32_t deviceid, uint32_t eventid)
+{
+    uint64_t cmd[4];
+
+    cmd[0] = GITS_CMD_INV | ((uint64_t)deviceid << 32);
+    cmd[1] = eventid;
+    cmd[2] = 0x00;
+    cmd[3] = 0x00;
+
+    return its_send_command(its, cmd);
+}
+
 /* Set up the (1:1) collection mapping for the given host CPU. */
 int gicv3_its_setup_collection(int cpu)
 {
@@ -359,13 +386,47 @@ int gicv3_its_init(struct host_its *hw_its)
 
 static void remove_mapped_guest_device(struct its_devices *dev)
 {
+    int i;
+
     if ( dev->hw_its )
         its_send_cmd_mapd(dev->hw_its, dev->host_devid, 0, 0, false);
 
+    for ( i = 0; i < dev->eventids / 32; i++ )
+        gicv3_free_host_lpi_block(dev->hw_its, dev->host_lpis[i]);
+
     xfree(dev->itt_addr);
+    xfree(dev->host_lpis);
     xfree(dev);
 }
 
+/*
+ * On the host ITS @its, map @nr_events consecutive LPIs.
+ * The mapping connects a device @devid and event @eventid pair to LPI @lpi,
+ * increasing both @eventid and @lpi to cover the number of requested LPIs.
+ */
+int gicv3_its_map_host_events(struct host_its *its,
+                              int devid, int eventid, int lpi,
+                              int nr_events)
+{
+    int i, ret;
+
+    for ( i = 0; i < nr_events; i++ )
+    {
+        ret = its_send_cmd_mapti(its, devid, eventid + i, lpi + i, 0);
+        if ( ret )
+            return ret;
+        ret = its_send_cmd_inv(its, devid, eventid + i);
+        if ( ret )
+            return ret;
+    }
+
+    ret = its_send_cmd_sync(its, 0);
+    if ( ret )
+        return ret;
+
+    return 0;
+}
+
 int gicv3_its_map_guest_device(struct domain *d, int host_devid,
                                int guest_devid, int bits, bool valid)
 {
@@ -373,7 +434,7 @@ int gicv3_its_map_guest_device(struct domain *d, int host_devid,
     struct its_devices *dev, *temp;
     struct rb_node **new = &d->arch.vgic.its_devices.rb_node, *parent = NULL;
     struct host_its *hw_its;
-    int ret;
+    int ret, i;
 
     /* check for already existing mappings */
     spin_lock(&d->arch.vgic.its_devices_lock);
@@ -430,10 +491,19 @@ int gicv3_its_map_guest_device(struct domain *d, int host_devid,
         goto out_unlock;
     }
 
+    dev->host_lpis = xzalloc_array(uint32_t, BIT(bits) / 32);
+    if ( !dev->host_lpis )
+    {
+        xfree(dev);
+        xfree(itt_addr);
+        return -ENOMEM;
+    }
+
     ret = its_send_cmd_mapd(hw_its, host_devid, bits - 1,
                             virt_to_maddr(itt_addr), true);
     if ( ret )
     {
+        xfree(dev->host_lpis);
         xfree(itt_addr);
         xfree(dev);
         goto out_unlock;
@@ -450,6 +520,14 @@ int gicv3_its_map_guest_device(struct domain *d, int host_devid,
 
     spin_unlock(&d->arch.vgic.its_devices_lock);
 
+    /*
+     * Map all host LPIs within this device already. We can't afford to queue
+     * any host ITS commands later on during the guest's runtime.
+     */
+    for ( i = 0; i < BIT(bits) / 32; i++ )
+        dev->host_lpis[i] = gicv3_allocate_host_lpi_block(hw_its, d, host_devid,
+                                                          i * 32);
+
     return 0;
 
 out_unlock:
diff --git a/xen/arch/arm/gic-v3-lpi.c b/xen/arch/arm/gic-v3-lpi.c
index 5911b91..8f6e7f3 100644
--- a/xen/arch/arm/gic-v3-lpi.c
+++ b/xen/arch/arm/gic-v3-lpi.c
@@ -18,16 +18,34 @@
 
 #include <xen/config.h>
 #include <xen/lib.h>
-#include <xen/mm.h>
+#include <xen/sched.h>
+#include <xen/err.h>
+#include <xen/sched.h>
 #include <xen/sizes.h>
+#include <asm/atomic.h>
+#include <asm/domain.h>
+#include <asm/io.h>
 #include <asm/gic.h>
 #include <asm/gic_v3_defs.h>
 #include <asm/gic_v3_its.h>
 
+/* LPIs on the host always go to a guest, so no struct irq_desc for them. */
+union host_lpi {
+    uint64_t data;
+    struct {
+        uint32_t virt_lpi;
+        uint16_t dom_id;
+        uint16_t vcpu_id;
+    };
+};
+
 /* Global state */
 static struct {
     uint8_t *lpi_property;
+    union host_lpi **host_lpis;
     unsigned int host_lpi_bits;
+    /* Protects allocation and deallocation of host LPIs, but not the access */
+    spinlock_t host_lpis_lock;
 } lpi_data;
 
 /* Physical redistributor address */
@@ -38,6 +56,19 @@ static DEFINE_PER_CPU(int, redist_id);
 static DEFINE_PER_CPU(void *, pending_table);
 
 #define MAX_PHYS_LPIS   (BIT_ULL(lpi_data.host_lpi_bits) - LPI_OFFSET)
+#define HOST_LPIS_PER_PAGE      (PAGE_SIZE / sizeof(union host_lpi))
+
+static union host_lpi *gic_get_host_lpi(uint32_t plpi)
+{
+    if ( !is_lpi(plpi) || plpi >= MAX_PHYS_LPIS + LPI_OFFSET )
+        return NULL;
+
+    plpi -= LPI_OFFSET;
+    if ( !lpi_data.host_lpis[plpi / HOST_LPIS_PER_PAGE] )
+        return NULL;
+
+    return &lpi_data.host_lpis[plpi / HOST_LPIS_PER_PAGE][plpi % HOST_LPIS_PER_PAGE];
+}
 
 /* Stores this redistributor's physical address and ID in a per-CPU variable */
 void gicv3_set_redist_address(paddr_t address, int redist_id)
@@ -130,15 +161,169 @@ uint64_t gicv3_lpi_get_proptable(void)
 static unsigned int max_lpi_bits = CONFIG_MAX_PHYS_LPI_BITS;
 integer_param("max_lpi_bits", max_lpi_bits);
 
+/*
+ * Allocate the 2nd level array for host LPIs. This one holds pointers
+ * to the page with the actual "union host_lpi" entries. Our LPI limit
+ * avoids excessive memory usage.
+ */
 int gicv3_lpi_init_host_lpis(unsigned int hw_lpi_bits)
 {
+    int nr_lpi_ptrs;
+
+    BUILD_BUG_ON(sizeof(union host_lpi) > sizeof(unsigned long));
+
     lpi_data.host_lpi_bits = min(hw_lpi_bits, max_lpi_bits);
 
+    spin_lock_init(&lpi_data.host_lpis_lock);
+
+    nr_lpi_ptrs = MAX_PHYS_LPIS / (PAGE_SIZE / sizeof(union host_lpi));
+    lpi_data.host_lpis = xzalloc_array(union host_lpi *, nr_lpi_ptrs);
+    if ( !lpi_data.host_lpis )
+        return -ENOMEM;
+
     printk("GICv3: using at most %lld LPIs on the host.\n", MAX_PHYS_LPIS);
 
     return 0;
 }
 
+#define LPI_BLOCK       32
+
+/* Must be called with host_lpis_lock held. */
+static int find_unused_host_lpi(int start, uint32_t *index)
+{
+    int chunk;
+    uint32_t i = *index;
+
+    for ( chunk = start; chunk < MAX_PHYS_LPIS / HOST_LPIS_PER_PAGE; chunk++ )
+    {
+        /* If we hit an unallocated chunk, use entry 0 in that one. */
+        if ( !lpi_data.host_lpis[chunk] )
+        {
+            *index = 0;
+            return chunk;
+        }
+
+        /* Find an unallocated entry in this chunk. */
+        for ( ; i < HOST_LPIS_PER_PAGE; i += LPI_BLOCK )
+        {
+            if ( lpi_data.host_lpis[chunk][i].dom_id == INVALID_DOMID )
+            {
+                *index = i;
+                return chunk;
+            }
+        }
+        i = 0;
+    }
+
+    return -1;
+}
+
+/*
+ * Allocate a block of 32 LPIs on the given host ITS for device "devid",
+ * starting with "eventid". Put them into the respective ITT by issuing a
+ * MAPTI command for each of them.
+ */
+int gicv3_allocate_host_lpi_block(struct host_its *its, struct domain *d,
+                                  uint32_t host_devid, uint32_t eventid)
+{
+    static uint32_t next_lpi = 0;
+    uint32_t lpi, lpi_idx = next_lpi % HOST_LPIS_PER_PAGE;
+    int chunk;
+    int i;
+
+    spin_lock(&lpi_data.host_lpis_lock);
+    chunk = find_unused_host_lpi(next_lpi / HOST_LPIS_PER_PAGE, &lpi_idx);
+
+    if ( chunk == - 1 )          /* rescan for a hole from the beginning */
+    {
+        lpi_idx = 0;
+        chunk = find_unused_host_lpi(0, &lpi_idx);
+        if ( chunk == -1 )
+        {
+            spin_unlock(&lpi_data.host_lpis_lock);
+            return -ENOSPC;
+        }
+    }
+
+    /* If we hit an unallocated chunk, we initialize it and use entry 0. */
+    if ( !lpi_data.host_lpis[chunk] )
+    {
+        union host_lpi *new_chunk;
+
+        new_chunk = alloc_xenheap_pages(0, 0);
+        if ( !new_chunk )
+        {
+            spin_unlock(&lpi_data.host_lpis_lock);
+            return -ENOMEM;
+        }
+
+        for ( i = 0; i < HOST_LPIS_PER_PAGE; i += LPI_BLOCK )
+            new_chunk[i].dom_id = INVALID_DOMID;
+
+        lpi_data.host_lpis[chunk] = new_chunk;
+        lpi_idx = 0;
+    }
+
+    lpi = chunk * HOST_LPIS_PER_PAGE + lpi_idx;
+
+    for ( i = 0; i < LPI_BLOCK; i++ )
+    {
+        union host_lpi hlpi;
+
+        /*
+         * Mark this host LPI as belonging to the domain, but don't assign
+         * any virtual LPI or a VCPU yet.
+         */
+        hlpi.virt_lpi = INVALID_LPI;
+        hlpi.dom_id = d->domain_id;
+        hlpi.vcpu_id = INVALID_DOMID;
+        write_u64_atomic(&lpi_data.host_lpis[chunk][lpi_idx + i].data,
+                         hlpi.data);
+
+        /*
+         * Enable this host LPI, so we don't have to do this during the
+         * guest's runtime.
+         */
+        lpi_data.lpi_property[lpi + i] |= LPI_PROP_ENABLED;
+    }
+
+    /*
+     * We have allocated and initialized the host LPI entries, so it's safe
+     * to drop the lock now. Access to the structures can be done concurrently
+     * as it involves only an atomic uint64_t access.
+     */
+    spin_unlock(&lpi_data.host_lpis_lock);
+
+    __flush_dcache_area(&lpi_data.lpi_property[lpi], LPI_BLOCK);
+
+    gicv3_its_map_host_events(its, host_devid, eventid, lpi + LPI_OFFSET,
+                              LPI_BLOCK);
+
+    next_lpi = lpi + LPI_BLOCK;
+    return lpi + LPI_OFFSET;
+}
+
+int gicv3_free_host_lpi_block(struct host_its *its, uint32_t lpi)
+{
+    union host_lpi *hlpi, empty_lpi = { .dom_id = INVALID_DOMID };
+    int i;
+
+    hlpi = gic_get_host_lpi(lpi);
+    if ( !hlpi )
+        return -ENOENT;
+
+    spin_lock(&lpi_data.host_lpis_lock);
+
+    for ( i = 0; i < LPI_BLOCK; i++ )
+        write_u64_atomic(&hlpi[i].data, empty_lpi.data);
+
+    /* TODO: Call a function in gic-v3-its.c to send DISCARDs */
+
+    spin_unlock(&lpi_data.host_lpis_lock);
+
+    return 0;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/include/asm-arm/atomic.h b/xen/include/asm-arm/atomic.h
index 22a5036..df9de6a 100644
--- a/xen/include/asm-arm/atomic.h
+++ b/xen/include/asm-arm/atomic.h
@@ -53,9 +53,9 @@ build_atomic_write(write_u16_atomic, "h", WORD, uint16_t, "r")
 build_atomic_write(write_u32_atomic, "",  WORD, uint32_t, "r")
 build_atomic_write(write_int_atomic, "",  WORD, int, "r")
 
-#if 0 /* defined (CONFIG_ARM_64) */
-build_atomic_read(read_u64_atomic, "x", uint64_t, "=r")
-build_atomic_write(write_u64_atomic, "x", uint64_t, "r")
+#if defined (CONFIG_ARM_64)
+build_atomic_read(read_u64_atomic, "", "", uint64_t, "=r")
+build_atomic_write(write_u64_atomic, "", "", uint64_t, "r")
 #endif
 
 build_add_sized(add_u8_sized, "b", BYTE, uint8_t, "ri")
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index 12bd155..7825575 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -220,7 +220,12 @@ enum gic_version {
     GIC_V3,
 };
 
+#define INVALID_LPI     0
 #define LPI_OFFSET      8192
+static inline bool is_lpi(unsigned int irq)
+{
+    return irq >= LPI_OFFSET;
+}
 
 extern enum gic_version gic_hw_version(void);
 
diff --git a/xen/include/asm-arm/gic_v3_its.h b/xen/include/asm-arm/gic_v3_its.h
index 9c5dcf3..0e6b06a 100644
--- a/xen/include/asm-arm/gic_v3_its.h
+++ b/xen/include/asm-arm/gic_v3_its.h
@@ -97,6 +97,8 @@
 #define HOST_ITS_FLUSH_CMD_QUEUE        (1U << 0)
 #define HOST_ITS_USES_PTA               (1U << 1)
 
+#define INVALID_DOMID ((uint16_t)~0)
+
 /* data structure for each hardware ITS */
 struct host_its {
     struct list_head entry;
@@ -117,6 +119,7 @@ struct its_devices {
     uint32_t guest_devid;
     uint32_t host_devid;
     uint32_t eventids;
+    uint32_t *host_lpis;
 };
 
 extern struct list_head host_its_list;
@@ -149,6 +152,12 @@ int gicv3_its_setup_collection(int cpu);
  */
 int gicv3_its_map_guest_device(struct domain *d, int host_devid,
                                int guest_devid, int bits, bool valid);
+int gicv3_its_map_host_events(struct host_its *its,
+                              int host_devid, int eventid,
+                              int lpi, int nrevents);
+int gicv3_allocate_host_lpi_block(struct host_its *its, struct domain *d,
+                                  uint32_t host_devid, uint32_t eventid);
+int gicv3_free_host_lpi_block(struct host_its *its, uint32_t lpi);
 
 #else
 
-- 
2.9.0


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

  parent reply	other threads:[~2017-01-30 18:30 UTC|newest]

Thread overview: 106+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-30 18:31 [PATCH 00/28] arm64: Dom0 ITS emulation Andre Przywara
2017-01-30 18:31 ` [PATCH 01/28] ARM: export __flush_dcache_area() Andre Przywara
2017-02-06 11:23   ` Julien Grall
2017-01-30 18:31 ` [PATCH 02/28] ARM: GICv3 ITS: parse and store ITS subnodes from hardware DT Andre Przywara
2017-02-06 12:39   ` Julien Grall
2017-02-16 17:44     ` Andre Przywara
2017-02-16 18:15       ` Julien Grall
2017-02-06 12:58   ` Julien Grall
2017-02-27 11:43     ` Andre Przywara
2017-02-27 12:51       ` Julien Grall
2017-01-30 18:31 ` [PATCH 03/28] ARM: GICv3: allocate LPI pending and property table Andre Przywara
2017-02-06 16:26   ` Julien Grall
2017-02-27 11:34     ` Andre Przywara
2017-02-27 12:48       ` Julien Grall
2017-02-14  0:47   ` Stefano Stabellini
2017-01-30 18:31 ` [PATCH 04/28] ARM: GICv3 ITS: allocate device and collection table Andre Przywara
2017-02-06 17:19   ` Julien Grall
2017-02-14  0:55     ` Stefano Stabellini
2017-02-06 17:36   ` Julien Grall
2017-02-06 17:43   ` Julien Grall
2017-03-23 18:06     ` Andre Przywara
2017-03-23 18:08       ` Julien Grall
2017-02-14  0:54   ` Stefano Stabellini
2017-02-15 18:31   ` Shanker Donthineni
2017-02-16 19:03   ` Shanker Donthineni
2017-02-24 19:29     ` Shanker Donthineni
2017-02-27 10:23       ` Andre Przywara
2017-01-30 18:31 ` [PATCH 05/28] ARM: GICv3 ITS: map ITS command buffer Andre Przywara
2017-02-06 17:43   ` Julien Grall
2017-02-14  0:59   ` Stefano Stabellini
2017-02-14 20:50     ` Julien Grall
2017-02-14 21:00       ` Stefano Stabellini
2017-01-30 18:31 ` [PATCH 06/28] ARM: GICv3 ITS: introduce ITS command handling Andre Przywara
2017-02-06 19:16   ` Julien Grall
2017-02-07 11:44     ` Julien Grall
2017-03-07 18:08     ` Andre Przywara
2017-03-08 15:28       ` Julien Grall
2017-03-08 16:16         ` Andre Przywara
2017-02-07 11:59   ` Julien Grall
2017-01-30 18:31 ` [PATCH 07/28] ARM: GICv3 ITS: introduce device mapping Andre Przywara
2017-02-07 14:05   ` Julien Grall
2017-02-15 16:30   ` Julien Grall
2017-02-22  7:06   ` Vijay Kilari
2017-02-24 19:37     ` Shanker Donthineni
2017-02-22 13:17   ` Julien Grall
2017-01-30 18:31 ` Andre Przywara [this message]
2017-02-07 18:01   ` [PATCH 08/28] ARM: GICv3 ITS: introduce host LPI array Julien Grall
2017-02-14 20:05   ` Stefano Stabellini
2017-01-30 18:31 ` [PATCH 09/28] ARM: GICv3 ITS: map device and LPIs to the ITS on physdev_op hypercall Andre Przywara
2017-01-31 10:29   ` Jaggi, Manish
2017-01-31 12:43     ` Julien Grall
2017-01-31 13:19       ` Jaggi, Manish
2017-01-31 13:46         ` Julien Grall
2017-01-31 14:08           ` Jaggi, Manish
2017-01-31 15:17             ` Julien Grall
2017-01-31 16:02               ` Jaggi, Manish
2017-01-31 16:18                 ` Julien Grall
2017-02-24 19:57                   ` Shanker Donthineni
2017-02-24 20:28                     ` Julien Grall
2017-02-27 17:20                     ` Andre Przywara
2017-02-28 18:29                       ` Julien Grall
2017-03-01 19:42                         ` Shanker Donthineni
2017-03-03 15:53                           ` Julien Grall
2017-01-31 13:28       ` Jaggi, Manish
2017-02-14 20:11   ` Stefano Stabellini
2017-01-30 18:31 ` [PATCH 10/28] ARM: GICv3: introduce separate pending_irq structs for LPIs Andre Przywara
2017-02-14 20:39   ` Stefano Stabellini
2017-02-15 17:06     ` Julien Grall
2017-02-15 17:03   ` Julien Grall
2017-01-30 18:31 ` [PATCH 11/28] ARM: GICv3: forward pending LPIs to guests Andre Przywara
2017-02-14 21:00   ` Stefano Stabellini
2017-02-15 17:18     ` Julien Grall
2017-02-15 21:25       ` Stefano Stabellini
2017-03-02 20:56         ` Julien Grall
2017-03-03  7:58           ` Jan Beulich
2017-03-03 14:53             ` Julien Grall
2017-02-15 17:30   ` Julien Grall
2017-01-30 18:31 ` [PATCH 12/28] ARM: GICv3: enable ITS and LPIs on the host Andre Przywara
2017-02-14 22:41   ` Stefano Stabellini
2017-02-15 17:35   ` Julien Grall
2017-01-30 18:31 ` [PATCH 13/28] ARM: vGICv3: handle virtual LPI pending and property tables Andre Przywara
2017-02-14 23:56   ` Stefano Stabellini
2017-02-15 18:44   ` Julien Grall
2017-01-30 18:31 ` [PATCH 14/28] ARM: vGICv3: Handle disabled LPIs Andre Przywara
2017-02-14 23:58   ` Stefano Stabellini
2017-01-30 18:31 ` [PATCH 15/28] ARM: vGICv3: introduce basic ITS emulation bits Andre Przywara
2017-02-15 20:06   ` Shanker Donthineni
2017-01-30 18:31 ` [PATCH 16/28] ARM: vITS: introduce translation table walks Andre Przywara
2017-01-30 18:31 ` [PATCH 17/28] ARM: vITS: handle CLEAR command Andre Przywara
2017-02-15  0:07   ` Stefano Stabellini
2017-01-30 18:31 ` [PATCH 18/28] ARM: vITS: handle INT command Andre Przywara
2017-01-30 18:31 ` [PATCH 19/28] ARM: vITS: handle MAPC command Andre Przywara
2017-01-30 18:31 ` [PATCH 20/28] ARM: vITS: handle MAPD command Andre Przywara
2017-02-15  0:17   ` Stefano Stabellini
2017-01-30 18:31 ` [PATCH 21/28] ARM: vITS: handle MAPTI command Andre Przywara
2017-01-30 18:31 ` [PATCH 22/28] ARM: vITS: handle MOVI command Andre Przywara
2017-01-30 18:31 ` [PATCH 23/28] ARM: vITS: handle DISCARD command Andre Przywara
2017-01-30 18:31 ` [PATCH 24/28] ARM: vITS: handle INV command Andre Przywara
2017-01-30 18:31 ` [PATCH 25/28] ARM: vITS: handle INVALL command Andre Przywara
2017-01-30 18:31 ` [PATCH 26/28] ARM: vITS: create and initialize virtual ITSes for Dom0 Andre Przywara
2017-01-30 18:31 ` [PATCH 27/28] ARM: vITS: create ITS subnodes for Dom0 DT Andre Przywara
2017-01-30 18:31 ` [PATCH 28/28] ARM: vGIC: advertising LPI support Andre Przywara
2017-02-13 13:53 ` [PATCH 00/28] arm64: Dom0 ITS emulation Vijay Kilari
2017-02-14 22:00   ` Stefano Stabellini
2017-02-15 15:59   ` Julien Grall
2017-02-15 17:55 ` Julien Grall

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20170130183153.28566-9-andre.przywara@arm.com \
    --to=andre.przywara@arm.com \
    --cc=julien.grall@arm.com \
    --cc=sstabellini@kernel.org \
    --cc=vijay.kilari@gmail.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.