[Xen-devel,2/3] xen/arm: Don't crash domain on bad MMIO emulation

Message ID 20180130161433.6910-3-julien.grall@arm.com
State Superseded
Headers show
Series
  • xen/arm: Inject an exception to the guest rather than crashing it
Related show

Commit Message

Julien Grall Jan. 30, 2018, 4:14 p.m.
Now the MMIO emulation is able to distinguish unhandled IO from aborted
one, there are no need to crash the domain when the region is access
with a bad width.

Instead let Xen inject a data abort to the guest and decide what to do.

Signed-off-by: Julien Grall <julien.grall@arm.com>
---
 xen/arch/arm/vgic-v2.c     | 2 --
 xen/arch/arm/vgic-v3-its.c | 3 ---
 xen/arch/arm/vgic-v3.c     | 8 --------
 xen/arch/arm/vpl011.c      | 2 --
 4 files changed, 15 deletions(-)

Comments

Stefano Stabellini Jan. 30, 2018, 6:18 p.m. | #1
On Tue, 30 Jan 2018, Julien Grall wrote:
> Now the MMIO emulation is able to distinguish unhandled IO from aborted
> one, there are no need to crash the domain when the region is access
> with a bad width.
> 
> Instead let Xen inject a data abort to the guest and decide what to do.
> 
> Signed-off-by: Julien Grall <julien.grall@arm.com>

Nice!

Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>

