All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] xen/arm: Bunch of fixes for the vGIC emulation
@ 2015-11-13 11:54 Julien Grall
  2015-11-13 11:54 ` [PATCH 1/9] xen/arm: vgic-v3: Use the correct offset GICR_IGRPMODR0 Julien Grall
                   ` (8 more replies)
  0 siblings, 9 replies; 21+ messages in thread
From: Julien Grall @ 2015-11-13 11:54 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini

Hi all,

The main point of this series is to fix the access to any register when the
user doesn't write at the base offset of the registers.

At the same, I took the opportunity to re-arrange the emulation and dropping
any registers which doesn't exists or not required by the spec.

This series is based on "xen/arm: vgic: Support 32-bit access for 64-bit
register" [1]. I've provided a branch with the 2 series applied:

git://xenbits.xen.org/people/julieng/xen-unstable.git branch gic-emulation-v1

Sincerely yours,

[1] http://lists.xen.org/archives/html/xen-devel/2015-11/msg00782.html

Julien Grall (9):
  xen/arm: vgic-v3: Use the correct offset GICR_IGRPMODR0
  xen/arm: vgic-v3: Only emulate identification registers requested by
    the spec
  xen/arm: vgic: Properly emulate the full register
  xen/arm: vgic-v3: Remove GICR_MOVALLR and GICR_MOVLPIR
  xen/arm: vgic: Re-order the register emulations to match the memory
    map
  xen/arm: vgic-v3: Emulate read to GICD_ICACTIVER<n>
  xen/arm: vgic-v3: Remove spurious return in GICR_INVALLR
  xen/arm: vgic-v3: Don't implement write-only register read as zero
  xen/arm: vgic-v3: Make clear that GICD_*SPI_* registers are reserved

 xen/arch/arm/vgic-v2.c            | 252 +++++++------
 xen/arch/arm/vgic-v3.c            | 720 +++++++++++++++++++++++++-------------
 xen/include/asm-arm/gic_v3_defs.h |  16 +-
 xen/include/asm-arm/vgic-emul.h   |  24 ++
 4 files changed, 654 insertions(+), 358 deletions(-)
 create mode 100644 xen/include/asm-arm/vgic-emul.h

-- 
2.1.4

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 1/9] xen/arm: vgic-v3: Use the correct offset GICR_IGRPMODR0
  2015-11-13 11:54 [PATCH 0/9] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
@ 2015-11-13 11:54 ` Julien Grall
  2015-11-16 13:20   ` Ian Campbell
  2015-11-13 11:54 ` [PATCH 2/9] xen/arm: vgic-v3: Only emulate identification registers requested by the spec Julien Grall
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Julien Grall @ 2015-11-13 11:54 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini

The offset is 0x0D00 and not 0x0F80.

Also re-order the definition to keep all the definitions ordered.

Signed-off-by: Julien Grall <julien.grall@citrix.com>
---
 xen/include/asm-arm/gic_v3_defs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/include/asm-arm/gic_v3_defs.h b/xen/include/asm-arm/gic_v3_defs.h
index 89a3548..34e8b0a 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -96,7 +96,6 @@
 /* GICR for SGI's & PPI's */
 
 #define GICR_IGROUPR0                (0x0080)
-#define GICR_IGRPMODR0               (0x0F80)
 #define GICR_ISENABLER0              (0x0100)
 #define GICR_ICENABLER0              (0x0180)
 #define GICR_ISPENDR0                (0x0200)
@@ -107,6 +106,7 @@
 #define GICR_IPRIORITYR7             (0x041C)
 #define GICR_ICFGR0                  (0x0C00)
 #define GICR_ICFGR1                  (0x0C04)
+#define GICR_IGRPMODR0               (0x0D00)
 #define GICR_NSACR                   (0x0E00)
 
 #define GICR_TYPER_PLPIS             (1U << 0)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 2/9] xen/arm: vgic-v3: Only emulate identification registers requested by the spec
  2015-11-13 11:54 [PATCH 0/9] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
  2015-11-13 11:54 ` [PATCH 1/9] xen/arm: vgic-v3: Use the correct offset GICR_IGRPMODR0 Julien Grall
@ 2015-11-13 11:54 ` Julien Grall
  2015-11-16 13:27   ` Ian Campbell
  2015-11-13 11:54 ` [PATCH 3/9] xen/arm: vgic: Properly emulate the full register Julien Grall
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Julien Grall @ 2015-11-13 11:54 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini

Most of the identification registers space contains implementation
defined registers (see 8.1.13 in ARM IHI 0069A) and only GIC{D,R}_PIDR2
is required to be implemented.

Currently the emulation of those registers mimic the ARM implementation,
but it's untrue to say that we properly emulate a such implementation.

Keep only GIC{D,R}_PIDR2 implemented with the "implementationd defined
bits" to zero and the ArchRev field (bits[7:4]) to 0x3 as we emulate a
GICv3.

Note that the emulation of the range wasn't valid anyway because the
registers are split in 2 sets (PIDR4-PIDR7 and PIDR0-PIDR2).

Signed-off-by: Julien Grall <julien.grall@citrix.com>
---
 xen/arch/arm/vgic-v3.c            | 127 +++++++++++++++++++++++---------------
 xen/include/asm-arm/gic_v3_defs.h |  12 ----
 2 files changed, 76 insertions(+), 63 deletions(-)

diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 902f64a..0f6cb95 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -31,17 +31,15 @@
 #include <asm/gic_v3_defs.h>
 #include <asm/vgic.h>
 
-/* GICD_PIDRn register values for ARM implementations */
-#define GICV3_GICD_PIDR0  0x92
-#define GICV3_GICD_PIDR1  0xb4
-#define GICV3_GICD_PIDR2  0x3b
-#define GICV3_GICD_PIDR4  0x04
-
-/* GICR_PIDRn register values for ARM implementations */
-#define GICV3_GICR_PIDR0  0x93
-#define GICV3_GICR_PIDR1  GICV3_GICD_PIDR1
+/*
+ * PIDR2: Only bits[7:4] are not implementation defined. We are
+ * emulating a GICv3 ([7:4] = 0x3).
+ *
+ * We don't emulate a specific registers scheme so implement the others
+ * bits as RES0 as recommended by the spec (see 8.1.13 in ARM IHI 0069A).
+ */
+#define GICV3_GICD_PIDR2  0x30
 #define GICV3_GICR_PIDR2  GICV3_GICD_PIDR2
-#define GICV3_GICR_PIDR4  GICV3_GICD_PIDR4
 
 /*
  * GICD_CTLR default value:
@@ -237,28 +235,20 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
     case GICR_MOVALLR:
         /* WO Read as zero */
         goto read_as_zero_64;
-    case GICR_PIDR0:
-        if ( dabt.size != DABT_WORD ) goto bad_width;
-        *r = vgic_reg32_extract(GICV3_GICR_PIDR0, info);
-         return 1;
-    case GICR_PIDR1:
-        if ( dabt.size != DABT_WORD ) goto bad_width;
-        *r = vgic_reg32_extract(GICV3_GICR_PIDR1, info);
-         return 1;
+
+    case 0xFFD0 ... 0xFFE4:
+        /* Implementation defined identification registers */
+       goto read_impl_defined;
+
     case GICR_PIDR2:
         if ( dabt.size != DABT_WORD ) goto bad_width;
         *r = vgic_reg32_extract(GICV3_GICR_PIDR2, info);
          return 1;
-    case GICR_PIDR3:
-        /* Manufacture/customer defined */
-        goto read_as_zero_32;
-    case GICR_PIDR4:
-        if ( dabt.size != DABT_WORD ) goto bad_width;
-        *r = vgic_reg32_extract(GICV3_GICR_PIDR4, info);
-         return 1;
-    case GICR_PIDR5 ... GICR_PIDR7:
-        /* Reserved0 */
-        goto read_as_zero_32;
+
+    case 0xFFEC ... 0xFFFC:
+         /* Implementation defined identification registers */
+         goto read_impl_defined;
+
     default:
         printk(XENLOG_G_ERR
                "%pv: vGICR: unhandled read r%d offset %#08x\n",
@@ -280,6 +270,13 @@ read_as_zero_32:
     if ( dabt.size != DABT_WORD ) goto bad_width;
     *r = 0;
     return 1;
+
+read_impl_defined:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICR: RAZ on implemention defined register offset %#08x\n",
+           v, gicr_reg);
+    *r = 0;
+    return 1;
 }
 
 static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
@@ -332,9 +329,19 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
     case GICR_MOVALLR:
         /* LPI is not implemented */
         goto write_ignore_64;
-    case GICR_PIDR7... GICR_PIDR0:
+
+    case 0xFFD0 ... 0xFFE4:
+        /* Implementation defined identification registers */
+       goto write_impl_defined;
+
+    case GICR_PIDR2:
         /* RO */
         goto write_ignore_32;
+
+    case 0xFFEC ... 0xFFFC:
+         /* Implementation defined identification registers */
+         goto write_impl_defined;
+
     default:
         printk(XENLOG_G_ERR "%pv: vGICR: unhandled write r%d offset %#08x\n",
                v, dabt.reg, gicr_reg);
@@ -354,6 +361,12 @@ write_ignore_64:
 write_ignore_32:
     if ( dabt.size != DABT_WORD ) goto bad_width;
     return 1;
+
+write_impl_defined:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICR: WI on implementation defined register offset %#08x\n",
+           v, gicr_reg);
+    return 1;
 }
 
 static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
@@ -835,32 +848,21 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
     case GICD_SPENDSGIR ... GICD_SPENDSGIRN:
         /* Replaced with GICR_ISPENDR0. So ignore write */
         goto read_as_zero_32;
-    case GICD_PIDR0:
-        /* GICv3 identification value */
-        if ( dabt.size != DABT_WORD ) goto bad_width;
-        *r = vgic_reg32_extract(GICV3_GICD_PIDR0, info);
-        return 1;
-    case GICD_PIDR1:
-        /* GICv3 identification value */
-        if ( dabt.size != DABT_WORD ) goto bad_width;
-        *r = vgic_reg32_extract(GICV3_GICD_PIDR1, info);
-        return 1;
+
+    case 0xFFD0 ... 0xFFE4:
+        /* Implementation defined identification registers */
+       goto read_impl_defined;
+
     case GICD_PIDR2:
         /* GICv3 identification value */
         if ( dabt.size != DABT_WORD ) goto bad_width;
         *r = vgic_reg32_extract(GICV3_GICD_PIDR2, info);
         return 1;
-    case GICD_PIDR3:
-        /* GICv3 identification value. Manufacturer/Customer defined */
-        goto read_as_zero_32;
-    case GICD_PIDR4:
-        /* GICv3 identification value */
-        if ( dabt.size != DABT_WORD ) goto bad_width;
-        *r = vgic_reg32_extract(GICV3_GICD_PIDR4, info);
-        return 1;
-    case GICD_PIDR5 ... GICD_PIDR7:
-        /* Reserved0 */
-        goto read_as_zero_32;
+
+    case 0xFFEC ... 0xFFFC:
+         /* Implementation defined identification registers */
+         goto read_impl_defined;
+
     case 0x00c:
     case 0x044:
     case 0x04c:
@@ -892,6 +894,13 @@ read_as_zero_32:
 read_as_zero:
     *r = 0;
     return 1;
+
+read_impl_defined:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: RAZ on implemention defined register offset %#08x\n",
+           v, gicd_reg);
+    *r = 0;
+    return 1;
 }
 
 static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
@@ -996,9 +1005,19 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         /* Replaced with GICR_ISPENDR0. So ignore write */
         if ( dabt.size != DABT_WORD ) goto bad_width;
         return 0;
-    case GICD_PIDR7... GICD_PIDR0:
+
+    case 0xFFD0 ... 0xFFE4:
+        /* Implementation defined identification registers */
+       goto write_impl_defined;
+
+    case GICD_PIDR2:
         /* RO -- write ignore */
         goto write_ignore_32;
+
+    case 0xFFEC ... 0xFFFC:
+         /* Implementation defined identification registers */
+         goto write_impl_defined;
+
     case 0x00c:
     case 0x044:
     case 0x04c:
@@ -1030,6 +1049,12 @@ write_ignore_32:
 
 write_ignore:
     return 1;
+
+write_impl_defined:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: WI on implementation defined register offset %#08x\n",
+           v, gicd_reg);
+    return 1;
 }
 
 static int vgic_v3_to_sgi(struct vcpu *v, register_t sgir)
diff --git a/xen/include/asm-arm/gic_v3_defs.h b/xen/include/asm-arm/gic_v3_defs.h
index 34e8b0a..5a6938c 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -31,13 +31,7 @@
 #define GICD_IROUTER                 (0x6000)
 #define GICD_IROUTER32               (0x6100)
 #define GICD_IROUTER1019             (0x7FD8)
-#define GICD_PIDR0                   (0xFFE0)
-#define GICD_PIDR1                   (0xFFE4)
 #define GICD_PIDR2                   (0xFFE8)
-#define GICD_PIDR3                   (0xFFEC)
-#define GICD_PIDR4                   (0xFFD0)
-#define GICD_PIDR5                   (0xFFD4)
-#define GICD_PIDR7                   (0xFFDC)
 
 /* Common between GICD_PIDR2 and GICR_PIDR2 */
 #define GIC_PIDR2_ARCH_MASK         (0xf0)
@@ -85,13 +79,7 @@
 #define GICR_SYNCR                   (0x00C0)
 #define GICR_MOVLPIR                 (0x100)
 #define GICR_MOVALLR                 (0x0110)
-#define GICR_PIDR0                   GICD_PIDR0
-#define GICR_PIDR1                   GICD_PIDR1
 #define GICR_PIDR2                   GICD_PIDR2
-#define GICR_PIDR3                   GICD_PIDR3
-#define GICR_PIDR4                   GICD_PIDR4
-#define GICR_PIDR5                   GICD_PIDR5
-#define GICR_PIDR7                   GICD_PIDR7
 
 /* GICR for SGI's & PPI's */
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 3/9] xen/arm: vgic: Properly emulate the full register
  2015-11-13 11:54 [PATCH 0/9] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
  2015-11-13 11:54 ` [PATCH 1/9] xen/arm: vgic-v3: Use the correct offset GICR_IGRPMODR0 Julien Grall
  2015-11-13 11:54 ` [PATCH 2/9] xen/arm: vgic-v3: Only emulate identification registers requested by the spec Julien Grall
@ 2015-11-13 11:54 ` Julien Grall
  2015-11-16 13:29   ` Ian Campbell
  2015-11-13 11:54 ` [PATCH 4/9] xen/arm: vgic-v3: Remove GICR_MOVALLR and GICR_MOVLPIR Julien Grall
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Julien Grall @ 2015-11-13 11:54 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini

