[for-4.14,1/3] xen/arm: Allow a platform to override the DMA width
diff mbox series

Message ID 20200518113008.15422-2-julien@xen.org
State Superseded
Headers show
Series
  • Remove the 1GB limitation on Rasberry Pi 4
Related show

Commit Message

Julien Grall May 18, 2020, 11:30 a.m. UTC
From: Julien Grall <jgrall@amazon.com>

At the moment, Xen is assuming that all the devices are at least 32-bit
DMA capable. However, some SoC have devices that may be able to access
a much restricted range. For instance, the RPI has devices that can
only access the first 1GB of RAM.

The structure platform_desc is now extended to allow a platform to
override the DMA width. The new is used to implement
arch_get_dma_bit_size().

The prototype is now moved in asm-arm/mm.h as the function is not NUMA
specific. The implementation is done in platform.c so we don't have to
include platform.h everywhere. This should be fine as the function is
not expected to be called in hotpath.

Signed-off-by: Julien Grall <jgrall@amazon.com>

---

Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <george.dunlap@citrix.com>

I noticed that arch_get_dma_bit_size() is only called when there is more
than one NUMA node. I am a bit unsure what is the reason behind it.

The goal for Arm is to use arch_get_dma_bit_size() when deciding how low
the first Dom0 bank should be allocated.
---
 xen/arch/arm/platform.c        | 5 +++++
 xen/include/asm-arm/mm.h       | 2 ++
 xen/include/asm-arm/numa.h     | 5 -----
 xen/include/asm-arm/platform.h | 2 ++
 4 files changed, 9 insertions(+), 5 deletions(-)

Comments

Volodymyr Babchuk May 18, 2020, 6:24 p.m. UTC | #1
Hi Julien,

On Mon, 2020-05-18 at 12:30 +0100, Julien Grall wrote:
> From: Julien Grall <jgrall@amazon.com>
> 
> At the moment, Xen is assuming that all the devices are at least 32-bit
> DMA capable. However, some SoC have devices that may be able to access
> a much restricted range. For instance, the RPI has devices that can
> only access the first 1GB of RAM.
> 
> The structure platform_desc is now extended to allow a platform to
> override the DMA width. The new is used to implement
> arch_get_dma_bit_size().
> 
> The prototype is now moved in asm-arm/mm.h as the function is not NUMA
> specific. The implementation is done in platform.c so we don't have to
> include platform.h everywhere. This should be fine as the function is
> not expected to be called in hotpath.
> 
> Signed-off-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>

