Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clocksource/drivers/davinci: Fix memory leak in davinci_timer_register when init fails

Smatch reports:
drivers/clocksource/timer-davinci.c:332 davinci_timer_register()
warn: 'base' from ioremap() not released on lines: 274.

Fix this and other potential memory leak problems
by adding a set of corresponding exit lables.

Fixes: 721154f972aa ("clocksource/drivers/davinci: Add support for clockevents")
Signed-off-by: Qinrun Dai <flno@hust.edu.cn>
Link: https://lore.kernel.org/r/20230413135037.1505799-1-flno@hust.edu.cn
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>

authored by

Qinrun Dai and committed by
Daniel Lezcano
fb735563 b6f228e8

+24 -6
+24 -6
drivers/clocksource/timer-davinci.c
··· 257 257 resource_size(&timer_cfg->reg), 258 258 "davinci-timer")) { 259 259 pr_err("Unable to request memory region\n"); 260 - return -EBUSY; 260 + rv = -EBUSY; 261 + goto exit_clk_disable; 261 262 } 262 263 263 264 base = ioremap(timer_cfg->reg.start, resource_size(&timer_cfg->reg)); 264 265 if (!base) { 265 266 pr_err("Unable to map the register range\n"); 266 - return -ENOMEM; 267 + rv = -ENOMEM; 268 + goto exit_mem_region; 267 269 } 268 270 269 271 davinci_timer_init(base); 270 272 tick_rate = clk_get_rate(clk); 271 273 272 274 clockevent = kzalloc(sizeof(*clockevent), GFP_KERNEL); 273 - if (!clockevent) 274 - return -ENOMEM; 275 + if (!clockevent) { 276 + rv = -ENOMEM; 277 + goto exit_iounmap_base; 278 + } 275 279 276 280 clockevent->dev.name = "tim12"; 277 281 clockevent->dev.features = CLOCK_EVT_FEAT_ONESHOT; ··· 300 296 "clockevent/tim12", clockevent); 301 297 if (rv) { 302 298 pr_err("Unable to request the clockevent interrupt\n"); 303 - return rv; 299 + goto exit_free_clockevent; 304 300 } 305 301 306 302 davinci_clocksource.dev.rating = 300; ··· 327 323 rv = clocksource_register_hz(&davinci_clocksource.dev, tick_rate); 328 324 if (rv) { 329 325 pr_err("Unable to register clocksource\n"); 330 - return rv; 326 + goto exit_free_irq; 331 327 } 332 328 333 329 sched_clock_register(davinci_timer_read_sched_clock, 334 330 DAVINCI_TIMER_CLKSRC_BITS, tick_rate); 335 331 336 332 return 0; 333 + 334 + exit_free_irq: 335 + free_irq(timer_cfg->irq[DAVINCI_TIMER_CLOCKEVENT_IRQ].start, 336 + clockevent); 337 + exit_free_clockevent: 338 + kfree(clockevent); 339 + exit_iounmap_base: 340 + iounmap(base); 341 + exit_mem_region: 342 + release_mem_region(timer_cfg->reg.start, 343 + resource_size(&timer_cfg->reg)); 344 + exit_clk_disable: 345 + clk_disable_unprepare(clk); 346 + return rv; 337 347 } 338 348 339 349 static int __init of_davinci_timer_register(struct device_node *np)