The offset in the emulation is based on byte. As most of the registers
are 64/32 bits, they will span over multiple bytes.

However, the current emulation only care about the first offset. This
will result to not emulate properly any access on the register with
other offset.

Introduce new macros to help implementing access on multiple byte and
use them over the vGIC emulation.

Note that I didn't convert the reserved/implementation defined
registers. It will be done in a follow-up.

Signed-off-by: Julien Grall <julien.grall@citrix.com>
---
 xen/arch/arm/vgic-v2.c          |  81 ++++++------
 xen/arch/arm/vgic-v3.c          | 287 ++++++++++++++++++++++++----------------
 xen/include/asm-arm/vgic-emul.h |  24 ++++
 3 files changed, 240 insertions(+), 152 deletions(-)
 create mode 100644 xen/include/asm-arm/vgic-emul.h

diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index 4fb954b..d1860a9 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -31,6 +31,7 @@
 #include <asm/mmio.h>
 #include <asm/platform.h>
 #include <asm/vgic.h>
+#include <asm/vgic-emul.h>
 
 static struct {
     bool_t enabled;
@@ -177,13 +178,14 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
 
     switch ( gicd_reg )
     {
-    case GICD_CTLR:
+    case VREG32(GICD_CTLR):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         vgic_lock(v);
         *r = vgic_reg32_extract(v->domain->arch.vgic.ctlr, info);
         vgic_unlock(v);
         return 1;
-    case GICD_TYPER:
+
+    case VREG32(GICD_TYPER):
     {
         uint32_t typer;
 
@@ -198,7 +200,8 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
 
         return 1;
     }
-    case GICD_IIDR:
+
+    case VREG32(GICD_IIDR):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         /*
          * XXX Do we need a JEP106 manufacturer ID?
@@ -211,11 +214,11 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
     case 0x020 ... 0x03c:
         goto read_as_zero;
 
-    case GICD_IGROUPR ... GICD_IGROUPRN:
+    case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
         /* We do not implement security extensions for guests, read zero */
         goto read_as_zero_32;
 
-    case GICD_ISENABLER ... GICD_ISENABLERN:
+    case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ISENABLER, DABT_WORD);
         if ( rank == NULL) goto read_as_zero;
@@ -224,7 +227,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         vgic_unlock_rank(v, rank, flags);
         return 1;
 
-    case GICD_ICENABLER ... GICD_ICENABLERN:
+    case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ICENABLER, DABT_WORD);
         if ( rank == NULL) goto read_as_zero;
@@ -234,16 +237,16 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         return 1;
 
     /* Read the pending status of an IRQ via GICD is not supported */
-    case GICD_ISPENDR ... GICD_ISPENDRN:
-    case GICD_ICPENDR ... GICD_ICPENDRN:
+    case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
+    case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
         goto read_as_zero;
 
     /* Read the active status of an IRQ via GICD is not supported */
-    case GICD_ISACTIVER ... GICD_ISACTIVERN:
-    case GICD_ICACTIVER ... GICD_ICACTIVERN:
+    case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN):
+    case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
         goto read_as_zero;
 
-    case GICD_ITARGETSR ... GICD_ITARGETSRN:
+    case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSRN):
     {
         uint32_t itargetsr;
 
@@ -258,7 +261,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         return 1;
     }
 
-    case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
+    case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
     {
         uint32_t ipriorityr;
 
@@ -276,7 +279,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         return 1;
     }
 
-    case GICD_ICFGR ... GICD_ICFGRN:
+    case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
     {
         uint32_t icfgr;
 
@@ -292,26 +295,26 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         return 1;
     }
 
-    case GICD_NSACR ... GICD_NSACRN:
+    case VRANGE32(GICD_NSACR, GICD_NSACRN):
         /* We do not implement security extensions for guests, read zero */
         goto read_as_zero_32;
 
-    case GICD_SGIR:
+    case VREG32(GICD_SGIR):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         /* Write only -- read unknown */
         *r = 0xdeadbeef;
         return 1;
 
     /* Setting/Clearing the SGI pending bit via GICD is not supported */
-    case GICD_CPENDSGIR ... GICD_CPENDSGIRN:
-    case GICD_SPENDSGIR ... GICD_SPENDSGIRN:
+    case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
+    case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
         goto read_as_zero;
 
     /* Implementation defined -- read as zero */
     case 0xfd0 ... 0xfe4:
         goto read_as_zero;
 
-    case GICD_ICPIDR2:
+    case VREG32(GICD_ICPIDR2):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR "%pv: vGICD: unhandled read from ICPIDR2\n", v);
         return 0;
@@ -396,7 +399,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
 
     switch ( gicd_reg )
     {
-    case GICD_CTLR:
+    case VREG32(GICD_CTLR):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         /* Ignore all but the enable bit */
         vgic_lock(v);
@@ -407,19 +410,19 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         return 1;
 
     /* R/O -- write ignored */
-    case GICD_TYPER:
-    case GICD_IIDR:
+    case VREG32(GICD_TYPER):
+    case VREG32(GICD_IIDR):
         goto write_ignore_32;
 
     /* Implementation defined -- write ignored */
     case 0x020 ... 0x03c:
         goto write_ignore;
 
-    case GICD_IGROUPR ... GICD_IGROUPRN:
+    case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
         /* We do not implement security extensions for guests, write ignore */
         goto write_ignore_32;
 
-    case GICD_ISENABLER ... GICD_ISENABLERN:
+    case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ISENABLER, DABT_WORD);
         if ( rank == NULL) goto write_ignore;
@@ -430,7 +433,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         vgic_unlock_rank(v, rank, flags);
         return 1;
 
-    case GICD_ICENABLER ... GICD_ICENABLERN:
+    case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ICENABLER, DABT_WORD);
         if ( rank == NULL) goto write_ignore;
@@ -441,39 +444,39 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         vgic_unlock_rank(v, rank, flags);
         return 1;
 
-    case GICD_ISPENDR ... GICD_ISPENDRN:
+    case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
                "%pv: vGICD: unhandled word write %#"PRIregister" to ISPENDR%d\n",
                v, r, gicd_reg - GICD_ISPENDR);
         return 0;
 
-    case GICD_ICPENDR ... GICD_ICPENDRN:
+    case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
                "%pv: vGICD: unhandled word write %#"PRIregister" to ICPENDR%d\n",
                v, r, gicd_reg - GICD_ICPENDR);
         return 0;
 
-    case GICD_ISACTIVER ... GICD_ISACTIVERN:
+    case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
                "%pv: vGICD: unhandled word write %#"PRIregister" to ISACTIVER%d\n",
                v, r, gicd_reg - GICD_ISACTIVER);
         return 0;
 
-    case GICD_ICACTIVER ... GICD_ICACTIVERN:
+    case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
                "%pv: vGICD: unhandled word write %#"PRIregister" to ICACTIVER%d\n",
                v, r, gicd_reg - GICD_ICACTIVER);
         return 0;
 
-    case GICD_ITARGETSR ... GICD_ITARGETSR7:
+    case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSR7):
         /* SGI/PPI target is read only */
         goto write_ignore_32;
 
-    case GICD_ITARGETSR8 ... GICD_ITARGETSRN:
+    case VRANGE32(GICD_ITARGETSR8, GICD_ITARGETSRN):
     {
         uint32_t itargetsr;
 
@@ -489,7 +492,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         return 1;
     }
 
-    case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
+    case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
     {
         uint32_t *ipriorityr;
 
@@ -505,14 +508,14 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         return 1;
     }
 
-    case GICD_ICFGR: /* SGIs */
+    case VREG32(GICD_ICFGR): /* SGIs */
         goto write_ignore_32;
 
-    case GICD_ICFGR1:
+    case VREG32(GICD_ICFGR1):
         /* It is implementation defined if these are writeable. We chose not */
         goto write_ignore_32;
 
-    case GICD_ICFGR2 ... GICD_ICFGRN: /* SPIs */
+    case VRANGE32(GICD_ICFGR2, GICD_ICFGRN): /* SPIs */
         if ( dabt.size != DABT_WORD ) goto bad_width;
         rank = vgic_rank_offset(v, 2, gicd_reg - GICD_ICFGR, DABT_WORD);
         if ( rank == NULL) goto write_ignore;
@@ -523,22 +526,22 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         vgic_unlock_rank(v, rank, flags);
         return 1;
 
-    case GICD_NSACR ... GICD_NSACRN:
+    case VRANGE32(GICD_NSACR, GICD_NSACRN):
         /* We do not implement security extensions for guests, write ignore */
         goto write_ignore_32;
 
-    case GICD_SGIR:
+    case VREG32(GICD_SGIR):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         return vgic_v2_to_sgi(v, r);
 
-    case GICD_CPENDSGIR ... GICD_CPENDSGIRN:
+    case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
         if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
                "%pv: vGICD: unhandled %s write %#"PRIregister" to ICPENDSGIR%d\n",
                v, dabt.size ? "word" : "byte", r, gicd_reg - GICD_CPENDSGIR);
         return 0;
 
-    case GICD_SPENDSGIR ... GICD_SPENDSGIRN:
+    case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
         if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
                "%pv: vGICD: unhandled %s write %#"PRIregister" to ISPENDSGIR%d\n",
@@ -550,7 +553,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         goto write_ignore;
 
     /* R/O -- write ignore */
