From 41d49e7939de5ec532d86494185b2ca2e99c848a Mon Sep 17 00:00:00 2001 From: Fabien Parent Date: Thu, 19 Sep 2019 21:13:15 +0200 Subject: clocksource/drivers/mediatek: Fix error handling When timer_of_init fails, it cleans up after itself by undoing everything it did during the initialization function. mtk_syst_init and mtk_gpt_init both call timer_of_cleanup if timer_of_init fails. timer_of_cleanup try to release the resource taken. Since these resources have already been cleaned up by timer_of_init, we end up getting a few warnings printed: [ 0.001935] WARNING: CPU: 0 PID: 0 at __clk_put+0xe8/0x128 [ 0.002650] Modules linked in: [ 0.003058] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.19.67+ #1 [ 0.003852] Hardware name: MediaTek MT8183 (DT) [ 0.004446] pstate: 20400085 (nzCv daIf +PAN -UAO) [ 0.005073] pc : __clk_put+0xe8/0x128 [ 0.005555] lr : clk_put+0xc/0x14 [ 0.005988] sp : ffffff80090b3ea0 [ 0.006422] x29: ffffff80090b3ea0 x28: 0000000040e20018 [ 0.007121] x27: ffffffc07bfff780 x26: 0000000000000001 [ 0.007819] x25: ffffff80090bda80 x24: ffffff8008ec5828 [ 0.008517] x23: ffffff80090bd000 x22: ffffff8008d8b2e8 [ 0.009216] x21: 0000000000000001 x20: fffffffffffffdfb [ 0.009914] x19: ffffff8009166180 x18: 00000000002bffa8 [ 0.010612] x17: ffffffc012996980 x16: 0000000000000000 [ 0.011311] x15: ffffffbf004a6800 x14: 3536343038393334 [ 0.012009] x13: 2079726576652073 x12: 7eb9c62c5c38f100 [ 0.012707] x11: ffffff80090b3ba0 x10: ffffff80090b3ba0 [ 0.013405] x9 : 0000000000000004 x8 : 0000000000000040 [ 0.014103] x7 : ffffffc079400270 x6 : 0000000000000000 [ 0.014801] x5 : ffffffc079400248 x4 : 0000000000000000 [ 0.015499] x3 : 0000000000000000 x2 : 0000000000000000 [ 0.016197] x1 : ffffff80091661c0 x0 : fffffffffffffdfb [ 0.016896] Call trace: [ 0.017218] __clk_put+0xe8/0x128 [ 0.017654] clk_put+0xc/0x14 [ 0.018048] timer_of_cleanup+0x60/0x7c [ 0.018551] mtk_syst_init+0x8c/0x9c [ 0.019020] timer_probe+0x6c/0xe0 [ 0.019469] time_init+0x14/0x44 [ 0.019893] start_kernel+0x2d0/0x46c [ 0.020378] ---[ end trace 8c1efabea1267649 ]--- [ 0.020982] ------------[ cut here ]------------ [ 0.021586] Trying to vfree() nonexistent vm area ((____ptrval____)) [ 0.022427] WARNING: CPU: 0 PID: 0 at __vunmap+0xd0/0xd8 [ 0.023119] Modules linked in: [ 0.023524] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W 4.19.67+ #1 [ 0.024498] Hardware name: MediaTek MT8183 (DT) [ 0.025091] pstate: 60400085 (nZCv daIf +PAN -UAO) [ 0.025718] pc : __vunmap+0xd0/0xd8 [ 0.026176] lr : __vunmap+0xd0/0xd8 [ 0.026632] sp : ffffff80090b3e90 [ 0.027066] x29: ffffff80090b3e90 x28: 0000000040e20018 [ 0.027764] x27: ffffffc07bfff780 x26: 0000000000000001 [ 0.028462] x25: ffffff80090bda80 x24: ffffff8008ec5828 [ 0.029160] x23: ffffff80090bd000 x22: ffffff8008d8b2e8 [ 0.029858] x21: 0000000000000000 x20: 0000000000000000 [ 0.030556] x19: ffffff800800d000 x18: 00000000002bffa8 [ 0.031254] x17: 0000000000000000 x16: 0000000000000000 [ 0.031952] x15: ffffffbf004a6800 x14: 3536343038393334 [ 0.032651] x13: 2079726576652073 x12: 7eb9c62c5c38f100 [ 0.033349] x11: ffffff80090b3b40 x10: ffffff80090b3b40 [ 0.034047] x9 : 0000000000000005 x8 : 5f5f6c6176727470 [ 0.034745] x7 : 5f5f5f5f28282061 x6 : ffffff80091c86ef [ 0.035443] x5 : ffffff800852b690 x4 : 0000000000000000 [ 0.036141] x3 : 0000000000000002 x2 : 0000000000000002 [ 0.036839] x1 : 7eb9c62c5c38f100 x0 : 7eb9c62c5c38f100 [ 0.037536] Call trace: [ 0.037859] __vunmap+0xd0/0xd8 [ 0.038271] vunmap+0x24/0x30 [ 0.038664] __iounmap+0x2c/0x34 [ 0.039088] timer_of_cleanup+0x70/0x7c [ 0.039591] mtk_syst_init+0x8c/0x9c [ 0.040060] timer_probe+0x6c/0xe0 [ 0.040507] time_init+0x14/0x44 [ 0.040932] start_kernel+0x2d0/0x46c This commit remove the calls to timer_of_cleanup when timer_of_init fails since it is unnecessary and actually cause warnings to be printed. Fixes: a0858f937960 ("mediatek: Convert the driver to timer-of") Signed-off-by: Fabien Parent Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/linux-arm-kernel/20190919191315.25190-1-fparent@baylibre.com/ --- drivers/clocksource/timer-mediatek.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c index a562f491b0f8..9318edcd8963 100644 --- a/drivers/clocksource/timer-mediatek.c +++ b/drivers/clocksource/timer-mediatek.c @@ -268,15 +268,12 @@ static int __init mtk_syst_init(struct device_node *node) ret = timer_of_init(node, &to); if (ret) - goto err; + return ret; clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), TIMER_SYNC_TICKS, 0xffffffff); return 0; -err: - timer_of_cleanup(&to); - return ret; } static int __init mtk_gpt_init(struct device_node *node) @@ -293,7 +290,7 @@ static int __init mtk_gpt_init(struct device_node *node) ret = timer_of_init(node, &to); if (ret) - goto err; + return ret; /* Configure clock source */ mtk_gpt_setup(&to, TIMER_CLK_SRC, GPT_CTRL_OP_FREERUN); @@ -311,9 +308,6 @@ static int __init mtk_gpt_init(struct device_node *node) mtk_gpt_enable_irq(&to, TIMER_CLK_EVT); return 0; -err: - timer_of_cleanup(&to); - return ret; } TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init); TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init); -- cgit v1.2.3 From 7693de9f7aa4e2993fbd7094863304be6a4bbe16 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 16 Oct 2019 16:30:03 +0200 Subject: clocksource/drivers/sh_mtu2: Do not loop using platform_get_irq_by_name() As platform_get_irq_by_name() now prints an error when the interrupt does not exist, looping over possibly non-existing interrupts causes the printing of scary messages like: sh_mtu2 fcff0000.timer: IRQ tgi1a not found sh_mtu2 fcff0000.timer: IRQ tgi2a not found Fix this by using the platform_irq_count() helper, to avoid touching non-existent interrupts. Limit the returned number of interrupts to the maximum number of channels currently supported by the driver in a future-proof way, i.e. using ARRAY_SIZE() instead of a hardcoded number. Fixes: 7723f4c5ecdb8d83 ("driver core: platform: Add an error message to platform_get_irq*()") Signed-off-by: Geert Uytterhoeven Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20191016143003.28561-1-geert+renesas@glider.be --- drivers/clocksource/sh_mtu2.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 354b27d14a19..62812f80b5cc 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -328,12 +328,13 @@ static int sh_mtu2_register(struct sh_mtu2_channel *ch, const char *name) return 0; } +static const unsigned int sh_mtu2_channel_offsets[] = { + 0x300, 0x380, 0x000, +}; + static int sh_mtu2_setup_channel(struct sh_mtu2_channel *ch, unsigned int index, struct sh_mtu2_device *mtu) { - static const unsigned int channel_offsets[] = { - 0x300, 0x380, 0x000, - }; char name[6]; int irq; int ret; @@ -356,7 +357,7 @@ static int sh_mtu2_setup_channel(struct sh_mtu2_channel *ch, unsigned int index, return ret; } - ch->base = mtu->mapbase + channel_offsets[index]; + ch->base = mtu->mapbase + sh_mtu2_channel_offsets[index]; ch->index = index; return sh_mtu2_register(ch, dev_name(&mtu->pdev->dev)); @@ -408,7 +409,12 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu, } /* Allocate and setup the channels. */ - mtu->num_channels = 3; + ret = platform_irq_count(pdev); + if (ret < 0) + goto err_unmap; + + mtu->num_channels = min_t(unsigned int, ret, + ARRAY_SIZE(sh_mtu2_channel_offsets)); mtu->channels = kcalloc(mtu->num_channels, sizeof(*mtu->channels), GFP_KERNEL); -- cgit v1.2.3 From 52338415cf4d4064ae6b8dd972dadbda841da4fa Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Thu, 24 Oct 2019 11:28:29 +0800 Subject: timekeeping/vsyscall: Update VDSO data unconditionally The update of the VDSO data is depending on __arch_use_vsyscall() returning True. This is a leftover from the attempt to map the features of various architectures 1:1 into generic code. The usage of __arch_use_vsyscall() in the actual vsyscall implementations got dropped and replaced by the requirement for the architecture code to return U64_MAX if the global clocksource is not usable in the VDSO. But the __arch_use_vsyscall() check in the update code stayed which causes the VDSO data to be stale or invalid when an architecture actually implements that function and returns False when the current clocksource is not usable in the VDSO. As a consequence the VDSO implementations of clock_getres(), time(), clock_gettime(CLOCK_.*_COARSE) operate on invalid data and return bogus information. Remove the __arch_use_vsyscall() check from the VDSO update function and update the VDSO data unconditionally. [ tglx: Massaged changelog and removed the now useless implementations in asm-generic/ARM64/MIPS ] Fixes: 44f57d788e7deecb50 ("timekeeping: Provide a generic update_vsyscall() implementation") Signed-off-by: Huacai Chen Signed-off-by: Thomas Gleixner Cc: Andy Lutomirski Cc: Vincenzo Frascino Cc: Arnd Bergmann Cc: Paul Burton Cc: linux-mips@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/1571887709-11447-1-git-send-email-chenhc@lemote.com --- arch/arm64/include/asm/vdso/vsyscall.h | 7 ------- arch/mips/include/asm/vdso/vsyscall.h | 7 ------- include/asm-generic/vdso/vsyscall.h | 7 ------- kernel/time/vsyscall.c | 9 +++------ 4 files changed, 3 insertions(+), 27 deletions(-) diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/asm/vdso/vsyscall.h index 0c731bfc7c8c..0c20a7c1bee5 100644 --- a/arch/arm64/include/asm/vdso/vsyscall.h +++ b/arch/arm64/include/asm/vdso/vsyscall.h @@ -30,13 +30,6 @@ int __arm64_get_clock_mode(struct timekeeper *tk) } #define __arch_get_clock_mode __arm64_get_clock_mode -static __always_inline -int __arm64_use_vsyscall(struct vdso_data *vdata) -{ - return !vdata[CS_HRES_COARSE].clock_mode; -} -#define __arch_use_vsyscall __arm64_use_vsyscall - static __always_inline void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk) { diff --git a/arch/mips/include/asm/vdso/vsyscall.h b/arch/mips/include/asm/vdso/vsyscall.h index 195314732233..00d41b94ba31 100644 --- a/arch/mips/include/asm/vdso/vsyscall.h +++ b/arch/mips/include/asm/vdso/vsyscall.h @@ -28,13 +28,6 @@ int __mips_get_clock_mode(struct timekeeper *tk) } #define __arch_get_clock_mode __mips_get_clock_mode -static __always_inline -int __mips_use_vsyscall(struct vdso_data *vdata) -{ - return (vdata[CS_HRES_COARSE].clock_mode != VDSO_CLOCK_NONE); -} -#define __arch_use_vsyscall __mips_use_vsyscall - /* The asm-generic header needs to be included after the definitions above */ #include diff --git a/include/asm-generic/vdso/vsyscall.h b/include/asm-generic/vdso/vsyscall.h index e94b19782c92..ce4103208619 100644 --- a/include/asm-generic/vdso/vsyscall.h +++ b/include/asm-generic/vdso/vsyscall.h @@ -25,13 +25,6 @@ static __always_inline int __arch_get_clock_mode(struct timekeeper *tk) } #endif /* __arch_get_clock_mode */ -#ifndef __arch_use_vsyscall -static __always_inline int __arch_use_vsyscall(struct vdso_data *vdata) -{ - return 1; -} -#endif /* __arch_use_vsyscall */ - #ifndef __arch_update_vsyscall static __always_inline void __arch_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk) diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c index 4bc37ac3bb05..5ee0f7709410 100644 --- a/kernel/time/vsyscall.c +++ b/kernel/time/vsyscall.c @@ -110,8 +110,7 @@ void update_vsyscall(struct timekeeper *tk) nsec = nsec + tk->wall_to_monotonic.tv_nsec; vdso_ts->sec += __iter_div_u64_rem(nsec, NSEC_PER_SEC, &vdso_ts->nsec); - if (__arch_use_vsyscall(vdata)) - update_vdso_data(vdata, tk); + update_vdso_data(vdata, tk); __arch_update_vsyscall(vdata, tk); @@ -124,10 +123,8 @@ void update_vsyscall_tz(void) { struct vdso_data *vdata = __arch_get_k_vdso_data(); - if (__arch_use_vsyscall(vdata)) { - vdata[CS_HRES_COARSE].tz_minuteswest = sys_tz.tz_minuteswest; - vdata[CS_HRES_COARSE].tz_dsttime = sys_tz.tz_dsttime; - } + vdata[CS_HRES_COARSE].tz_minuteswest = sys_tz.tz_minuteswest; + vdata[CS_HRES_COARSE].tz_dsttime = sys_tz.tz_dsttime; __arch_sync_vdso_data(vdata); } -- cgit v1.2.3