[PATCH v1 4/6] xen/arm: io: Add support for mmio background regions

Edgar E. Iglesias posted 6 patches 3 months, 1 week ago
[PATCH v1 4/6] xen/arm: io: Add support for mmio background regions
Posted by Edgar E. Iglesias 3 months, 1 week ago
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>

Add support for mmio background regions. These regions
can be overlayed by IOREQ handlers and thus act as
fallback handlers while IOREQ clients haven't registered.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
---
 xen/arch/arm/include/asm/mmio.h | 11 ++++++++++-
 xen/arch/arm/io.c               | 18 ++++++++++++------
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/xen/arch/arm/include/asm/mmio.h b/xen/arch/arm/include/asm/mmio.h
index b22cfdac5b..7da542cd79 100644
--- a/xen/arch/arm/include/asm/mmio.h
+++ b/xen/arch/arm/include/asm/mmio.h
@@ -70,6 +70,7 @@ struct mmio_handler_ops {
 struct mmio_handler {
     paddr_t addr;
     paddr_t size;
+    bool background;
     const struct mmio_handler_ops *ops;
     void *priv;
 };
@@ -83,9 +84,17 @@ struct vmmio {
 
 enum io_state try_handle_mmio(struct cpu_user_regs *regs,
                               mmio_info_t *info);
+void register_mmio_bg_handler(struct domain *d,
+                              bool background,
+                              const struct mmio_handler_ops *ops,
+                              paddr_t addr, paddr_t size, void *priv);
+static inline
 void register_mmio_handler(struct domain *d,
                            const struct mmio_handler_ops *ops,
-                           paddr_t addr, paddr_t size, void *priv);
+                           paddr_t addr, paddr_t size, void *priv)
+{
+    register_mmio_bg_handler(d, false, ops, addr, size, priv);
+}
 int domain_io_init(struct domain *d, unsigned int max_count);
 void domain_io_free(struct domain *d);
 
diff --git a/xen/arch/arm/io.c b/xen/arch/arm/io.c
index 96c740d563..934a2ad2b9 100644
--- a/xen/arch/arm/io.c
+++ b/xen/arch/arm/io.c
@@ -159,6 +159,7 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs,
 {
     struct vcpu *v = current;
     const struct mmio_handler *handler = NULL;
+    bool has_background;
     int rc;
 
     ASSERT(info->dabt.ec == HSR_EC_DATA_ABORT_LOWER_EL);
@@ -170,13 +171,16 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs,
     }
 
     handler = find_mmio_handler(v->domain, info->gpa);
-    if ( !handler )
+    has_background = handler && handler->background;
+    if ( !handler || has_background )
     {
         rc = try_fwd_ioserv(regs, v, info);
         if ( rc == IO_HANDLED )
             return handle_ioserv(regs, v);
-
-        return rc;
+        else if ( !(rc == IO_UNHANDLED && has_background) ) {
+            /* Only return failure if there's no background handler.  */
+            return rc;
+        }
     }
 
     /*
@@ -197,9 +201,10 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs,
         return handle_read(handler, v, info);
 }
 
-void register_mmio_handler(struct domain *d,
-                           const struct mmio_handler_ops *ops,
-                           paddr_t addr, paddr_t size, void *priv)
+void register_mmio_bg_handler(struct domain *d,
+                              bool background,
+                              const struct mmio_handler_ops *ops,
+                              paddr_t addr, paddr_t size, void *priv)
 {
     struct vmmio *vmmio = &d->arch.vmmio;
     struct mmio_handler *handler;
@@ -213,6 +218,7 @@ void register_mmio_handler(struct domain *d,
     handler->ops = ops;
     handler->addr = addr;
     handler->size = size;
+    handler->background = background;
     handler->priv = priv;
 
     vmmio->num_entries++;
-- 
2.43.0
Re: [PATCH v1 4/6] xen/arm: io: Add support for mmio background regions
Posted by Stefano Stabellini 3 months ago
On Tue, 24 Sep 2024, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
> 
> Add support for mmio background regions. These regions
> can be overlayed by IOREQ handlers and thus act as
> fallback handlers while IOREQ clients haven't registered.
> 
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>

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


> ---
>  xen/arch/arm/include/asm/mmio.h | 11 ++++++++++-
>  xen/arch/arm/io.c               | 18 ++++++++++++------
>  2 files changed, 22 insertions(+), 7 deletions(-)
> 
> diff --git a/xen/arch/arm/include/asm/mmio.h b/xen/arch/arm/include/asm/mmio.h
> index b22cfdac5b..7da542cd79 100644
> --- a/xen/arch/arm/include/asm/mmio.h
> +++ b/xen/arch/arm/include/asm/mmio.h
> @@ -70,6 +70,7 @@ struct mmio_handler_ops {
>  struct mmio_handler {
>      paddr_t addr;
>      paddr_t size;
> +    bool background;
>      const struct mmio_handler_ops *ops;
>      void *priv;
>  };
> @@ -83,9 +84,17 @@ struct vmmio {
>  
>  enum io_state try_handle_mmio(struct cpu_user_regs *regs,
>                                mmio_info_t *info);
> +void register_mmio_bg_handler(struct domain *d,
> +                              bool background,
> +                              const struct mmio_handler_ops *ops,
> +                              paddr_t addr, paddr_t size, void *priv);
> +static inline
>  void register_mmio_handler(struct domain *d,
>                             const struct mmio_handler_ops *ops,
> -                           paddr_t addr, paddr_t size, void *priv);
> +                           paddr_t addr, paddr_t size, void *priv)
> +{
> +    register_mmio_bg_handler(d, false, ops, addr, size, priv);
> +}
>  int domain_io_init(struct domain *d, unsigned int max_count);
>  void domain_io_free(struct domain *d);
>  
> diff --git a/xen/arch/arm/io.c b/xen/arch/arm/io.c
> index 96c740d563..934a2ad2b9 100644
> --- a/xen/arch/arm/io.c
> +++ b/xen/arch/arm/io.c
> @@ -159,6 +159,7 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs,
>  {
>      struct vcpu *v = current;
>      const struct mmio_handler *handler = NULL;
> +    bool has_background;
>      int rc;
>  
>      ASSERT(info->dabt.ec == HSR_EC_DATA_ABORT_LOWER_EL);
> @@ -170,13 +171,16 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs,
>      }
>  
>      handler = find_mmio_handler(v->domain, info->gpa);
> -    if ( !handler )
> +    has_background = handler && handler->background;
> +    if ( !handler || has_background )
>      {
>          rc = try_fwd_ioserv(regs, v, info);
>          if ( rc == IO_HANDLED )
>              return handle_ioserv(regs, v);
> -
> -        return rc;
> +        else if ( !(rc == IO_UNHANDLED && has_background) ) {
> +            /* Only return failure if there's no background handler.  */
> +            return rc;
> +        }
>      }
>  
>      /*
> @@ -197,9 +201,10 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs,
>          return handle_read(handler, v, info);
>  }
>  
> -void register_mmio_handler(struct domain *d,
> -                           const struct mmio_handler_ops *ops,
> -                           paddr_t addr, paddr_t size, void *priv)
> +void register_mmio_bg_handler(struct domain *d,
> +                              bool background,
> +                              const struct mmio_handler_ops *ops,
> +                              paddr_t addr, paddr_t size, void *priv)
>  {
>      struct vmmio *vmmio = &d->arch.vmmio;
>      struct mmio_handler *handler;
> @@ -213,6 +218,7 @@ void register_mmio_handler(struct domain *d,
>      handler->ops = ops;
>      handler->addr = addr;
>      handler->size = size;
> +    handler->background = background;
>      handler->priv = priv;
>  
>      vmmio->num_entries++;
> -- 
> 2.43.0
>