-    case GICD_ICPIDR2:
+    case VREG32(GICD_ICPIDR2):
         goto write_ignore_32;
 
     /* Implementation defined -- write ignored */
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 0f6cb95..892104d 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -30,6 +30,7 @@
 #include <asm/mmio.h>
 #include <asm/gic_v3_defs.h>
 #include <asm/vgic.h>
+#include <asm/vgic-emul.h>
 
 /*
  * PIDR2: Only bits[7:4] are not implementation defined. We are
@@ -172,15 +173,16 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
 
     switch ( gicr_reg )
     {
-    case GICR_CTLR:
+    case VREG32(GICR_CTLR):
         /* We have not implemented LPI's, read zero */
         goto read_as_zero_32;
-    case GICR_IIDR:
+
+    case VREG32(GICR_IIDR):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         *r = vgic_reg32_extract(GICV3_GICR_IIDR_VAL, info);
         return 1;
-    case GICR_TYPER:
-    case GICR_TYPER + 4:
+
+    case VREG64(GICR_TYPER):
     {
         uint64_t typer, aff;
 
@@ -199,40 +201,51 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
 
         return 1;
     }
-    case GICR_STATUSR:
+
+    case VREG32(GICR_STATUSR):
         /* Not implemented */
         goto read_as_zero_32;
-    case GICR_WAKER:
+
+    case VREG32(GICR_WAKER):
         /* Power management is not implemented */
         goto read_as_zero_32;
-    case GICR_SETLPIR:
+
+    case VREG64(GICR_SETLPIR):
         /* WO. Read as zero */
         goto read_as_zero_64;
-    case GICR_CLRLPIR:
+
+    case VREG64(GICR_CLRLPIR):
         /* WO. Read as zero */
         goto read_as_zero_64;
-    case GICR_PROPBASER:
+
+    case VREG64(GICR_PROPBASER):
         /* LPI's not implemented */
         goto read_as_zero_64;
-    case GICR_PENDBASER:
+
+    case VREG64(GICR_PENDBASER):
         /* LPI's not implemented */
         goto read_as_zero_64;
-    case GICR_INVLPIR:
+
+    case VREG64(GICR_INVLPIR):
         /* WO. Read as zero */
         goto read_as_zero_64;
-    case GICR_INVALLR:
+
+    case VREG64(GICR_INVALLR):
         /* WO. Read as zero */
         goto read_as_zero_64;
         return 0;
-    case GICR_SYNCR:
+
+    case VREG32(GICR_SYNCR):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         /* RO . But when read it always returns busy bito bit[0] */
         *r = vgic_reg32_extract(GICR_SYNCR_NOT_BUSY, info);
         return 1;
-    case GICR_MOVLPIR:
+
+    case VREG64(GICR_MOVLPIR):
         /* WO Read as zero */
         goto read_as_zero_64;
-    case GICR_MOVALLR:
+
+    case VREG64(GICR_MOVALLR):
         /* WO Read as zero */
         goto read_as_zero_64;
 
@@ -240,7 +253,7 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
         /* Implementation defined identification registers */
        goto read_impl_defined;
 
-    case GICR_PIDR2:
+    case VREG32(GICR_PIDR2):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         *r = vgic_reg32_extract(GICV3_GICR_PIDR2, info);
          return 1;
@@ -287,46 +300,59 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
 
     switch ( gicr_reg )
     {
-    case GICR_CTLR:
+    case VREG32(GICR_CTLR):
         /* LPI's not implemented */
         goto write_ignore_32;
-    case GICR_IIDR:
+
+    case VREG32(GICR_IIDR):
         /* RO */
         goto write_ignore_32;
-    case GICR_TYPER:
+
+    case VREG64(GICR_TYPER):
         /* RO */
         goto write_ignore_64;
-    case GICR_STATUSR:
+
+    case VREG32(GICR_STATUSR):
         /* Not implemented */
         goto write_ignore_32;
-    case GICR_WAKER:
+
+    case VREG32(GICR_WAKER):
         /* Power mgmt not implemented */
         goto write_ignore_32;
-    case GICR_SETLPIR:
+
+    case VREG64(GICR_SETLPIR):
         /* LPI is not implemented */
         goto write_ignore_64;
-    case GICR_CLRLPIR:
+
+    case VREG64(GICR_CLRLPIR):
         /* LPI is not implemented */
         goto write_ignore_64;
-    case GICR_PROPBASER:
+
+    case VREG64(GICR_PROPBASER):
         /* LPI is not implemented */
         goto write_ignore_64;
-    case GICR_PENDBASER:
+
+    case VREG64(GICR_PENDBASER):
         /* LPI is not implemented */
         goto write_ignore_64;
-    case GICR_INVLPIR:
+
+    case VREG64(GICR_INVLPIR):
         /* LPI is not implemented */
         goto write_ignore_64;
-    case GICR_INVALLR:
+
+    case VREG64(GICR_INVALLR):
         /* LPI is not implemented */
         goto write_ignore_64;
-    case GICR_SYNCR:
+
+    case VREG32(GICR_SYNCR):
         /* RO */
         goto write_ignore_32;
-    case GICR_MOVLPIR:
+
+    case VREG64(GICR_MOVLPIR):
         /* LPI is not implemented */
         goto write_ignore_64;
-    case GICR_MOVALLR:
+
+    case VREG64(GICR_MOVALLR):
         /* LPI is not implemented */
         goto write_ignore_64;
 
@@ -334,7 +360,7 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
         /* Implementation defined identification registers */
        goto write_impl_defined;
 
-    case GICR_PIDR2:
+    case VREG32(GICR_PIDR2):
         /* RO */
         goto write_ignore_32;
 
@@ -379,11 +405,12 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
 
     switch ( reg )
     {
-    case GICD_IGROUPR ... GICD_IGROUPRN:
+    case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
         /* We do not implement security extensions for guests, read zero */
         if ( dabt.size != DABT_WORD ) goto bad_width;
         goto read_as_zero;
-    case GICD_ISENABLER ... GICD_ISENABLERN:
+
+    case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         rank = vgic_rank_offset(v, 1, reg - GICD_ISENABLER, DABT_WORD);
         if ( rank == NULL ) goto read_as_zero;
@@ -391,7 +418,8 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
         *r = vgic_reg32_extract(rank->ienable, info);
         vgic_unlock_rank(v, rank, flags);
         return 1;
-    case GICD_ICENABLER ... GICD_ICENABLERN:
+
+    case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         rank = vgic_rank_offset(v, 1, reg - GICD_ICENABLER, DABT_WORD);
         if ( rank == NULL ) goto read_as_zero;
@@ -399,17 +427,18 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
         *r = vgic_reg32_extract(rank->ienable, info);
         vgic_unlock_rank(v, rank, flags);
         return 1;
+
     /* Read the pending status of an IRQ via GICD/GICR is not supported */
-    case GICD_ISPENDR ... GICD_ISPENDRN:
-    case GICD_ICPENDR ... GICD_ICPENDRN:
+    case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
+    case VRANGE32(GICD_ICPENDR, GICD_ICPENDR):
         goto read_as_zero;
 
     /* Read the active status of an IRQ via GICD/GICR is not supported */
-    case GICD_ISACTIVER ... GICD_ISACTIVERN:
-    case GICD_ICACTIVER ... GICD_ICACTIVERN:
+    case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVER):
+    case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
         goto read_as_zero;
 
-    case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
+    case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
     {
         uint32_t ipriorityr;
 
@@ -427,7 +456,7 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
         return 1;
     }
 
-    case GICD_ICFGR ... GICD_ICFGRN:
+    case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
     {
         uint32_t icfgr;
 
@@ -442,6 +471,7 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
 
         return 1;
     }
+
     default:
         printk(XENLOG_G_ERR
                "%pv: %s: unhandled read r%d offset %#08x\n",
@@ -471,10 +501,11 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
 
     switch ( reg )
     {
-    case GICD_IGROUPR ... GICD_IGROUPRN:
+    case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
         /* We do not implement security extensions for guests, write ignore */
         goto write_ignore_32;
-    case GICD_ISENABLER ... GICD_ISENABLERN:
+
+    case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         rank = vgic_rank_offset(v, 1, reg - GICD_ISENABLER, DABT_WORD);
         if ( rank == NULL ) goto write_ignore;
@@ -484,7 +515,8 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
         vgic_enable_irqs(v, (rank->ienable) & (~tr), rank->index);
         vgic_unlock_rank(v, rank, flags);
         return 1;
-    case GICD_ICENABLER ... GICD_ICENABLERN:
+
+    case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         rank = vgic_rank_offset(v, 1, reg - GICD_ICENABLER, DABT_WORD);
         if ( rank == NULL ) goto write_ignore;
@@ -494,35 +526,36 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
         vgic_disable_irqs(v, (~rank->ienable) & tr, rank->index);
         vgic_unlock_rank(v, rank, flags);
         return 1;
-    case GICD_ISPENDR ... GICD_ISPENDRN:
+
+    case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
                "%pv: %s: unhandled word write %#"PRIregister" to ISPENDR%d\n",
                v, name, r, reg - GICD_ISPENDR);
         return 0;
 
-    case GICD_ICPENDR ... GICD_ICPENDRN:
+    case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
                "%pv: %s: unhandled word write %#"PRIregister" to ICPENDR%d\n",
                v, name, r, reg - GICD_ICPENDR);
         return 0;
 
-    case GICD_ISACTIVER ... GICD_ISACTIVERN:
+    case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
                "%pv: %s: unhandled word write %#"PRIregister" to ISACTIVER%d\n",
                v, name, r, reg - GICD_ISACTIVER);
         return 0;
 
-    case GICD_ICACTIVER ... GICD_ICACTIVERN:
+    case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
                "%pv: %s: unhandled word write %#"PRIregister" to ICACTIVER%d\n",
                v, name, r, reg - GICD_ICACTIVER);
         return 0;
 
-    case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
+    case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
     {
         uint32_t *ipriorityr;
 
@@ -536,9 +569,11 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
         vgic_unlock_rank(v, rank, flags);
         return 1;
     }
-    case GICD_ICFGR: /* Restricted to configure SGIs */
+
+    case VREG32(GICD_ICFGR): /* Restricted to configure SGIs */
         goto write_ignore_32;
-    case GICD_ICFGR + 4 ... GICD_ICFGRN: /* PPI + SPIs */
+
+    case VRANGE32(GICD_ICFGR + 4, GICD_ICFGRN): /* PPI + SPIs */
         /* ICFGR1 for PPI's, which is implementation defined
            if ICFGR1 is programmable or not. We chose to program */
         if ( dabt.size != DABT_WORD ) goto bad_width;