> ---
>  xen/arch/arm/vgic-v2.c     | 2 --
>  xen/arch/arm/vgic-v3-its.c | 3 ---
>  xen/arch/arm/vgic-v3.c     | 8 --------
>  xen/arch/arm/vpl011.c      | 2 --
>  4 files changed, 15 deletions(-)
> 
> diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
> index 2bdb25261a..646d1f3d12 100644
> --- a/xen/arch/arm/vgic-v2.c
> +++ b/xen/arch/arm/vgic-v2.c
> @@ -348,7 +348,6 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
>  bad_width:
>      printk(XENLOG_G_ERR "%pv: vGICD: bad read width %d r%d offset %#08x\n",
>             v, dabt.size, dabt.reg, gicd_reg);
> -    domain_crash_synchronous();
>      return 0;
>  
>  read_as_zero_32:
> @@ -613,7 +612,6 @@ bad_width:
>      printk(XENLOG_G_ERR
>             "%pv: vGICD: bad write width %d r%d=%"PRIregister" offset %#08x\n",
>             v, dabt.size, dabt.reg, r, gicd_reg);
> -    domain_crash_synchronous();
>      return 0;
>  
>  write_ignore_32:
> diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c
> index d8fa44258d..32061c6b03 100644
> --- a/xen/arch/arm/vgic-v3-its.c
> +++ b/xen/arch/arm/vgic-v3-its.c
> @@ -1136,7 +1136,6 @@ read_reserved:
>  bad_width:
>      printk(XENLOG_G_ERR "vGITS: bad read width %d r%d offset %#04lx\n",
>             info->dabt.size, info->dabt.reg, (unsigned long)info->gpa & 0xffff);
> -    domain_crash_synchronous();
>  
>      return 0;
>  }
> @@ -1446,8 +1445,6 @@ bad_width:
>      printk(XENLOG_G_ERR "vGITS: bad write width %d r%d offset %#08lx\n",
>             info->dabt.size, info->dabt.reg, (unsigned long)info->gpa & 0xffff);
>  
> -    domain_crash_synchronous();
> -
>      return 0;
>  }
>  
> diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
> index af16dfd005..2ad8a6be62 100644
> --- a/xen/arch/arm/vgic-v3.c
> +++ b/xen/arch/arm/vgic-v3.c
> @@ -328,7 +328,6 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
>  bad_width:
>      printk(XENLOG_G_ERR "%pv vGICR: bad read width %d r%d offset %#08x\n",
>             v, dabt.size, dabt.reg, gicr_reg);
> -    domain_crash_synchronous();
>      return 0;
>  
>  read_as_zero_64:
> @@ -648,7 +647,6 @@ bad_width:
>      printk(XENLOG_G_ERR
>            "%pv: vGICR: bad write width %d r%d=%"PRIregister" offset %#08x\n",
>            v, dabt.size, dabt.reg, r, gicr_reg);
> -    domain_crash_synchronous();
>      return 0;
>  
>  write_ignore_64:
> @@ -760,7 +758,6 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
>  bad_width:
>      printk(XENLOG_G_ERR "%pv: %s: bad read width %d r%d offset %#08x\n",
>             v, name, dabt.size, dabt.reg, reg);
> -    domain_crash_synchronous();
>      return 0;
>  
>  read_as_zero:
> @@ -876,7 +873,6 @@ bad_width:
>      printk(XENLOG_G_ERR
>             "%pv: %s: bad write width %d r%d=%"PRIregister" offset %#08x\n",
>             v, name, dabt.size, dabt.reg, r, reg);
> -    domain_crash_synchronous();
>      return 0;
>  
>  write_ignore_32:
> @@ -937,7 +933,6 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info,
>  bad_width:
>      printk(XENLOG_G_ERR "%pv: vGICR: SGI: bad read width %d r%d offset %#08x\n",
>             v, dabt.size, dabt.reg, gicr_reg);
> -    domain_crash_synchronous();
>      return 0;
>  
>  read_as_zero_32:
> @@ -1017,7 +1012,6 @@ bad_width:
>      printk(XENLOG_G_ERR
>             "%pv: vGICR: SGI: bad write width %d r%d=%"PRIregister" offset %#08x\n",
>             v, dabt.size, dabt.reg, r, gicr_reg);
> -    domain_crash_synchronous();
>      return 0;
>  
>  write_ignore_32:
> @@ -1268,7 +1262,6 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
>  bad_width:
>      printk(XENLOG_G_ERR "%pv: vGICD: bad read width %d r%d offset %#08x\n",
>             v, dabt.size, dabt.reg, gicd_reg);
> -    domain_crash_synchronous();
>      return 0;
>  
>  read_as_zero_32:
> @@ -1456,7 +1449,6 @@ bad_width:
>      printk(XENLOG_G_ERR
>             "%pv: vGICD: bad write width %d r%d=%"PRIregister" offset %#08x\n",
>             v, dabt.size, dabt.reg, r, gicd_reg);
> -    domain_crash_synchronous();
>      return 0;
>  
>  write_ignore_32:
> diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
> index 725b2e03ad..7788c2fc32 100644
> --- a/xen/arch/arm/vpl011.c
> +++ b/xen/arch/arm/vpl011.c
> @@ -296,7 +296,6 @@ static int vpl011_mmio_read(struct vcpu *v,
>  bad_width:
>      gprintk(XENLOG_ERR, "vpl011: bad read width %d r%d offset %#08x\n",
>              dabt.size, dabt.reg, vpl011_reg);
> -    domain_crash_synchronous();
>      return 0;
>  
>  }
> @@ -366,7 +365,6 @@ write_ignore:
>  bad_width:
>      gprintk(XENLOG_ERR, "vpl011: bad write width %d r%d offset %#08x\n",
>              dabt.size, dabt.reg, vpl011_reg);
> -    domain_crash_synchronous();
>      return 0;
>  
>  }
> -- 
> 2.11.0
>

Patch

diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index 2bdb25261a..646d1f3d12 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -348,7 +348,6 @@  static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
 bad_width:
     printk(XENLOG_G_ERR "%pv: vGICD: bad read width %d r%d offset %#08x\n",
            v, dabt.size, dabt.reg, gicd_reg);
-    domain_crash_synchronous();
     return 0;
 
 read_as_zero_32:
@@ -613,7 +612,6 @@  bad_width:
     printk(XENLOG_G_ERR
            "%pv: vGICD: bad write width %d r%d=%"PRIregister" offset %#08x\n",
            v, dabt.size, dabt.reg, r, gicd_reg);
-    domain_crash_synchronous();
     return 0;
 
 write_ignore_32:
diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c
index d8fa44258d..32061c6b03 100644
--- a/xen/arch/arm/vgic-v3-its.c
+++ b/xen/arch/arm/vgic-v3-its.c
@@ -1136,7 +1136,6 @@  read_reserved:
 bad_width:
     printk(XENLOG_G_ERR "vGITS: bad read width %d r%d offset %#04lx\n",
            info->dabt.size, info->dabt.reg, (unsigned long)info->gpa & 0xffff);
-    domain_crash_synchronous();
 
     return 0;
 }
@@ -1446,8 +1445,6 @@  bad_width:
     printk(XENLOG_G_ERR "vGITS: bad write width %d r%d offset %#08lx\n",
            info->dabt.size, info->dabt.reg, (unsigned long)info->gpa & 0xffff);
 
-    domain_crash_synchronous();
-
     return 0;
 }
 
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index af16dfd005..2ad8a6be62 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -328,7 +328,6 @@  static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
 bad_width:
     printk(XENLOG_G_ERR "%pv vGICR: bad read width %d r%d offset %#08x\n",
            v, dabt.size, dabt.reg, gicr_reg);
-    domain_crash_synchronous();
     return 0;
 
 read_as_zero_64:
@@ -648,7 +647,6 @@  bad_width:
     printk(XENLOG_G_ERR
           "%pv: vGICR: bad write width %d r%d=%"PRIregister" offset %#08x\n",
           v, dabt.size, dabt.reg, r, gicr_reg);
-    domain_crash_synchronous();
     return 0;
 
 write_ignore_64:
@@ -760,7 +758,6 @@  static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
 bad_width:
     printk(XENLOG_G_ERR "%pv: %s: bad read width %d r%d offset %#08x\n",
            v, name, dabt.size, dabt.reg, reg);
-    domain_crash_synchronous();
     return 0;
 
 read_as_zero:
@@ -876,7 +873,6 @@  bad_width:
     printk(XENLOG_G_ERR
            "%pv: %s: bad write width %d r%d=%"PRIregister" offset %#08x\n",
            v, name, dabt.size, dabt.reg, r, reg);
-    domain_crash_synchronous();
     return 0;
 
 write_ignore_32:
@@ -937,7 +933,6 @@  static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info,
 bad_width:
     printk(XENLOG_G_ERR "%pv: vGICR: SGI: bad read width %d r%d offset %#08x\n",
            v, dabt.size, dabt.reg, gicr_reg);
-    domain_crash_synchronous();
     return 0;
 
 read_as_zero_32:
@@ -1017,7 +1012,6 @@  bad_width:
     printk(XENLOG_G_ERR
            "%pv: vGICR: SGI: bad write width %d r%d=%"PRIregister" offset %#08x\n",
            v, dabt.size, dabt.reg, r, gicr_reg);
-    domain_crash_synchronous();
     return 0;
 
 write_ignore_32:
@@ -1268,7 +1262,6 @@  static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
 bad_width:
     printk(XENLOG_G_ERR "%pv: vGICD: bad read width %d r%d offset %#08x\n",
            v, dabt.size, dabt.reg, gicd_reg);
-    domain_crash_synchronous();
     return 0;
 
 read_as_zero_32:
@@ -1456,7 +1449,6 @@  bad_width:
     printk(XENLOG_G_ERR
            "%pv: vGICD: bad write width %d r%d=%"PRIregister" offset %#08x\n",
            v, dabt.size, dabt.reg, r, gicd_reg);
-    domain_crash_synchronous();
     return 0;
 
 write_ignore_32:
diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
index 725b2e03ad..7788c2fc32 100644
--- a/xen/arch/arm/vpl011.c
+++ b/xen/arch/arm/vpl011.c
@@ -296,7 +296,6 @@  static int vpl011_mmio_read(struct vcpu *v,
 bad_width:
     gprintk(XENLOG_ERR, "vpl011: bad read width %d r%d offset %#08x\n",
             dabt.size, dabt.reg, vpl011_reg);
-    domain_crash_synchronous();
     return 0;
 
 }
@@ -366,7 +365,6 @@  write_ignore:
 bad_width:
     gprintk(XENLOG_ERR, "vpl011: bad write width %d r%d offset %#08x\n",
             dabt.size, dabt.reg, vpl011_reg);
-    domain_crash_synchronous();
     return 0;
 
 }