In some conditions, while testing Xenomai in VirtualBox, I had the error that xnarch_init_timeconv() is called from init_32.h with a frequency of 0. That leads to a division by zero, followed by a system oops.
Of course that is a bug in the virtualisation and Linux reports a CPU frequency of 0 in /proc/cpuinfo. However, there's no harm if Xenomai checks that instead of crashing the whole system. Signed-off-by: Bernhard Walle <[email protected]> include/asm-arm/bits/init.h | 4 +++- include/asm-blackfin/bits/init.h | 4 +++- include/asm-generic/bits/timeconv.h | 18 +++++++++++++++++- include/asm-nios2/bits/init.h | 4 +++- include/asm-powerpc/bits/init.h | 4 +++- include/asm-x86/bits/init_32.h | 4 +++- include/asm-x86/bits/init_64.h | 4 +++- src/skins/native/timer.c | 7 ++++++- src/skins/posix/clock.c | 8 +++++++- 9 files changed, 48 insertions(+), 9 deletions(-)
In some conditions, while testing Xenomai in VirtualBox, I had the error that xnarch_init_timeconv() is called from init_32.h with a frequency of 0. That leads to a division by zero, followed by a system oops. Of course that is a bug in the virtualisation and Linux reports a CPU frequency of 0 in /proc/cpuinfo. However, there's no harm if Xenomai checks that instead of crashing the whole system. Signed-off-by: Bernhard Walle <[email protected]> diff --git a/include/asm-arm/bits/init.h b/include/asm-arm/bits/init.h --- a/include/asm-arm/bits/init.h +++ b/include/asm-arm/bits/init.h @@ -82,7 +82,9 @@ set_cpus_allowed(current, cpumask_of_cpu(0)); #endif /* CONFIG_SMP && MODULE */ - xnarch_init_timeconv(RTHAL_CPU_FREQ); + ret = xnarch_init_timeconv(RTHAL_CPU_FREQ); + if (ret) + return ret; ret = xnarch_calibrate_sched(); if (ret) diff --git a/include/asm-blackfin/bits/init.h b/include/asm-blackfin/bits/init.h --- a/include/asm-blackfin/bits/init.h +++ b/include/asm-blackfin/bits/init.h @@ -83,7 +83,9 @@ set_cpus_allowed(current, cpumask_of_cpu(0)); #endif /* CONFIG_SMP && MODULE */ - xnarch_init_timeconv(RTHAL_CPU_FREQ); + ret = xnarch_init_timeconv(RTHAL_CPU_FREQ); + if (ret) + return ret; ret = xnarch_calibrate_sched(); if (ret) diff --git a/include/asm-generic/bits/timeconv.h b/include/asm-generic/bits/timeconv.h --- a/include/asm-generic/bits/timeconv.h +++ b/include/asm-generic/bits/timeconv.h @@ -100,8 +100,23 @@ } #endif /* !XNARCH_HAVE_NODIV_LLIMD */ -static inline void xnarch_init_timeconv(unsigned long long freq) +#ifndef xnarch_logerr +#define xnarch_logerr(fmt, args...) +#endif + +static inline int xnarch_init_timeconv(unsigned long long freq) { + /* + * Division by zero is not defined (and in kernel context, it + * especially leads to an oops) + */ + if (freq == 0) { + xnarch_logerr("xnarch_init_timeconv called with a " + "frequency of 0. Probably this indicates a " + "broken TSC."); + return -EINVAL; + } + clockfreq = freq; #ifdef XNARCH_HAVE_LLMULSHFT xnarch_init_llmulshft(1000000000, freq, &tsc_scale, &tsc_shift); @@ -110,6 +125,7 @@ xnarch_init_u32frac(&bln_frac, 1, 1000000000); #endif #endif + return 0; } #ifdef __KERNEL__ diff --git a/include/asm-nios2/bits/init.h b/include/asm-nios2/bits/init.h --- a/include/asm-nios2/bits/init.h +++ b/include/asm-nios2/bits/init.h @@ -72,7 +72,9 @@ if (ret) return ret; - xnarch_init_timeconv(RTHAL_CLOCK_FREQ); + ret = xnarch_init_timeconv(RTHAL_CLOCK_FREQ); + if (ret) + return ret; ret = xnarch_calibrate_sched(); if (ret) diff --git a/include/asm-powerpc/bits/init.h b/include/asm-powerpc/bits/init.h --- a/include/asm-powerpc/bits/init.h +++ b/include/asm-powerpc/bits/init.h @@ -82,7 +82,9 @@ set_cpus_allowed(current, cpumask_of_cpu(0)); #endif /* CONFIG_SMP && MODULE */ - xnarch_init_timeconv(RTHAL_CPU_FREQ); + ret = xnarch_init_timeconv(RTHAL_CPU_FREQ); + if (ret) + return ret; ret = xnarch_calibrate_sched(); if (ret) diff --git a/include/asm-x86/bits/init_32.h b/include/asm-x86/bits/init_32.h --- a/include/asm-x86/bits/init_32.h +++ b/include/asm-x86/bits/init_32.h @@ -88,7 +88,9 @@ set_cpus_allowed(current, cpumask_of_cpu(0)); #endif /* CONFIG_SMP && MODULE */ - xnarch_init_timeconv(RTHAL_CPU_FREQ); + ret = xnarch_init_timeconv(RTHAL_CPU_FREQ); + if (ret) + return ret; ret = xnarch_calibrate_sched(); if (ret) diff --git a/include/asm-x86/bits/init_64.h b/include/asm-x86/bits/init_64.h --- a/include/asm-x86/bits/init_64.h +++ b/include/asm-x86/bits/init_64.h @@ -85,7 +85,9 @@ set_cpus_allowed(current, cpumask_of_cpu(0)); #endif /* CONFIG_SMP && MODULE */ - xnarch_init_timeconv(RTHAL_CPU_FREQ); + ret = xnarch_init_timeconv(RTHAL_CPU_FREQ); + if (ret) + return ret; ret = xnarch_calibrate_sched(); if (ret) diff --git a/src/skins/native/timer.c b/src/skins/native/timer.c --- a/src/skins/native/timer.c +++ b/src/skins/native/timer.c @@ -35,7 +35,12 @@ exit(EXIT_FAILURE); } - xnarch_init_timeconv(sysinfo.cpufreq); + err = xnarch_init_timeconv(sysinfo.cpufreq); + if (err) { + fprintf(stderr, "Native skin init: " + "xnarch_init_timeconv: %s\n", strerror(-err)); + exit(EXIT_FAILURE); + } } int rt_timer_set_mode(RTIME tickval) diff --git a/src/skins/posix/clock.c b/src/skins/posix/clock.c --- a/src/skins/posix/clock.c +++ b/src/skins/posix/clock.c @@ -38,7 +38,13 @@ "sys_info: %s\n", strerror(err)); exit(EXIT_FAILURE); } - xnarch_init_timeconv(sysinfo.cpufreq); + + err = xnarch_init_timeconv(sysinfo.cpufreq); + if (err) { + fprintf(stderr, "Xenomai Posix skin init: " + "xnarch_init_timeconv: %s\n", strerror(err)); + exit(EXIT_FAILURE); + } } #endif /* XNARCH_HAVE_NONPRIV_TSC */
_______________________________________________ Xenomai-core mailing list [email protected] https://mail.gna.org/listinfo/xenomai-core