@@ -578,16 +613,17 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info,
 
     switch ( gicr_reg )
     {
-    case GICR_IGRPMODR0:
+    case VREG32(GICR_IGRPMODR0):
         /* We do not implement security extensions for guests, read zero */
         goto read_as_zero_32;
-    case GICR_IGROUPR0:
-    case GICR_ISENABLER0:
-    case GICR_ICENABLER0:
-    case GICR_ISACTIVER0:
-    case GICR_ICACTIVER0:
-    case GICR_IPRIORITYR0...GICR_IPRIORITYR7:
-    case GICR_ICFGR0... GICR_ICFGR1:
+
+    case VREG32(GICR_IGROUPR0):
+    case VREG32(GICR_ISENABLER0):
+    case VREG32(GICR_ICENABLER0):
+    case VREG32(GICR_ISACTIVER0):
+    case VREG32(GICR_ICACTIVER0):
+    case VRANGE32(GICR_IPRIORITYR0, GICR_IPRIORITYR7):
+    case VRANGE32(GICR_ICFGR0, GICR_ICFGR1):
          /*
           * Above registers offset are common with GICD.
           * So handle in common with GICD handling
@@ -596,11 +632,11 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info,
                                                 gicr_reg, r);
 
     /* Read the pending status of an SGI is via GICR is not supported */
-    case GICR_ISPENDR0:
-    case GICR_ICPENDR0:
+    case VREG32(GICR_ISPENDR0):
+    case VREG32(GICR_ICPENDR0):
         goto read_as_zero;
 
-    case GICR_NSACR:
+    case VREG32(GICR_NSACR):
         /* We do not implement security extensions for guests, read zero */
         goto read_as_zero_32;
 
@@ -630,39 +666,42 @@ static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info,
 
     switch ( gicr_reg )
     {
-    case GICR_IGRPMODR0:
+    case VREG32(GICR_IGRPMODR0):
         /* We do not implement security extensions for guests, write ignore */
         goto write_ignore_32;
-    case GICR_IGROUPR0:
-    case GICR_ISENABLER0:
-    case GICR_ICENABLER0:
-    case GICR_ISACTIVER0:
-    case GICR_ICACTIVER0:
-    case GICR_ICFGR1:
-    case GICR_IPRIORITYR0...GICR_IPRIORITYR7:
+
+    case VREG32(GICR_IGROUPR0):
+    case VREG32(GICR_ISENABLER0):
+    case VREG32(GICR_ICENABLER0):
+    case VREG32(GICR_ISACTIVER0):
+    case VREG32(GICR_ICACTIVER0):
+    case VREG32(GICR_ICFGR1):
+    case VRANGE32(GICR_IPRIORITYR0, GICR_IPRIORITYR7):
          /*
           * Above registers offset are common with GICD.
           * So handle common with GICD handling
           */
         return __vgic_v3_distr_common_mmio_write("vGICR: SGI", v,
                                                  info, gicr_reg, r);
-    case GICR_ISPENDR0:
+
+    case VREG32(GICR_ISPENDR0):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
                "%pv: vGICR: SGI: unhandled word write %#"PRIregister" to ISPENDR0\n",
                v, r);
         return 0;
 
-    case GICR_ICPENDR0:
+    case VREG32(GICR_ICPENDR0):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
                "%pv: vGICR: SGI: unhandled word write %#"PRIregister" to ICPENDR0\n",
                v, r);
         return 0;
 
-    case GICR_NSACR:
+    case VREG32(GICR_NSACR):
         /* We do not implement security extensions for guests, write ignore */
         goto write_ignore_32;
+
     default:
         printk(XENLOG_G_ERR
                "%pv: vGICR: SGI: unhandled write r%d offset %#08x\n",
@@ -761,13 +800,14 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
 
     switch ( gicd_reg )
     {
-    case GICD_CTLR:
+    case VREG32(GICD_CTLR):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         vgic_lock(v);
         *r = vgic_reg32_extract(v->domain->arch.vgic.ctlr, info);
         vgic_unlock(v);
         return 1;
-    case GICD_TYPER:
+
+    case VREG32(GICD_TYPER):
     {
         /*
          * Number of interrupt identifier bits supported by the GIC
@@ -792,34 +832,39 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
 
         return 1;
     }
-    case GICD_STATUSR:
+
+    case VREG32(GICD_STATUSR):
         /*
          *  Optional, Not implemented for now.
          *  Update to support guest debugging.
          */
         goto read_as_zero_32;
-    case GICD_IIDR:
+
+    case VREG32(GICD_IIDR):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         *r = vgic_reg32_extract(GICV3_GICD_IIDR_VAL, info);
         return 1;
+
     case 0x020 ... 0x03c:
     case 0xc000 ... 0xffcc:
         /* Implementation defined -- read as zero */
         goto read_as_zero_32;
-    case GICD_IGROUPR ... GICD_IGROUPRN:
-    case GICD_ISENABLER ... GICD_ISENABLERN:
-    case GICD_ICENABLER ... GICD_ICENABLERN:
-    case GICD_ISPENDR ... GICD_ISPENDRN:
-    case GICD_ICPENDR ... GICD_ICPENDRN:
-    case GICD_ISACTIVER ... GICD_ISACTIVERN:
-    case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
-    case GICD_ICFGR ... GICD_ICFGRN:
+
+    case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
+    case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
+    case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):
+    case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
+    case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
+    case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN):
+    case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
+    case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
         /*
          * Above all register are common with GICR and GICD
          * Manage in common
          */
         return __vgic_v3_distr_common_mmio_read("vGICD", v, info, gicd_reg, r);
-    case GICD_IROUTER32 ... GICD_IROUTER1019:
+
+    case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
     {
         uint64_t irouter;
 
@@ -836,16 +881,19 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         return 1;
     }
 
-    case GICD_NSACR ... GICD_NSACRN:
+    case VRANGE32(GICD_NSACR, GICD_NSACRN):
         /* We do not implement security extensions for guests, read zero */
         goto read_as_zero_32;
-    case GICD_SGIR:
+
+    case VREG32(GICD_SGIR):
         /* Read as ICH_SGIR system register with SRE set. So ignore */
         goto read_as_zero_32;
-    case GICD_CPENDSGIR ... GICD_CPENDSGIRN:
+
+    case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
         /* Replaced with GICR_ICPENDR0. So ignore write */
         goto read_as_zero_32;
-    case GICD_SPENDSGIR ... GICD_SPENDSGIRN:
+
+    case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
         /* Replaced with GICR_ISPENDR0. So ignore write */
         goto read_as_zero_32;
 
@@ -853,7 +901,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         /* Implementation defined identification registers */
        goto read_impl_defined;
 
-    case GICD_PIDR2:
+    case VREG32(GICD_PIDR2):
         /* GICv3 identification value */
         if ( dabt.size != DABT_WORD ) goto bad_width;
         *r = vgic_reg32_extract(GICV3_GICD_PIDR2, info);
@@ -915,7 +963,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
 
     switch ( gicd_reg )
     {
-    case GICD_CTLR:
+    case VREG32(GICD_CTLR):
     {
         uint32_t ctlr = 0;
 
@@ -934,27 +982,35 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
 
         return 1;
     }
-    case GICD_TYPER:
+
+    case VREG32(GICD_TYPER):
         /* RO -- write ignored */
         goto write_ignore_32;
-    case GICD_IIDR:
+
+    case VREG32(GICD_IIDR):
         /* RO -- write ignored */
         goto write_ignore_32;
-    case GICD_STATUSR:
+
+    case VREG32(GICD_STATUSR):
         /* RO -- write ignored */
         goto write_ignore_32;
-    case GICD_SETSPI_NSR:
+
+    case VREG32(GICD_SETSPI_NSR):
         /* Message based SPI is not implemented */
         goto write_ignore_32;
-    case GICD_CLRSPI_NSR:
+
+    case VREG32(GICD_CLRSPI_NSR):
         /* Message based SPI is not implemented */
         goto write_ignore_32;
-    case GICD_SETSPI_SR:
+
+    case VREG32(GICD_SETSPI_SR):
         /* Message based SPI is not implemented */
         goto write_ignore_32;
-    case GICD_CLRSPI_SR:
+
+    case VREG32(GICD_CLRSPI_SR):
         /* Message based SPI is not implemented */
         goto write_ignore_32;
+
     case 0x020 ... 0x03c:
     case 0xc000 ... 0xffcc:
         /* Implementation defined -- write ignored */
@@ -962,20 +1018,22 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
                "%pv: vGICD: WI on implementation defined register offset %#08x\n",
                v, gicd_reg);
         goto write_ignore_32;
-    case GICD_IGROUPR ... GICD_IGROUPRN:
-    case GICD_ISENABLER ... GICD_ISENABLERN:
-    case GICD_ICENABLER ... GICD_ICENABLERN:
-    case GICD_ISPENDR ... GICD_ISPENDRN:
-    case GICD_ICPENDR ... GICD_ICPENDRN:
-    case GICD_ISACTIVER ... GICD_ISACTIVERN:
-    case GICD_ICACTIVER ... GICD_ICACTIVERN:
-    case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
-    case GICD_ICFGR ... GICD_ICFGRN:
+
+    case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
+    case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
+    case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):
+    case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
+    case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
+    case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN):
+    case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
+    case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
+    case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
         /* Above registers are common with GICR and GICD
          * Manage in common */
         return __vgic_v3_distr_common_mmio_write("vGICD", v, info,
                                                  gicd_reg, r);
-    case GICD_IROUTER32 ... GICD_IROUTER1019:
+
+    case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
     {
         uint64_t irouter;
 
@@ -991,17 +1049,20 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         return 1;
     }
 
-    case GICD_NSACR ... GICD_NSACRN:
+    case VRANGE32(GICD_NSACR, GICD_NSACRN):
         /* We do not implement security extensions for guests, write ignore */
         goto write_ignore_32;
-    case GICD_SGIR:
+
+    case VREG32(GICD_SGIR):
         /* it is accessed as system register in GICv3 */
         goto write_ignore_32;
-    case GICD_CPENDSGIR ... GICD_CPENDSGIRN:
+
+    case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
         /* Replaced with GICR_ICPENDR0. So ignore write */
         if ( dabt.size != DABT_WORD ) goto bad_width;
         return 0;
-    case GICD_SPENDSGIR ... GICD_SPENDSGIRN:
+
+    case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
         /* Replaced with GICR_ISPENDR0. So ignore write */
         if ( dabt.size != DABT_WORD ) goto bad_width;
         return 0;
@@ -1010,7 +1071,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         /* Implementation defined identification registers */
        goto write_impl_defined;
 
-    case GICD_PIDR2:
+    case VREG32(GICD_PIDR2):
         /* RO -- write ignore */
         goto write_ignore_32;
 
diff --git a/xen/include/asm-arm/vgic-emul.h b/xen/include/asm-arm/vgic-emul.h
new file mode 100644
index 0000000..184a1f0
--- /dev/null
+++ b/xen/include/asm-arm/vgic-emul.h
@@ -0,0 +1,24 @@
+#ifndef __ASM_ARM_VGIC_EMUL_H__
+#define __ASM_ARM_VGIC_EMUL_H__
+
+/*
+ * Helpers to create easily a case to match emulate a single register or
+ * a range of registers
+ */
+
+#define VREG32(reg) reg ... reg + 3
+#define VREG64(reg) reg ... reg + 7
+
+#define VRANGE32(start, end) start ... end + 3
+#define VRANGE64(start, end) start ... end + 7
+
+#endif /* __ASM_ARM_VGIC_EMUL_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 4/9] xen/arm: vgic-v3: Remove GICR_MOVALLR and GICR_MOVLPIR
  2015-11-13 11:54 [PATCH 0/9] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
                   ` (2 preceding siblings ...)
  2015-11-13 11:54 ` [PATCH 3/9] xen/arm: vgic: Properly emulate the full register Julien Grall
@ 2015-11-13 11:54 ` Julien Grall
  2015-11-16 13:33   ` Ian Campbell
  2015-11-13 11:54 ` [PATCH 5/9] xen/arm: vgic: Re-order the register emulations to match the memory map Julien Grall
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Julien Grall @ 2015-11-13 11:54 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini

The 2 registers are not described in the software spec (ARM IHI 0069A)
and their offsets are marked "implementation defined".

Signed-off-by: Julien Grall <julien.grall@citrix.com>

---

Note that I didn't combine the 2 cases because a follow-up patch
will add reserved registers between the 2 cases.
---
 xen/arch/arm/vgic-v3.c            | 20 ++++++++------------
 xen/include/asm-arm/gic_v3_defs.h |  2 --
 2 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 892104d..28f075a 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -241,13 +241,11 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
         *r = vgic_reg32_extract(GICR_SYNCR_NOT_BUSY, info);
         return 1;
 
-    case VREG64(GICR_MOVLPIR):
-        /* WO Read as zero */
-        goto read_as_zero_64;
+    case VREG64(0x0100):
+        goto read_impl_defined;
 
-    case VREG64(GICR_MOVALLR):
-        /* WO Read as zero */
-        goto read_as_zero_64;
+    case VREG64(0x0110):
+        goto read_impl_defined;
 
     case 0xFFD0 ... 0xFFE4:
         /* Implementation defined identification registers */
@@ -348,13 +346,11 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
         /* RO */
         goto write_ignore_32;
 
-    case VREG64(GICR_MOVLPIR):
-        /* LPI is not implemented */
-        goto write_ignore_64;
+    case VREG64(0x0100):
+        goto write_impl_defined;
 
-    case VREG64(GICR_MOVALLR):
-        /* LPI is not implemented */
-        goto write_ignore_64;
+    case VREG64(0x0110):
+        goto write_impl_defined;
 
     case 0xFFD0 ... 0xFFE4:
         /* Implementation defined identification registers */
diff --git a/xen/include/asm-arm/gic_v3_defs.h b/xen/include/asm-arm/gic_v3_defs.h
index 5a6938c..6d98491 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -77,8 +77,6 @@
 #define GICR_INVLPIR                 (0x00A0)
 #define GICR_INVALLR                 (0x00B0)
 #define GICR_SYNCR                   (0x00C0)
-#define GICR_MOVLPIR                 (0x100)
-#define GICR_MOVALLR                 (0x0110)
 #define GICR_PIDR2                   GICD_PIDR2
 
 /* GICR for SGI's & PPI's */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 5/9] xen/arm: vgic: Re-order the register emulations to match the memory map
  2015-11-13 11:54 [PATCH 0/9] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
                   ` (3 preceding siblings ...)
  2015-11-13 11:54 ` [PATCH 4/9] xen/arm: vgic-v3: Remove GICR_MOVALLR and GICR_MOVLPIR Julien Grall
@ 2015-11-13 11:54 ` Julien Grall
  2015-11-16 13:35   ` Ian Campbell
  2015-11-13 11:54 ` [PATCH 6/9] xen/arm: vgic-v3: Emulate read to GICD_ICACTIVER<n> Julien Grall
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Julien Grall @ 2015-11-13 11:54 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini

