Re: [Xen-devel] [PATCH v2] xen/arm: Propagate clock-frequency to DOMU if present in the DT timer node

2015-09-25 Thread Ian Campbell
On Fri, 2015-06-19 at 13:41 +0100, Julien Grall wrote:
> When the property "clock-frequency" is present in the DT timer node, it
> means that the bootloader/firmware didn't correctly configure the
> CNTFRQ/CNTFRQ_EL0 on each processor.
> 
> The best solution would be to fix the offending firmware/bootloader,
> although it may not always be possible to modify and re-flash it.
> 
> As it's not possible to trap the register CNTFRQ/CNTFRQ_EL0, we have
> to extend xen_arch_domainconfig to provide the timer frequency to the
> toolstack when the property "clock-frequency" is present to the host DT
> timer node. Then, a property "clock-frequency" will be created in the
> guest
> DT timer node if the value is not 0.
> 
> We could have set the property in the guest DT no matter if the property
> is present in the host DT. Although, we still want to let the guest
> using CNTFRQ in normal case. After all, the property "clock-frequency"
> is just a workaround for buggy firmware.
> 
> Also add a stub for fdt_property_u32 which is not present in libfdt <
> 1.4.0 used by distribution such as Debian Wheezy.
> 
> Signed-off-by: Julien Grall 
> Tested-by: Chris Brand 

I had this on my list to backport to 4.5 but it didn't apply at all cleanly
in a variety of ways.

I don't think this one is particularly worth the effort, so I've dropped it
from the list. If someone is keen to have it then please provide a
backport.

Ian.