> ---
> 
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: George Dunlap <george.dunlap@citrix.com>
> 
> I noticed that arch_get_dma_bit_size() is only called when there is more
> than one NUMA node. I am a bit unsure what is the reason behind it.
> 
> The goal for Arm is to use arch_get_dma_bit_size() when deciding how low
> the first Dom0 bank should be allocated.
> ---
>  xen/arch/arm/platform.c        | 5 +++++
>  xen/include/asm-arm/mm.h       | 2 ++
>  xen/include/asm-arm/numa.h     | 5 -----
>  xen/include/asm-arm/platform.h | 2 ++
>  4 files changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c
> index 8eb0b6e57a5a..4db5bbb4c51d 100644
> --- a/xen/arch/arm/platform.c
> +++ b/xen/arch/arm/platform.c
> @@ -155,6 +155,11 @@ bool platform_device_is_blacklisted(const struct dt_device_node *node)
>      return (dt_match_node(blacklist, node) != NULL);
>  }
>  
> +unsigned int arch_get_dma_bitsize(void)
> +{
> +    return ( platform && platform->dma_bitsize ) ? platform->dma_bitsize : 32;
> +}
> +
>  /*
>   * Local variables:
>   * mode: C
> diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
> index 7df91280bc77..f8ba49b1188f 100644
> --- a/xen/include/asm-arm/mm.h
> +++ b/xen/include/asm-arm/mm.h
> @@ -366,6 +366,8 @@ int arch_acquire_resource(struct domain *d, unsigned int type, unsigned int id,
>      return -EOPNOTSUPP;
>  }
>  
> +unsigned int arch_get_dma_bitsize(void);
> +
>  #endif /*  __ARCH_ARM_MM__ */
>  /*
>   * Local variables:
> diff --git a/xen/include/asm-arm/numa.h b/xen/include/asm-arm/numa.h
> index 490d1f31aa14..31a6de4e2346 100644
> --- a/xen/include/asm-arm/numa.h
> +++ b/xen/include/asm-arm/numa.h
> @@ -25,11 +25,6 @@ extern mfn_t first_valid_mfn;
>  #define node_start_pfn(nid) (mfn_x(first_valid_mfn))
>  #define __node_distance(a, b) (20)
>  
> -static inline unsigned int arch_get_dma_bitsize(void)
> -{
> -    return 32;
> -}
> -
>  #endif /* __ARCH_ARM_NUMA_H */
>  /*
>   * Local variables:
> diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h
> index ed4d30a1be7c..997eb2521631 100644
> --- a/xen/include/asm-arm/platform.h
> +++ b/xen/include/asm-arm/platform.h
> @@ -38,6 +38,8 @@ struct platform_desc {
>       * List of devices which must not pass-through to a guest
>       */
>      const struct dt_device_match *blacklist_dev;
> +    /* Override the DMA width (32-bit by default). */
> +    unsigned int dma_bitsize;
>  };
>  
>  /*
Stefano Stabellini May 20, 2020, 10:01 p.m. UTC | #2
On Mon, 18 May 2020, Volodymyr Babchuk wrote:
> Hi Julien,
> 
> On Mon, 2020-05-18 at 12:30 +0100, Julien Grall wrote:
> > From: Julien Grall <jgrall@amazon.com>
> > 
> > At the moment, Xen is assuming that all the devices are at least 32-bit
> > DMA capable. However, some SoC have devices that may be able to access
> > a much restricted range. For instance, the RPI has devices that can
> > only access the first 1GB of RAM.
> > 
> > The structure platform_desc is now extended to allow a platform to
> > override the DMA width. The new is used to implement
> > arch_get_dma_bit_size().
> > 
> > The prototype is now moved in asm-arm/mm.h as the function is not NUMA
> > specific. The implementation is done in platform.c so we don't have to
> > include platform.h everywhere. This should be fine as the function is
> > not expected to be called in hotpath.
> > 
> > Signed-off-by: Julien Grall <jgrall@amazon.com>
> Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>

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


> > ---
> > 
> > Cc: Jan Beulich <jbeulich@suse.com>
> > Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> > Cc: George Dunlap <george.dunlap@citrix.com>
> > 
> > I noticed that arch_get_dma_bit_size() is only called when there is more
> > than one NUMA node. I am a bit unsure what is the reason behind it.
> > 
> > The goal for Arm is to use arch_get_dma_bit_size() when deciding how low
> > the first Dom0 bank should be allocated.
> > ---
> >  xen/arch/arm/platform.c        | 5 +++++
> >  xen/include/asm-arm/mm.h       | 2 ++
> >  xen/include/asm-arm/numa.h     | 5 -----
> >  xen/include/asm-arm/platform.h | 2 ++
> >  4 files changed, 9 insertions(+), 5 deletions(-)
> > 
> > diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c
> > index 8eb0b6e57a5a..4db5bbb4c51d 100644
> > --- a/xen/arch/arm/platform.c
> > +++ b/xen/arch/arm/platform.c
> > @@ -155,6 +155,11 @@ bool platform_device_is_blacklisted(const struct dt_device_node *node)
> >      return (dt_match_node(blacklist, node) != NULL);
> >  }
> >  
> > +unsigned int arch_get_dma_bitsize(void)
> > +{
> > +    return ( platform && platform->dma_bitsize ) ? platform->dma_bitsize : 32;
> > +}
> > +
> >  /*
> >   * Local variables:
> >   * mode: C
> > diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
> > index 7df91280bc77..f8ba49b1188f 100644
> > --- a/xen/include/asm-arm/mm.h
> > +++ b/xen/include/asm-arm/mm.h
> > @@ -366,6 +366,8 @@ int arch_acquire_resource(struct domain *d, unsigned int type, unsigned int id,
> >      return -EOPNOTSUPP;
> >  }
> >  
> > +unsigned int arch_get_dma_bitsize(void);
> > +
> >  #endif /*  __ARCH_ARM_MM__ */
> >  /*
> >   * Local variables:
> > diff --git a/xen/include/asm-arm/numa.h b/xen/include/asm-arm/numa.h
> > index 490d1f31aa14..31a6de4e2346 100644
> > --- a/xen/include/asm-arm/numa.h
> > +++ b/xen/include/asm-arm/numa.h
> > @@ -25,11 +25,6 @@ extern mfn_t first_valid_mfn;
> >  #define node_start_pfn(nid) (mfn_x(first_valid_mfn))
> >  #define __node_distance(a, b) (20)
> >  
> > -static inline unsigned int arch_get_dma_bitsize(void)
> > -{
> > -    return 32;
> > -}
> > -
> >  #endif /* __ARCH_ARM_NUMA_H */
> >  /*
> >   * Local variables:
> > diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h
> > index ed4d30a1be7c..997eb2521631 100644
> > --- a/xen/include/asm-arm/platform.h
> > +++ b/xen/include/asm-arm/platform.h
> > @@ -38,6 +38,8 @@ struct platform_desc {
> >       * List of devices which must not pass-through to a guest
> >       */
> >      const struct dt_device_match *blacklist_dev;
> > +    /* Override the DMA width (32-bit by default). */
> > +    unsigned int dma_bitsize;
> >  };
> >  
> >  /*
>

Patch
diff mbox series

diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c
index 8eb0b6e57a5a..4db5bbb4c51d 100644
--- a/xen/arch/arm/platform.c
+++ b/xen/arch/arm/platform.c
@@ -155,6 +155,11 @@  bool platform_device_is_blacklisted(const struct dt_device_node *node)
     return (dt_match_node(blacklist, node) != NULL);
 }
 
+unsigned int arch_get_dma_bitsize(void)
+{
+    return ( platform && platform->dma_bitsize ) ? platform->dma_bitsize : 32;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index 7df91280bc77..f8ba49b1188f 100644
--- a/xen/include/asm-arm/mm.h
+++ b/xen/include/asm-arm/mm.h
@@ -366,6 +366,8 @@  int arch_acquire_resource(struct domain *d, unsigned int type, unsigned int id,
     return -EOPNOTSUPP;
 }
 
+unsigned int arch_get_dma_bitsize(void);
+
 #endif /*  __ARCH_ARM_MM__ */
 /*
  * Local variables:
diff --git a/xen/include/asm-arm/numa.h b/xen/include/asm-arm/numa.h
index 490d1f31aa14..31a6de4e2346 100644
--- a/xen/include/asm-arm/numa.h
+++ b/xen/include/asm-arm/numa.h
@@ -25,11 +25,6 @@  extern mfn_t first_valid_mfn;
 #define node_start_pfn(nid) (mfn_x(first_valid_mfn))
 #define __node_distance(a, b) (20)
 
-static inline unsigned int arch_get_dma_bitsize(void)
-{
-    return 32;
-}
-
 #endif /* __ARCH_ARM_NUMA_H */
 /*
  * Local variables:
diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h
index ed4d30a1be7c..997eb2521631 100644
--- a/xen/include/asm-arm/platform.h
+++ b/xen/include/asm-arm/platform.h
@@ -38,6 +38,8 @@  struct platform_desc {
      * List of devices which must not pass-through to a guest
      */
     const struct dt_device_match *blacklist_dev;
+    /* Override the DMA width (32-bit by default). */
+    unsigned int dma_bitsize;
 };
 
 /*