It helps to find quickly whether we forgot to emulate a register or not.

At the same time add the missing reserved/implementation defined
registers. All other missing registers will be added in a follow-up if
necessary.

Note that only the distributor register map explicitely say the
size of a register (see 8.8 in ARM IHI 0069A). When the size is not
known, the implementation defined/reserved may not be emulated
correctly.

Signed-off-by: Julien Grall <julien.grall@citrix.com>

---

Note that the reserved range after IROUTER<n> is overlapping in the
spec. It has been fixup in the code to avoid a build error.
---
 xen/arch/arm/vgic-v2.c | 177 ++++++++++++++++++-----------
 xen/arch/arm/vgic-v3.c | 298 +++++++++++++++++++++++++++++++++++--------------
 2 files changed, 328 insertions(+), 147 deletions(-)

diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index d1860a9..2c73133 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -210,9 +210,14 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         *r = vgic_reg32_extract(0x0000043b, info);
         return 1;
 
-    /* Implementation defined -- read as zero */
-    case 0x020 ... 0x03c:
-        goto read_as_zero;
+    case VRANGE32(0x00C, 0x01C):
+        goto read_reserved;
+
+    case VRANGE32(0x020, 0x03C):
+        goto read_impl_defined;
+
+    case VRANGE32(0x040, 0x07C):
+        goto read_reserved;
 
     case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
         /* We do not implement security extensions for guests, read zero */
@@ -246,21 +251,6 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
     case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
         goto read_as_zero;
 
-    case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSRN):
-    {
-        uint32_t itargetsr;
-
-        if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
-        rank = vgic_rank_offset(v, 8, gicd_reg - GICD_ITARGETSR, DABT_WORD);
-        if ( rank == NULL) goto read_as_zero;
-        vgic_lock_rank(v, rank, flags);
-        itargetsr = vgic_fetch_itargetsr(rank, gicd_reg - GICD_ITARGETSR);
-        vgic_unlock_rank(v, rank, flags);
-        *r = vgic_reg32_extract(itargetsr, info);
-
-        return 1;
-    }
-
     case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
     {
         uint32_t ipriorityr;
@@ -279,6 +269,27 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         return 1;
     }
 
+    case VREG32(0x7FC):
+        goto read_reserved;
+
+    case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSRN):
+    {
+        uint32_t itargetsr;
+
+        if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
+        rank = vgic_rank_offset(v, 8, gicd_reg - GICD_ITARGETSR, DABT_WORD);
+        if ( rank == NULL) goto read_as_zero;
+        vgic_lock_rank(v, rank, flags);
+        itargetsr = vgic_fetch_itargetsr(rank, gicd_reg - GICD_ITARGETSR);
+        vgic_unlock_rank(v, rank, flags);
+        *r = vgic_reg32_extract(itargetsr, info);
+
+        return 1;
+    }
+
+    case VREG32(0xBFC):
+        goto read_reserved;
+
     case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
     {
         uint32_t icfgr;
@@ -295,6 +306,9 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         return 1;
     }
 
+    case VRANGE32(0xD00, 0xDFC):
+        goto read_impl_defined;
+
     case VRANGE32(GICD_NSACR, GICD_NSACRN):
         /* We do not implement security extensions for guests, read zero */
         goto read_as_zero_32;
@@ -305,32 +319,27 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         *r = 0xdeadbeef;
         return 1;
 
+    case VRANGE32(0xF04, 0xF0C):
+        goto read_reserved;
+
     /* Setting/Clearing the SGI pending bit via GICD is not supported */
     case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
     case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
         goto read_as_zero;
 
-    /* Implementation defined -- read as zero */
-    case 0xfd0 ... 0xfe4:
-        goto read_as_zero;
+    case VRANGE32(0xF30, 0xFCC):
+        goto read_reserved;
+
+    case VRANGE32(0xFD0, 0xFE4):
+        goto read_impl_defined;
 
     case VREG32(GICD_ICPIDR2):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR "%pv: vGICD: unhandled read from ICPIDR2\n", v);
         return 0;
 
-    /* Implementation defined -- read as zero */
-    case 0xfec ... 0xffc:
-        goto read_as_zero;
-
-    /* Reserved -- read as zero */
-    case 0x00c ... 0x01c:
-    case 0x040 ... 0x07c:
-    case 0x7fc:
-    case 0xbfc:
-    case 0xf04 ... 0xf0c:
-    case 0xf30 ... 0xfcc:
-        goto read_as_zero;
+    case VRANGE32(0xFEC, 0xFFC):
+        goto read_impl_defined;
 
     default:
         printk(XENLOG_G_ERR "%pv: vGICD: unhandled read r%d offset %#08x\n",
@@ -349,6 +358,20 @@ read_as_zero_32:
 read_as_zero:
     *r = 0;
     return 1;
+
+read_impl_defined:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: RAZ on implemention defined register offset %#08x\n",
+           v, gicd_reg);
+    *r = 0;
+    return 1;
+
+read_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: RAZ on reserved register offset %#08x\n",
+           v, gicd_reg);
+    *r = 0;
+    return 1;
 }
 
 static int vgic_v2_to_sgi(struct vcpu *v, register_t sgir)
@@ -414,9 +437,14 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
     case VREG32(GICD_IIDR):
         goto write_ignore_32;
 
-    /* Implementation defined -- write ignored */
-    case 0x020 ... 0x03c:
-        goto write_ignore;
+    case VRANGE32(0x00C, 0x01C):
+        goto write_reserved;
+
+    case VRANGE32(0x020, 0x03C):
+        goto write_impl_defined;
+
+    case VRANGE32(0x040, 0x07C):
+        goto write_reserved;
 
     case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
         /* We do not implement security extensions for guests, write ignore */
@@ -472,6 +500,25 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
                v, r, gicd_reg - GICD_ICACTIVER);
         return 0;
 
+    case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
+    {
+        uint32_t *ipriorityr;
+
+        if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
+        rank = vgic_rank_offset(v, 8, gicd_reg - GICD_IPRIORITYR, DABT_WORD);
+        if ( rank == NULL) goto write_ignore;
+        vgic_lock_rank(v, rank, flags);
+        ipriorityr = &rank->ipriorityr[REG_RANK_INDEX(8,
+                                                      gicd_reg - GICD_IPRIORITYR,
+                                                      DABT_WORD)];
+        vgic_reg32_update(ipriorityr, r, info);
+        vgic_unlock_rank(v, rank, flags);
+        return 1;
+    }
+
+    case VREG32(0x7FC):
+        goto write_reserved;
+
     case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSR7):
         /* SGI/PPI target is read only */
         goto write_ignore_32;
@@ -492,21 +539,8 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         return 1;
     }
 
-    case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
-    {
-        uint32_t *ipriorityr;
-
-        if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
-        rank = vgic_rank_offset(v, 8, gicd_reg - GICD_IPRIORITYR, DABT_WORD);
-        if ( rank == NULL) goto write_ignore;
-        vgic_lock_rank(v, rank, flags);
-        ipriorityr = &rank->ipriorityr[REG_RANK_INDEX(8,
-                                                      gicd_reg - GICD_IPRIORITYR,
-                                                      DABT_WORD)];
-        vgic_reg32_update(ipriorityr, r, info);
-        vgic_unlock_rank(v, rank, flags);
-        return 1;
-    }
+    case VREG32(0xBFC):
+        goto write_reserved;
 
     case VREG32(GICD_ICFGR): /* SGIs */
         goto write_ignore_32;
@@ -526,6 +560,9 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         vgic_unlock_rank(v, rank, flags);
         return 1;
 
+    case VRANGE32(0xD00, 0xDFC):
+        goto write_impl_defined;
+
     case VRANGE32(GICD_NSACR, GICD_NSACRN):
         /* We do not implement security extensions for guests, write ignore */
         goto write_ignore_32;
@@ -534,6 +571,9 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         if ( dabt.size != DABT_WORD ) goto bad_width;
         return vgic_v2_to_sgi(v, r);
 
+    case VRANGE32(0xF04, 0xF0C):
+        goto write_reserved;
+
     case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
         if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
@@ -548,26 +588,19 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
                v, dabt.size ? "word" : "byte", r, gicd_reg - GICD_SPENDSGIR);
         return 0;
 
-    /* Implementation defined -- write ignored */
-    case 0xfd0 ... 0xfe4:
-        goto write_ignore;
+    case VRANGE32(0xF30, 0xFCC):
+        goto write_reserved;
+
+    case VRANGE32(0xFD0, 0xFE4):
+        /* Implementation defined identification registers */
+        goto write_impl_defined;
 
     /* R/O -- write ignore */
     case VREG32(GICD_ICPIDR2):
         goto write_ignore_32;
 
-    /* Implementation defined -- write ignored */
-    case 0xfec ... 0xffc:
-        goto write_ignore;
-
-    /* Reserved -- write ignored */
-    case 0x00c ... 0x01c:
-    case 0x040 ... 0x07c:
-    case 0x7fc:
-    case 0xbfc:
-    case 0xf04 ... 0xf0c:
-    case 0xf30 ... 0xfcc:
-        goto write_ignore;
+    case VRANGE32(0xFEC, 0xFFC):
+        /* Implementation defined identification registers */
 
     default:
         printk(XENLOG_G_ERR
@@ -587,6 +620,18 @@ write_ignore_32:
     if ( dabt.size != DABT_WORD ) goto bad_width;
 write_ignore:
     return 1;
+
+write_impl_defined:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: WI on implementation defined register offset %#08x\n",
+           v, gicd_reg);
+    return 1;
+
+write_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: WI on implementation defined register offset %#08x\n",
+           v, gicd_reg);
+    return 1;
 }
 
 static const struct mmio_handler_ops vgic_v2_distr_mmio_handler = {
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 28f075a..f9d8ecb 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -210,6 +210,12 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
         /* Power management is not implemented */
         goto read_as_zero_32;
 
+    case 0x0018:
+        goto read_reserved;
+
+    case 0x0020:
+        goto read_impl_defined;
+
     case VREG64(GICR_SETLPIR):
         /* WO. Read as zero */
         goto read_as_zero_64;
@@ -218,6 +224,9 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
         /* WO. Read as zero */
         goto read_as_zero_64;
 
+    case 0x0050:
+        goto read_reserved;
+
     case VREG64(GICR_PROPBASER):
         /* LPI's not implemented */
         goto read_as_zero_64;
@@ -226,27 +235,48 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
         /* LPI's not implemented */
         goto read_as_zero_64;
 
+    case 0x0080:
+        goto read_reserved;
+
     case VREG64(GICR_INVLPIR):
         /* WO. Read as zero */
         goto read_as_zero_64;
 
+    case 0x00A8:
+        goto read_reserved;
+
     case VREG64(GICR_INVALLR):
         /* WO. Read as zero */
         goto read_as_zero_64;
         return 0;
 
+    case 0x00B8:
+        goto read_reserved;
+
     case VREG32(GICR_SYNCR):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         /* RO . But when read it always returns busy bito bit[0] */
         *r = vgic_reg32_extract(GICR_SYNCR_NOT_BUSY, info);
         return 1;
 
+    case 0x00C8:
+        goto read_reserved;
+
     case VREG64(0x0100):
         goto read_impl_defined;
 
+    case 0x0108:
+        goto read_reserved;
+
     case VREG64(0x0110):
         goto read_impl_defined;
 
+    case 0x0118 ... 0xBFFC:
+        goto read_reserved;
+
+    case 0xC000 ... 0xFFCC:
+        goto read_impl_defined;
+
     case 0xFFD0 ... 0xFFE4:
         /* Implementation defined identification registers */
        goto read_impl_defined;
@@ -284,7 +314,14 @@ read_as_zero_32:
 
 read_impl_defined:
     printk(XENLOG_G_DEBUG
-           "%pv: vGICR: RAZ on implemention defined register offset %#08x\n",
+           "%pv: vGICR: RAZ on implementation defined register offset %#08x\n",
+           v, gicr_reg);
+    *r = 0;
+    return 1;
+
+read_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICR: RAZ on reserved register offset %#08x\n",
            v, gicr_reg);
     *r = 0;
     return 1;