> 
> ---
> This patch requires to regenerate tools/configure.
> 
> Changes in v2:
> - Typo in commit message
> - Make the patch compiling on wheezy where fdt_property_u32 is
> not present
> ---
>  tools/configure.ac|  4 
>  tools/libxl/libxl_arm.c   |  9 +++--
>  tools/libxl/libxl_libfdt_compat.h |  9 +
>  xen/arch/arm/domain.c |  2 +-
>  xen/arch/arm/time.c   |  5 +
>  xen/arch/arm/vtimer.c |  4 +++-
>  xen/arch/arm/vtimer.h |  3 ++-
>  xen/include/asm-arm/time.h|  6 ++
>  xen/include/public/arch-arm.h | 14 ++
>  9 files changed, 51 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/configure.ac b/tools/configure.ac
> index 1a06ddf..2886cb5 100644
> --- a/tools/configure.ac
> +++ b/tools/configure.ac
> @@ -379,6 +379,10 @@ AS_IF([test "x$partial_dt" = "xy" ],
>  #   * The prototype exists but the functions are not exposed. Don't ask
> why...
>  AC_CHECK_FUNCS([fdt_first_subnode fdt_next_subnode])
>  AC_CHECK_DECLS([fdt_first_subnode, fdt_next_subnode],,,[#include
> ])
> +
> +# The helper fdt_property_u32 is only present in libfdt >= 1.4.0
> +# It's an inline function, so only check if the declaration is present
> +AC_CHECK_DECLS([fdt_property_u32],,,[#include ])
>  esac
>  
>  # Checks for header files.
> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
> index 4fb5e26..f09c860 100644
> --- a/tools/libxl/libxl_arm.c
> +++ b/tools/libxl/libxl_arm.c
> @@ -444,7 +444,9 @@ static int make_gicv3_node(libxl__gc *gc, void *fdt)
>  return 0;
>  }
>  
> -static int make_timer_node(libxl__gc *gc, void *fdt, const struct
> arch_info *ainfo)
> +static int make_timer_node(libxl__gc *gc, void *fdt,
> +   const struct arch_info *ainfo,
> +   uint32_t frequency)
>  {
>  int res;
>  gic_interrupt ints[3];
> @@ -462,6 +464,9 @@ static int make_timer_node(libxl__gc *gc, void *fdt,
> const struct arch_info *ain
>  res = fdt_property_interrupts(gc, fdt, ints, 3);
>  if (res) return res;
>  
> +if ( frequency )
> +fdt_property_u32(fdt, "clock-frequency", frequency);
> +
>  res = fdt_end_node(fdt);
>  if (res) return res;
>  
> @@ -805,7 +810,7 @@ next_resize:
>  goto out;
>  }
>  
> -FDT( make_timer_node(gc, fdt, ainfo) );
> +FDT( make_timer_node(gc, fdt, ainfo, xc_config->clock_frequency)
> );
>  FDT( make_hypervisor_node(gc, fdt, vers) );
>  
>  if (pfdt)
> diff --git a/tools/libxl/libxl_libfdt_compat.h
> b/tools/libxl/libxl_libfdt_compat.h
> index 53a5076..23230b5 100644
> --- a/tools/libxl/libxl_libfdt_compat.h
> +++ b/tools/libxl/libxl_libfdt_compat.h
> @@ -61,6 +61,7 @@
>  #define LIBXL_LIBFDT_COMPAT_H
>  
>  #include "libxl_internal.h"
> +#include 
>  
>  #if !HAVE_DECL_FDT_FIRST_SUBNODE
>  _hidden int fdt_first_subnode(const void *fdt, int offset);
> @@ -70,6 +71,14 @@ _hidden int fdt_first_subnode(const void *fdt, int
> offset);
>  _hidden int fdt_next_subnode(const void *fdt, int offset);
>  #endif
>  
> +#if !HAVE_DECL_FDT_PROPERTY_U32
> +static inline int fdt_property_u32(void *fdt, const char *name, uint32_t
> val)
> +{
> + uint32_t tmp = cpu_to_fdt32(val);
> + return fdt_property(fdt, name, &tmp, sizeof(tmp));
> +}
> +#endif
> +
>  #endif
>  
>  /*
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index 24b8938..8b1bf5a 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> 

Re: [Xen-devel] [PATCH v2] xen/arm: Propagate clock-frequency to DOMU if present in the DT timer node

2015-06-25 Thread Ian Campbell
On Fri, 2015-06-19 at 13:41 +0100, Julien Grall wrote:
> When the property "clock-frequency" is present in the DT timer node, it
> means that the bootloader/firmware didn't correctly configure the
> CNTFRQ/CNTFRQ_EL0 on each processor.
> 
> The best solution would be to fix the offending firmware/bootloader,
> although it may not always be possible to modify and re-flash it.
> 
> As it's not possible to trap the register CNTFRQ/CNTFRQ_EL0, we have
> to extend xen_arch_domainconfig to provide the timer frequency to the
> toolstack when the property "clock-frequency" is present to the host DT
> timer node. Then, a property "clock-frequency" will be created in the guest
> DT timer node if the value is not 0.
> 
> We could have set the property in the guest DT no matter if the property
> is present in the host DT. Although, we still want to let the guest
> using CNTFRQ in normal case. After all, the property "clock-frequency"
> is just a workaround for buggy firmware.
> 
> Also add a stub for fdt_property_u32 which is not present in libfdt <
> 1.4.0 used by distribution such as Debian Wheezy.
> 
> Signed-off-by: Julien Grall 
> Tested-by: Chris Brand 

Acked + applied, thanks

> This patch requires to regenerate tools/configure.

Done.



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


[Xen-devel] [PATCH v2] xen/arm: Propagate clock-frequency to DOMU if present in the DT timer node

2015-06-19 Thread Julien Grall
When the property "clock-frequency" is present in the DT timer node, it
means that the bootloader/firmware didn't correctly configure the
CNTFRQ/CNTFRQ_EL0 on each processor.

The best solution would be to fix the offending firmware/bootloader,
although it may not always be possible to modify and re-flash it.

As it's not possible to trap the register CNTFRQ/CNTFRQ_EL0, we have
to extend xen_arch_domainconfig to provide the timer frequency to the
toolstack when the property "clock-frequency" is present to the host DT
timer node. Then, a property "clock-frequency" will be created in the guest
DT timer node if the value is not 0.

We could have set the property in the guest DT no matter if the property
is present in the host DT. Although, we still want to let the guest
using CNTFRQ in normal case. After all, the property "clock-frequency"
is just a workaround for buggy firmware.

Also add a stub for fdt_property_u32 which is not present in libfdt <
1.4.0 used by distribution such as Debian Wheezy.

Signed-off-by: Julien Grall 
Tested-by: Chris Brand 

---
This patch requires to regenerate tools/configure.

Changes in v2:
- Typo in commit message
- Make the patch compiling on wheezy where fdt_property_u32 is
not present
---
 tools/configure.ac|  4 
 tools/libxl/libxl_arm.c   |  9 +++--
 tools/libxl/libxl_libfdt_compat.h |  9 +
 xen/arch/arm/domain.c |  2 +-
 xen/arch/arm/time.c   |  5 +
 xen/arch/arm/vtimer.c |  4 +++-
 xen/arch/arm/vtimer.h |  3 ++-
 xen/include/asm-arm/time.h|  6 ++
 xen/include/public/arch-arm.h | 14 ++
 9 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/tools/configure.ac b/tools/configure.ac
index 1a06ddf..2886cb5 100644
--- a/tools/configure.ac
+++ b/tools/configure.ac
@@ -379,6 +379,10 @@ AS_IF([test "x$partial_dt" = "xy" ],
 #   * The prototype exists but the functions are not exposed. Don't ask why...
 AC_CHECK_FUNCS([fdt_first_subnode fdt_next_subnode])
 AC_CHECK_DECLS([fdt_first_subnode, fdt_next_subnode],,,[#include ])
+
+# The helper fdt_property_u32 is only present in libfdt >= 1.4.0
+# It's an inline function, so only check if the declaration is present
+AC_CHECK_DECLS([fdt_property_u32],,,[#include ])
 esac
 
 # Checks for header files.
diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
index 4fb5e26..f09c860 100644
--- a/tools/libxl/libxl_arm.c
+++ b/tools/libxl/libxl_arm.c
@@ -444,7 +444,9 @@ static int make_gicv3_node(libxl__gc *gc, void *fdt)
 return 0;
 }
 
-static int make_timer_node(libxl__gc *gc, void *fdt, const struct arch_info 
*ainfo)
+static int make_timer_node(libxl__gc *gc, void *fdt,
+   const struct arch_info *ainfo,
+   uint32_t frequency)
 {
 int res;
 gic_interrupt ints[3];
@@ -462,6 +464,9 @@ static int make_timer_node(libxl__gc *gc, void *fdt, const 
struct arch_info *ain
 res = fdt_property_interrupts(gc, fdt, ints, 3);
 if (res) return res;
 
+if ( frequency )
+fdt_property_u32(fdt, "clock-frequency", frequency);
+
 res = fdt_end_node(fdt);
 if (res) return res;
 
@@ -805,7 +810,7 @@ next_resize:
 goto out;
 }
 
-FDT( make_timer_node(gc, fdt, ainfo) );
+FDT( make_timer_node(gc, fdt, ainfo, xc_config->clock_frequency) );
 FDT( make_hypervisor_node(gc, fdt, vers) );
 
 if (pfdt)
diff --git a/tools/libxl/libxl_libfdt_compat.h 
b/tools/libxl/libxl_libfdt_compat.h
index 53a5076..23230b5 100644
--- a/tools/libxl/libxl_libfdt_compat.h
+++ b/tools/libxl/libxl_libfdt_compat.h
@@ -61,6 +61,7 @@
 #define LIBXL_LIBFDT_COMPAT_H
 
 #include "libxl_internal.h"
+#include 
 
 #if !HAVE_DECL_FDT_FIRST_SUBNODE
 _hidden int fdt_first_subnode(const void *fdt, int offset);
@@ -70,6 +71,14 @@ _hidden int fdt_first_subnode(const void *fdt, int offset);
 _hidden int fdt_next_subnode(const void *fdt, int offset);
 #endif
 
+#if !HAVE_DECL_FDT_PROPERTY_U32
+static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
+{
+   uint32_t tmp = cpu_to_fdt32(val);
+   return fdt_property(fdt, name, &tmp, sizeof(tmp));
+}
+#endif
+
 #endif
 
 /*
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 24b8938..8b1bf5a 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -593,7 +593,7 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags,
 if ( (rc = domain_vgic_init(d, config->nr_spis)) != 0 )
 goto fail;
 
-if ( (rc = domain_vtimer_init(d)) != 0 )
+if ( (rc = domain_vtimer_init(d, config)) != 0 )
 goto fail;
 
 /*
diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
index ce6d3fd..5ded30c 100644
--- a/xen/arch/arm/time.c
+++ b/xen/arch/arm/time.c
@@ -42,6 +42,8 @@ uint64_t __read_mostly boot_count;
  * register-mapped time source in the SoC. */
 unsigned long __read_mostly cpu_khz;