@@ -318,6 +355,12 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
         /* Power mgmt not implemented */
         goto write_ignore_32;
 
+    case 0x0018:
+        goto write_reserved;
+
+    case 0x0020:
+        goto write_impl_defined;
+
     case VREG64(GICR_SETLPIR):
         /* LPI is not implemented */
         goto write_ignore_64;
@@ -326,6 +369,9 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
         /* LPI is not implemented */
         goto write_ignore_64;
 
+    case 0x0050:
+        goto write_reserved;
+
     case VREG64(GICR_PROPBASER):
         /* LPI is not implemented */
         goto write_ignore_64;
@@ -334,24 +380,45 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
         /* LPI is not implemented */
         goto write_ignore_64;
 
+    case 0x0080:
+        goto write_reserved;
+
     case VREG64(GICR_INVLPIR):
         /* LPI is not implemented */
         goto write_ignore_64;
 
+    case 0x00A8:
+        goto write_reserved;
+
     case VREG64(GICR_INVALLR):
         /* LPI is not implemented */
         goto write_ignore_64;
 
+    case 0x00B8:
+        goto write_reserved;
+
     case VREG32(GICR_SYNCR):
         /* RO */
         goto write_ignore_32;
 
+    case 0x00C8:
+        goto write_reserved;
+
     case VREG64(0x0100):
         goto write_impl_defined;
 
+    case 0x0108:
+        goto write_reserved;
+
     case VREG64(0x0110):
         goto write_impl_defined;
 
+    case 0x0118 ... 0xBFFC:
+        goto write_reserved;
+
+    case 0xC000 ... 0xFFCC:
+        goto write_impl_defined;
+
     case 0xFFD0 ... 0xFFE4:
         /* Implementation defined identification registers */
        goto write_impl_defined;
@@ -389,6 +456,12 @@ write_impl_defined:
            "%pv: vGICR: WI on implementation defined register offset %#08x\n",
            v, gicr_reg);
     return 1;
+
+write_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICR: WI on reserved register offset %#08x\n",
+           v, gicr_reg);
+    return 1;
 }
 
 static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
@@ -609,10 +682,6 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info,
 
     switch ( gicr_reg )
     {
-    case VREG32(GICR_IGRPMODR0):
-        /* We do not implement security extensions for guests, read zero */
-        goto read_as_zero_32;
-
     case VREG32(GICR_IGROUPR0):
     case VREG32(GICR_ISENABLER0):
     case VREG32(GICR_ICENABLER0):
@@ -632,10 +701,23 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info,
     case VREG32(GICR_ICPENDR0):
         goto read_as_zero;
 
+    case VREG32(GICR_IGRPMODR0):
+        /* We do not implement security extensions for guests, read zero */
+        goto read_as_zero_32;
+
     case VREG32(GICR_NSACR):
         /* We do not implement security extensions for guests, read zero */
         goto read_as_zero_32;
 
+    case 0x0E04 ... 0xBFFC:
+        goto read_reserved;
+
+    case 0xC000 ... 0xFFCC:
+        goto read_impl_defined;
+
+    case 0xFFD0 ... 0xFFFC:
+        goto read_reserved;
+
     default:
         printk(XENLOG_G_ERR
                "%pv: vGICR: SGI: unhandled read r%d offset %#08x\n",
@@ -653,6 +735,21 @@ read_as_zero_32:
 read_as_zero:
     *r = 0;
     return 1;
+
+read_impl_defined:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICR: SGI: RAZ on implementation defined register offset %#08x\n",
+           v, gicr_reg);
+    *r = 0;
+    return 1;
+
+read_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICR: SGI: RAZ on reserved register offset %#08x\n",
+           v, gicr_reg);
+    *r = 0;
+    return 1;
+
 }
 
 static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info,
@@ -662,10 +759,6 @@ static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info,
 
     switch ( gicr_reg )
     {
-    case VREG32(GICR_IGRPMODR0):
-        /* We do not implement security extensions for guests, write ignore */
-        goto write_ignore_32;
-
     case VREG32(GICR_IGROUPR0):
     case VREG32(GICR_ISENABLER0):
     case VREG32(GICR_ICENABLER0):
@@ -694,6 +787,11 @@ static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info,
                v, r);
         return 0;
 
+    case VREG32(GICR_IGRPMODR0):
+        /* We do not implement security extensions for guests, write ignore */
+        goto write_ignore_32;
+
+
     case VREG32(GICR_NSACR):
         /* We do not implement security extensions for guests, write ignore */
         goto write_ignore_32;
@@ -829,6 +927,14 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         return 1;
     }
 
+    case VREG32(GICD_IIDR):
+        if ( dabt.size != DABT_WORD ) goto bad_width;
+        *r = vgic_reg32_extract(GICV3_GICD_IIDR_VAL, info);
+        return 1;
+
+    case VREG32(0x000C):
+        goto read_reserved;
+
     case VREG32(GICD_STATUSR):
         /*
          *  Optional, Not implemented for now.
@@ -836,15 +942,23 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
          */
         goto read_as_zero_32;
 
-    case VREG32(GICD_IIDR):
-        if ( dabt.size != DABT_WORD ) goto bad_width;
-        *r = vgic_reg32_extract(GICV3_GICD_IIDR_VAL, info);
-        return 1;
+    case VRANGE32(0x0014, 0x001C):
+        goto read_reserved;
 
-    case 0x020 ... 0x03c:
-    case 0xc000 ... 0xffcc:
-        /* Implementation defined -- read as zero */
-        goto read_as_zero_32;
+    case VRANGE32(0x0020, 0x003C):
+        goto read_impl_defined;
+
+    case VREG32(0x0044):
+        goto read_reserved;
+
+    case VREG32(0x004C):
+        goto read_reserved;
+
+    case VREG32(0x0054):
+        goto read_reserved;
+
+    case VRANGE32(0x005C, 0x007C):
+        goto read_reserved;
 
     case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
     case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
@@ -860,6 +974,25 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
          */
         return __vgic_v3_distr_common_mmio_read("vGICD", v, info, gicd_reg, r);
 
+    case VRANGE32(GICD_NSACR, GICD_NSACRN):
+        /* We do not implement security extensions for guests, read zero */
+        goto read_as_zero_32;
+
+    case VREG32(GICD_SGIR):
+        /* Read as ICH_SGIR system register with SRE set. So ignore */
+        goto read_as_zero_32;
+
+    case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
+        /* Replaced with GICR_ICPENDR0. So ignore write */
+        goto read_as_zero_32;
+
+    case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
+        /* Replaced with GICR_ISPENDR0. So ignore write */
+        goto read_as_zero_32;
+
+    case VRANGE32(0x0F30, 0x60FC):
+        goto read_reserved;
+
     case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
     {
         uint64_t irouter;
@@ -877,23 +1010,13 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         return 1;
     }
 
-    case VRANGE32(GICD_NSACR, GICD_NSACRN):
-        /* We do not implement security extensions for guests, read zero */
-        goto read_as_zero_32;
+    case VRANGE32(0x7FE0, 0xBFFC):
+        goto read_reserved;
 
-    case VREG32(GICD_SGIR):
-        /* Read as ICH_SGIR system register with SRE set. So ignore */
-        goto read_as_zero_32;
-
-    case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
-        /* Replaced with GICR_ICPENDR0. So ignore write */
-        goto read_as_zero_32;
-
-    case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
-        /* Replaced with GICR_ISPENDR0. So ignore write */
-        goto read_as_zero_32;
+    case VRANGE32(0xC000, 0xFFCC):
+        goto read_impl_defined;
 
-    case 0xFFD0 ... 0xFFE4:
+    case VRANGE32(0xFFD0, 0xFFE4):
         /* Implementation defined identification registers */
        goto read_impl_defined;
 
@@ -903,21 +1026,10 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         *r = vgic_reg32_extract(GICV3_GICD_PIDR2, info);
         return 1;
 
-    case 0xFFEC ... 0xFFFC:
+    case VRANGE32(0xFFEC, 0xFFFC):
          /* Implementation defined identification registers */
          goto read_impl_defined;
 
-    case 0x00c:
-    case 0x044:
-    case 0x04c:
-    case 0x05c ... 0x07c:
-    case 0xf30 ... 0x5fcc:
-    case 0x8000 ... 0xbfcc:
-        /* These are reserved register addresses */
-        printk(XENLOG_G_DEBUG
-               "%pv: vGICD: RAZ on reserved register offset %#08x\n",
-               v, gicd_reg);
-        goto read_as_zero;
     default:
         printk(XENLOG_G_ERR "%pv: vGICD: unhandled read r%d offset %#08x\n",
                v, dabt.reg, gicd_reg);
@@ -941,7 +1053,14 @@ read_as_zero:
 
 read_impl_defined:
     printk(XENLOG_G_DEBUG
-           "%pv: vGICD: RAZ on implemention defined register offset %#08x\n",
+           "%pv: vGICD: RAZ on implementation defined register offset %#08x\n",
+           v, gicd_reg);
+    *r = 0;
+    return 1;
+
+read_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: RAZ on reserved register offset %#08x\n",
            v, gicd_reg);
     *r = 0;
     return 1;
@@ -987,33 +1106,46 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         /* RO -- write ignored */
         goto write_ignore_32;
 
+    case VREG32(0x000C):
+        goto write_reserved;
+
     case VREG32(GICD_STATUSR):
         /* RO -- write ignored */
         goto write_ignore_32;
 
+    case VRANGE32(0x0014, 0x001C):
+        goto write_reserved;
+
+    case VRANGE32(0x0020, 0x003C):
+        goto write_impl_defined;
+
     case VREG32(GICD_SETSPI_NSR):
         /* Message based SPI is not implemented */
         goto write_ignore_32;
 
+    case VREG32(0x0044):
+        goto write_reserved;
+
     case VREG32(GICD_CLRSPI_NSR):
         /* Message based SPI is not implemented */
         goto write_ignore_32;
 
+    case VREG32(0x004C):
+        goto write_reserved;
+
     case VREG32(GICD_SETSPI_SR):
         /* Message based SPI is not implemented */
         goto write_ignore_32;
 
+    case VREG32(0x0054):
+        goto write_reserved;
+
     case VREG32(GICD_CLRSPI_SR):
         /* Message based SPI is not implemented */
         goto write_ignore_32;
 
-    case 0x020 ... 0x03c:
-    case 0xc000 ... 0xffcc:
-        /* Implementation defined -- write ignored */
-        printk(XENLOG_G_DEBUG
-               "%pv: vGICD: WI on implementation defined register offset %#08x\n",
-               v, gicd_reg);
-        goto write_ignore_32;
+    case VRANGE32(0x005C, 0x007C):
+        goto write_reserved;
 
     case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
     case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
@@ -1029,22 +1161,6 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         return __vgic_v3_distr_common_mmio_write("vGICD", v, info,
                                                  gicd_reg, r);
 
-    case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
-    {
-        uint64_t irouter;
-
-        if ( !vgic_reg64_check_access(dabt) ) goto bad_width;
-        rank = vgic_rank_offset(v, 64, gicd_reg - GICD_IROUTER,
-                                DABT_DOUBLE_WORD);
-        if ( rank == NULL ) goto write_ignore;
-        vgic_lock_rank(v, rank, flags);
-        irouter = vgic_fetch_irouter(rank, gicd_reg - GICD_IROUTER);
-        vgic_reg64_update(&irouter, r, info);
-        vgic_store_irouter(v->domain, rank, gicd_reg - GICD_IROUTER, irouter);
-        vgic_unlock_rank(v, rank, flags);
-        return 1;
-    }
-
     case VRANGE32(GICD_NSACR, GICD_NSACRN):
         /* We do not implement security extensions for guests, write ignore */
         goto write_ignore_32;
@@ -1063,7 +1179,32 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         if ( dabt.size != DABT_WORD ) goto bad_width;
         return 0;
 
-    case 0xFFD0 ... 0xFFE4:
+    case VRANGE32(0x0F30, 0x60FC):
+        goto write_reserved;
+
+    case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
+    {
+        uint64_t irouter;
+
+        if ( !vgic_reg64_check_access(dabt) ) goto bad_width;
+        rank = vgic_rank_offset(v, 64, gicd_reg - GICD_IROUTER,
+                                DABT_DOUBLE_WORD);
+        if ( rank == NULL ) goto write_ignore;
+        vgic_lock_rank(v, rank, flags);
+        irouter = vgic_fetch_irouter(rank, gicd_reg - GICD_IROUTER);
+        vgic_reg64_update(&irouter, r, info);
+        vgic_store_irouter(v->domain, rank, gicd_reg - GICD_IROUTER, irouter);
+        vgic_unlock_rank(v, rank, flags);
+        return 1;
+    }
+
+    case VRANGE32(0x7FE0, 0xBFFC):
+        goto write_reserved;
+
+    case VRANGE32(0xC000, 0xFFCC):
+        goto write_impl_defined;
+
+    case VRANGE32(0xFFD0, 0xFFE4):
         /* Implementation defined identification registers */
        goto write_impl_defined;
 
@@ -1071,21 +1212,10 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         /* RO -- write ignore */
         goto write_ignore_32;
 
-    case 0xFFEC ... 0xFFFC:
+    case VRANGE32(0xFFEC, 0xFFFC):
          /* Implementation defined identification registers */
          goto write_impl_defined;
 
-    case 0x00c:
-    case 0x044:
-    case 0x04c:
-    case 0x05c ... 0x07c:
-    case 0xf30 ... 0x5fcc:
-    case 0x8000 ... 0xbfcc:
-        /* Reserved register addresses */
-        printk(XENLOG_G_DEBUG
-               "%pv: vGICD: write unknown 0x00c 0xfcc  r%d offset %#08x\n",
-               v, dabt.reg, gicd_reg);
-        goto write_ignore;
     default:
         printk(XENLOG_G_ERR
                "%pv: vGICD: unhandled write r%d=%"PRIregister" offset %#08x\n",
@@ -1112,6 +1242,12 @@ write_impl_defined:
            "%pv: vGICD: WI on implementation defined register offset %#08x\n",
            v, gicd_reg);
     return 1;
+
+write_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: WI on reserved register offset %#08x\n",
+           v, gicd_reg);
+    return 1;
 }
 
 static int vgic_v3_to_sgi(struct vcpu *v, register_t sgir)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 6/9] xen/arm: vgic-v3: Emulate read to GICD_ICACTIVER<n>
  2015-11-13 11:54 [PATCH 0/9] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
                   ` (4 preceding siblings ...)
  2015-11-13 11:54 ` [PATCH 5/9] xen/arm: vgic: Re-order the register emulations to match the memory map Julien Grall
@ 2015-11-13 11:54 ` Julien Grall
  2015-11-16 13:36   ` Ian Campbell
  2015-11-13 11:54 ` [PATCH 7/9] xen/arm: vgic-v3: Remove spurious return in GICR_INVALLR Julien Grall
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Julien Grall @ 2015-11-13 11:54 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini

The GICD_ICACTIVER<n> registers are missing in the read emulation of the
distributor.

Call the common emulation for the whole range.

Signed-off-by: Julien Grall <julien.grall@citrix.com>
---
 xen/arch/arm/vgic-v3.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index f9d8ecb..98104ba 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -966,6 +966,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
     case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):
     case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):
     case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN):
+    case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
     case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
     case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
         /*
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 7/9] xen/arm: vgic-v3: Remove spurious return in GICR_INVALLR
  2015-11-13 11:54 [PATCH 0/9] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
                   ` (5 preceding siblings ...)
  2015-11-13 11:54 ` [PATCH 6/9] xen/arm: vgic-v3: Emulate read to GICD_ICACTIVER<n> Julien Grall
@ 2015-11-13 11:54 ` Julien Grall
  2015-11-16 13:36   ` Ian Campbell
  2015-11-13 11:54 ` [PATCH 8/9] xen/arm: vgic-v3: Don't implement write-only register read as zero Julien Grall
  2015-11-13 11:54 ` [PATCH 9/9] xen/arm: vgic-v3: Make clear that GICD_*SPI_* registers are reserved Julien Grall
  8 siblings, 1 reply; 21+ messages in thread
From: Julien Grall @ 2015-11-13 11:54 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini

Signed-off-by: Julien Grall <julien.grall@citrix.com>
---
 xen/arch/arm/vgic-v3.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 98104ba..c68afdb 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -248,7 +248,6 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
     case VREG64(GICR_INVALLR):
         /* WO. Read as zero */
         goto read_as_zero_64;
-        return 0;
 
     case 0x00B8:
         goto read_reserved;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 8/9] xen/arm: vgic-v3: Don't implement write-only register read as zero
  2015-11-13 11:54 [PATCH 0/9] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
                   ` (6 preceding siblings ...)
  2015-11-13 11:54 ` [PATCH 7/9] xen/arm: vgic-v3: Remove spurious return in GICR_INVALLR Julien Grall
@ 2015-11-13 11:54 ` Julien Grall
  2015-11-16 13:37   ` Ian Campbell
  2015-11-13 11:54 ` [PATCH 9/9] xen/arm: vgic-v3: Make clear that GICD_*SPI_* registers are reserved Julien Grall
  8 siblings, 1 reply; 21+ messages in thread
From: Julien Grall @ 2015-11-13 11:54 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini

A read to a write only register is unknown. Use a memorable value to
differentiate from an actual RAZ register.

Signed-off-by: Julien Grall <julien.grall@citrix.com>
---
 xen/arch/arm/vgic-v3.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index c68afdb..44e926a 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -217,12 +217,12 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
         goto read_impl_defined;
 
     case VREG64(GICR_SETLPIR):
-        /* WO. Read as zero */
-        goto read_as_zero_64;
+        /* WO. Read unknown */
+        goto read_unknown;
 
     case VREG64(GICR_CLRLPIR):
-        /* WO. Read as zero */
-        goto read_as_zero_64;
+        /* WO. Read unknown */
+        goto read_unknown;
 
     case 0x0050:
         goto read_reserved;
@@ -239,15 +239,15 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
         goto read_reserved;
 
     case VREG64(GICR_INVLPIR):
-        /* WO. Read as zero */
-        goto read_as_zero_64;
+        /* WO. Read unknown */
+        goto read_unknown;
 
     case 0x00A8:
         goto read_reserved;
 
     case VREG64(GICR_INVALLR):
-        /* WO. Read as zero */
-        goto read_as_zero_64;
+        /* WO. Read unknown */
+        goto read_unknown;
 
     case 0x00B8:
         goto read_reserved;
@@ -324,6 +324,10 @@ read_reserved:
            v, gicr_reg);
     *r = 0;
     return 1;
+
+read_unknown:
+    *r = vgic_reg64_extract(0xdeadbeafdeadbeaf, info);
+    return 1;
 }
 
 static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 9/9] xen/arm: vgic-v3: Make clear that GICD_*SPI_* registers are reserved
  2015-11-13 11:54 [PATCH 0/9] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
                   ` (7 preceding siblings ...)
  2015-11-13 11:54 ` [PATCH 8/9] xen/arm: vgic-v3: Don't implement write-only register read as zero Julien Grall
@ 2015-11-13 11:54 ` Julien Grall
  2015-11-16 13:39   ` Ian Campbell
  8 siblings, 1 reply; 21+ messages in thread
From: Julien Grall @ 2015-11-13 11:54 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini

Our vGIC emulation have GICD_TYPER.MBIS set to 0 which means that
GICD_*SPI_* registers are reserved. Implement them using the *_reserved
labels.

Also, implement thoses registers for the read part.

Signed-off-by: Julien Grall <julien.grall@citrix.com>
---
 xen/arch/arm/vgic-v3.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 44e926a..985e866 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -951,15 +951,31 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
     case VRANGE32(0x0020, 0x003C):
         goto read_impl_defined;
 
+    case VREG32(GICD_SETSPI_NSR):
+        /* Message based SPI is not implemented */
+        goto read_reserved;
+
     case VREG32(0x0044):
         goto read_reserved;
 
+    case VREG32(GICD_CLRSPI_NSR):
+        /* Message based SPI is not implemented */
+        goto read_reserved;
+
     case VREG32(0x004C):
         goto read_reserved;
 
+    case VREG32(GICD_SETSPI_SR):
+        /* Message based SPI is not implemented */
+        goto read_reserved;
+
     case VREG32(0x0054):
         goto read_reserved;
 
+    case VREG32(GICD_CLRSPI_SR):
+        /* Message based SPI is not implemented */
+        goto read_reserved;
+
     case VRANGE32(0x005C, 0x007C):
         goto read_reserved;
 
@@ -1125,28 +1141,28 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
 
     case VREG32(GICD_SETSPI_NSR):
         /* Message based SPI is not implemented */
-        goto write_ignore_32;
+        goto write_reserved;
 
     case VREG32(0x0044):
         goto write_reserved;
 
     case VREG32(GICD_CLRSPI_NSR):
         /* Message based SPI is not implemented */
-        goto write_ignore_32;
+        goto write_reserved;
 
     case VREG32(0x004C):
         goto write_reserved;
 
     case VREG32(GICD_SETSPI_SR):
         /* Message based SPI is not implemented */
-        goto write_ignore_32;
+        goto write_reserved;
 
     case VREG32(0x0054):
         goto write_reserved;
 
     case VREG32(GICD_CLRSPI_SR):
         /* Message based SPI is not implemented */
-        goto write_ignore_32;
+        goto write_reserved;
 
     case VRANGE32(0x005C, 0x007C):
         goto write_reserved;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/9] xen/arm: vgic-v3: Use the correct offset GICR_IGRPMODR0
  2015-11-13 11:54 ` [PATCH 1/9] xen/arm: vgic-v3: Use the correct offset GICR_IGRPMODR0 Julien Grall
@ 2015-11-16 13:20   ` Ian Campbell
  0 siblings, 0 replies; 21+ messages in thread
From: Ian Campbell @ 2015-11-16 13:20 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: stefano.stabellini

On Fri, 2015-11-13 at 11:54 +0000, Julien Grall wrote:
> The offset is 0x0D00 and not 0x0F80.
> 
> Also re-order the definition to keep all the definitions ordered.
> 
> Signed-off-by: Julien Grall <julien.grall@citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 2/9] xen/arm: vgic-v3: Only emulate identification registers requested by the spec
  2015-11-13 11:54 ` [PATCH 2/9] xen/arm: vgic-v3: Only emulate identification registers requested by the spec Julien Grall
@ 2015-11-16 13:27   ` Ian Campbell
  2015-11-18 16:46     ` Julien Grall
  0 siblings, 1 reply; 21+ messages in thread
From: Ian Campbell @ 2015-11-16 13:27 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: stefano.stabellini

On Fri, 2015-11-13 at 11:54 +0000, Julien Grall wrote:
> Most of the identification registers space contains implementation
> defined registers (see 8.1.13 in ARM IHI 0069A) and only GIC{D,R}_PIDR2
> is required to be implemented.

I think you mean s/requested/required/ in the subject too?

> 
> Currently the emulation of those registers mimic the ARM implementation,
> but it's untrue to say that we properly emulate a such implementation.
> 
> Keep only GIC{D,R}_PIDR2 implemented with the "implementationd defined

"implementation"

> bits" to zero and the ArchRev field (bits[7:4]) to 0x3 as we emulate a
> GICv3.
> 
> Note that the emulation of the range wasn't valid anyway because the
> registers are split in 2 sets (PIDR4-PIDR7 and PIDR0-PIDR2).
> 
> Signed-off-by: Julien Grall <julien.grall@citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 3/9] xen/arm: vgic: Properly emulate the full register
  2015-11-13 11:54 ` [PATCH 3/9] xen/arm: vgic: Properly emulate the full register Julien Grall
@ 2015-11-16 13:29   ` Ian Campbell
  0 siblings, 0 replies; 21+ messages in thread
From: Ian Campbell @ 2015-11-16 13:29 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: stefano.stabellini

On Fri, 2015-11-13 at 11:54 +0000, Julien Grall wrote:
> The offset in the emulation is based on byte. As most of the registers
> are 64/32 bits, they will span over multiple bytes.
> 
> However, the current emulation only care about the first offset. This

"cares"

> will result to not emulate properly any access on the register with

"This results in not properly emulating ... with any other offset"

> other offset.
> 
> Introduce new macros to help implementing access on multiple byte and
> use them over the vGIC emulation.
> 
> Note that I didn't convert the reserved/implementation defined
> registers. It will be done in a follow-up.
> 
> Signed-off-by: Julien Grall <julien.grall@citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/9] xen/arm: vgic-v3: Remove GICR_MOVALLR and GICR_MOVLPIR
  2015-11-13 11:54 ` [PATCH 4/9] xen/arm: vgic-v3: Remove GICR_MOVALLR and GICR_MOVLPIR Julien Grall
@ 2015-11-16 13:33   ` Ian Campbell
  2015-11-18 16:58     ` Julien Grall
  0 siblings, 1 reply; 21+ messages in thread
From: Ian Campbell @ 2015-11-16 13:33 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: stefano.stabellini

On Fri, 2015-11-13 at 11:54 +0000, Julien Grall wrote:
> The 2 registers are not described in the software spec (ARM IHI 0069A)
> and their offsets are marked "implementation defined".

They do exist in "PRD03-GENC-010745 24.0", in that they are mentioned as
having corresponding completion bits in GICR_SYNCR in that version, but
seem to never be defined themselves. I suppose they were a remnant of an
older spec. No need to discuss that in the commit message though.

> 
> Signed-off-by: Julien Grall <julien.grall@citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>


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

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 5/9] xen/arm: vgic: Re-order the register emulations to match the memory map
  2015-11-13 11:54 ` [PATCH 5/9] xen/arm: vgic: Re-order the register emulations to match the memory map Julien Grall
@ 2015-11-16 13:35   ` Ian Campbell
  0 siblings, 0 replies; 21+ messages in thread
From: Ian Campbell @ 2015-11-16 13:35 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: stefano.stabellini

On Fri, 2015-11-13 at 11:54 +0000, Julien Grall wrote:
> It helps to find quickly whether we forgot to emulate a register or not.
> 
> At the same time add the missing reserved/implementation defined
> registers. All other missing registers will be added in a follow-up if
> necessary.
> 
> Note that only the distributor register map explicitely say the
> size of a register (see 8.8 in ARM IHI 0069A). When the size is not
> known, the implementation defined/reserved may not be emulated
> correctly.
> 
> Signed-off-by: Julien Grall <julien.grall@citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 6/9] xen/arm: vgic-v3: Emulate read to GICD_ICACTIVER<n>
  2015-11-13 11:54 ` [PATCH 6/9] xen/arm: vgic-v3: Emulate read to GICD_ICACTIVER<n> Julien Grall
@ 2015-11-16 13:36   ` Ian Campbell
  0 siblings, 0 replies; 21+ messages in thread
From: Ian Campbell @ 2015-11-16 13:36 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: stefano.stabellini

On Fri, 2015-11-13 at 11:54 +0000, Julien Grall wrote:
> The GICD_ICACTIVER<n> registers are missing in the read emulation of the
> distributor.
> 
> Call the common emulation for the whole range.
> 
> Signed-off-by: Julien Grall <julien.grall@citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 7/9] xen/arm: vgic-v3: Remove spurious return in GICR_INVALLR
  2015-11-13 11:54 ` [PATCH 7/9] xen/arm: vgic-v3: Remove spurious return in GICR_INVALLR Julien Grall
@ 2015-11-16 13:36   ` Ian Campbell
  0 siblings, 0 replies; 21+ messages in thread
From: Ian Campbell @ 2015-11-16 13:36 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: stefano.stabellini

On Fri, 2015-11-13 at 11:54 +0000, Julien Grall wrote:
> Signed-off-by: Julien Grall <julien.grall@citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 8/9] xen/arm: vgic-v3: Don't implement write-only register read as zero
  2015-11-13 11:54 ` [PATCH 8/9] xen/arm: vgic-v3: Don't implement write-only register read as zero Julien Grall
@ 2015-11-16 13:37   ` Ian Campbell
  0 siblings, 0 replies; 21+ messages in thread
From: Ian Campbell @ 2015-11-16 13:37 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: stefano.stabellini

On Fri, 2015-11-13 at 11:54 +0000, Julien Grall wrote:
> A read to a write only register is unknown. Use a memorable value to
> differentiate from an actual RAZ register.

Shame it's the same memorable value as every other memorable value in the
world ;-)

> Signed-off-by: Julien Grall <julien.grall@citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 9/9] xen/arm: vgic-v3: Make clear that GICD_*SPI_* registers are reserved
  2015-11-13 11:54 ` [PATCH 9/9] xen/arm: vgic-v3: Make clear that GICD_*SPI_* registers are reserved Julien Grall
@ 2015-11-16 13:39   ` Ian Campbell
  0 siblings, 0 replies; 21+ messages in thread
From: Ian Campbell @ 2015-11-16 13:39 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: stefano.stabellini

On Fri, 2015-11-13 at 11:54 +0000, Julien Grall wrote:
> Our vGIC emulation have GICD_TYPER.MBIS set to 0 which means that
> GICD_*SPI_* registers are reserved. Implement them using the *_reserved
> labels.
> 
> Also, implement thoses registers for the read part.

"those" ("these" might be better though)

> 
> Signed-off-by: Julien Grall <julien.grall@citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 2/9] xen/arm: vgic-v3: Only emulate identification registers requested by the spec
  2015-11-16 13:27   ` Ian Campbell
@ 2015-11-18 16:46     ` Julien Grall
  0 siblings, 0 replies; 21+ messages in thread
From: Julien Grall @ 2015-11-18 16:46 UTC (permalink / raw)
  To: Ian Campbell, xen-devel; +Cc: stefano.stabellini

Hi Ian,

On 16/11/15 13:27, Ian Campbell wrote:
> On Fri, 2015-11-13 at 11:54 +0000, Julien Grall wrote:
>> Most of the identification registers space contains implementation
>> defined registers (see 8.1.13 in ARM IHI 0069A) and only GIC{D,R}_PIDR2
>> is required to be implemented.
> 
> I think you mean s/requested/required/ in the subject too?

Right, I will fix it in the next version.

>>
>> Currently the emulation of those registers mimic the ARM implementation,
>> but it's untrue to say that we properly emulate a such implementation.
>>
>> Keep only GIC{D,R}_PIDR2 implemented with the "implementationd defined
> 
> "implementation"
> 
>> bits" to zero and the ArchRev field (bits[7:4]) to 0x3 as we emulate a
>> GICv3.
>>
>> Note that the emulation of the range wasn't valid anyway because the
>> registers are split in 2 sets (PIDR4-PIDR7 and PIDR0-PIDR2).
>>
>> Signed-off-by: Julien Grall <julien.grall@citrix.com>
> 
> Acked-by: Ian Campbell <ian.campbell@citrix.com>

Thank you!

Regards,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/9] xen/arm: vgic-v3: Remove GICR_MOVALLR and GICR_MOVLPIR
  2015-11-16 13:33   ` Ian Campbell
@ 2015-11-18 16:58     ` Julien Grall
  0 siblings, 0 replies; 21+ messages in thread
From: Julien Grall @ 2015-11-18 16:58 UTC (permalink / raw)
  To: Ian Campbell, xen-devel; +Cc: stefano.stabellini

Hi Ian,

On 16/11/15 13:33, Ian Campbell wrote:
> On Fri, 2015-11-13 at 11:54 +0000, Julien Grall wrote:
>> The 2 registers are not described in the software spec (ARM IHI 0069A)
>> and their offsets are marked "implementation defined".
> 
> They do exist in "PRD03-GENC-010745 24.0", in that they are mentioned as
> having corresponding completion bits in GICR_SYNCR in that version, but
> seem to never be defined themselves. I suppose they were a remnant of an
> older spec. No need to discuss that in the commit message though.

At the end of the GICR_SYNCR section the spec says that this register is
only mandatory in implementation which supports LPIs and doesn't include
an ITS.

For now, we don't support LPIs at all and in the future it will be
through the ITS, so they are effectively implementation defined in our
use case.

>>
>> Signed-off-by: Julien Grall <julien.grall@citrix.com>
> 
> Acked-by: Ian Campbell <ian.campbell@citrix.com>

Thank you!

Regards,


-- 
Julien Grall

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2015-11-18 16:59 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-13 11:54 [PATCH 0/9] xen/arm: Bunch of fixes for the vGIC emulation Julien Grall
2015-11-13 11:54 ` [PATCH 1/9] xen/arm: vgic-v3: Use the correct offset GICR_IGRPMODR0 Julien Grall
2015-11-16 13:20   ` Ian Campbell
2015-11-13 11:54 ` [PATCH 2/9] xen/arm: vgic-v3: Only emulate identification registers requested by the spec Julien Grall
2015-11-16 13:27   ` Ian Campbell
2015-11-18 16:46     ` Julien Grall
2015-11-13 11:54 ` [PATCH 3/9] xen/arm: vgic: Properly emulate the full register Julien Grall
2015-11-16 13:29   ` Ian Campbell
2015-11-13 11:54 ` [PATCH 4/9] xen/arm: vgic-v3: Remove GICR_MOVALLR and GICR_MOVLPIR Julien Grall
2015-11-16 13:33   ` Ian Campbell
2015-11-18 16:58     ` Julien Grall
2015-11-13 11:54 ` [PATCH 5/9] xen/arm: vgic: Re-order the register emulations to match the memory map Julien Grall
2015-11-16 13:35   ` Ian Campbell
2015-11-13 11:54 ` [PATCH 6/9] xen/arm: vgic-v3: Emulate read to GICD_ICACTIVER<n> Julien Grall
2015-11-16 13:36   ` Ian Campbell
2015-11-13 11:54 ` [PATCH 7/9] xen/arm: vgic-v3: Remove spurious return in GICR_INVALLR Julien Grall
2015-11-16 13:36   ` Ian Campbell
2015-11-13 11:54 ` [PATCH 8/9] xen/arm: vgic-v3: Don't implement write-only register read as zero Julien Grall
2015-11-16 13:37   ` Ian Campbell
2015-11-13 11:54 ` [PATCH 9/9] xen/arm: vgic-v3: Make clear that GICD_*SPI_* registers are reserved Julien Grall
2015-11-16 13:39   ` Ian Campbell

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.