* [PATCH 0/2] watchdog: fixes for menz069_wdt driver @ 2023-04-18 17:25 Johannes Thumshirn 2023-04-18 17:25 ` [PATCH 1/2] watchdog: menz069_wdt: fix watchdog initialisation Johannes Thumshirn 2023-04-18 17:25 ` [PATCH 2/2] watchdog: menz069_wdt: fix timeout setting Johannes Thumshirn 0 siblings, 2 replies; 5+ messages in thread From: Johannes Thumshirn @ 2023-04-18 17:25 UTC (permalink / raw) To: Wim Van Sebroeck, Guenter Roeck Cc: linux-watchdog, linux-kernel, Johannes Thumshirn While testing the Qemu emulation of the menz069_wdt watchdog core, I've found two issues in the kernel driver. On is a NULL pointer dereference, because the driver can't access it's private data and one is a wrong register read resulting in incorrect timeout values being set. Johannes Thumshirn (2): watchdog: menz069_wdt: fix watchdog initialisation watchdog: menz069_wdt: fix timeout setting drivers/watchdog/menz69_wdt.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) -- 2.39.2 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] watchdog: menz069_wdt: fix watchdog initialisation 2023-04-18 17:25 [PATCH 0/2] watchdog: fixes for menz069_wdt driver Johannes Thumshirn @ 2023-04-18 17:25 ` Johannes Thumshirn 2023-04-18 18:20 ` Guenter Roeck 2023-04-18 17:25 ` [PATCH 2/2] watchdog: menz069_wdt: fix timeout setting Johannes Thumshirn 1 sibling, 1 reply; 5+ messages in thread From: Johannes Thumshirn @ 2023-04-18 17:25 UTC (permalink / raw) To: Wim Van Sebroeck, Guenter Roeck Cc: linux-watchdog, linux-kernel, Johannes Thumshirn Doing a 'cat /dev/watchdog0' with menz069_wdt as watchdog0 will result in a NULL pointer dereference. This happens because we're passing the wrong pointer to watchdog_register_device(). Fix this by getting rid of the static watchdog_device structure and use the one embedded into the driver's per-instance private data. Signed-off-by: Johannes Thumshirn <jth@kernel.org> --- drivers/watchdog/menz69_wdt.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/watchdog/menz69_wdt.c b/drivers/watchdog/menz69_wdt.c index 8973f98bc6a5..bca0938f3429 100644 --- a/drivers/watchdog/menz69_wdt.c +++ b/drivers/watchdog/menz69_wdt.c @@ -98,14 +98,6 @@ static const struct watchdog_ops men_z069_ops = { .set_timeout = men_z069_wdt_set_timeout, }; -static struct watchdog_device men_z069_wdt = { - .info = &men_z069_info, - .ops = &men_z069_ops, - .timeout = MEN_Z069_DEFAULT_TIMEOUT, - .min_timeout = 1, - .max_timeout = MEN_Z069_WDT_COUNTER_MAX / MEN_Z069_TIMER_FREQ, -}; - static int men_z069_probe(struct mcb_device *dev, const struct mcb_device_id *id) { @@ -125,15 +117,19 @@ static int men_z069_probe(struct mcb_device *dev, goto release_mem; drv->mem = mem; + drv->wdt.info = &men_z069_info; + drv->wdt.ops = &men_z069_ops; + drv->wdt.timeout = MEN_Z069_DEFAULT_TIMEOUT; + drv->wdt.min_timeout = 1; + drv->wdt.max_timeout = MEN_Z069_WDT_COUNTER_MAX / MEN_Z069_TIMER_FREQ; - drv->wdt = men_z069_wdt; watchdog_init_timeout(&drv->wdt, 0, &dev->dev); watchdog_set_nowayout(&drv->wdt, nowayout); watchdog_set_drvdata(&drv->wdt, drv); drv->wdt.parent = &dev->dev; mcb_set_drvdata(dev, drv); - return watchdog_register_device(&men_z069_wdt); + return watchdog_register_device(&drv->wdt); release_mem: mcb_release_mem(mem); -- 2.39.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] watchdog: menz069_wdt: fix watchdog initialisation 2023-04-18 17:25 ` [PATCH 1/2] watchdog: menz069_wdt: fix watchdog initialisation Johannes Thumshirn @ 2023-04-18 18:20 ` Guenter Roeck 0 siblings, 0 replies; 5+ messages in thread From: Guenter Roeck @ 2023-04-18 18:20 UTC (permalink / raw) To: Johannes Thumshirn, Wim Van Sebroeck; +Cc: linux-watchdog, linux-kernel On 4/18/23 10:25, Johannes Thumshirn wrote: > Doing a 'cat /dev/watchdog0' with menz069_wdt as watchdog0 will result in > a NULL pointer dereference. > > This happens because we're passing the wrong pointer to > watchdog_register_device(). Fix this by getting rid of the static > watchdog_device structure and use the one embedded into the driver's > per-instance private data. > > Signed-off-by: Johannes Thumshirn <jth@kernel.org> Reviewed-by: Guenter Roeck <linux@roeck-us.net> > --- > drivers/watchdog/menz69_wdt.c | 16 ++++++---------- > 1 file changed, 6 insertions(+), 10 deletions(-) > > diff --git a/drivers/watchdog/menz69_wdt.c b/drivers/watchdog/menz69_wdt.c > index 8973f98bc6a5..bca0938f3429 100644 > --- a/drivers/watchdog/menz69_wdt.c > +++ b/drivers/watchdog/menz69_wdt.c > @@ -98,14 +98,6 @@ static const struct watchdog_ops men_z069_ops = { > .set_timeout = men_z069_wdt_set_timeout, > }; > > -static struct watchdog_device men_z069_wdt = { > - .info = &men_z069_info, > - .ops = &men_z069_ops, > - .timeout = MEN_Z069_DEFAULT_TIMEOUT, > - .min_timeout = 1, > - .max_timeout = MEN_Z069_WDT_COUNTER_MAX / MEN_Z069_TIMER_FREQ, > -}; > - > static int men_z069_probe(struct mcb_device *dev, > const struct mcb_device_id *id) > { > @@ -125,15 +117,19 @@ static int men_z069_probe(struct mcb_device *dev, > goto release_mem; > > drv->mem = mem; > + drv->wdt.info = &men_z069_info; > + drv->wdt.ops = &men_z069_ops; > + drv->wdt.timeout = MEN_Z069_DEFAULT_TIMEOUT; > + drv->wdt.min_timeout = 1; > + drv->wdt.max_timeout = MEN_Z069_WDT_COUNTER_MAX / MEN_Z069_TIMER_FREQ; > > - drv->wdt = men_z069_wdt; > watchdog_init_timeout(&drv->wdt, 0, &dev->dev); > watchdog_set_nowayout(&drv->wdt, nowayout); > watchdog_set_drvdata(&drv->wdt, drv); > drv->wdt.parent = &dev->dev; > mcb_set_drvdata(dev, drv); > > - return watchdog_register_device(&men_z069_wdt); > + return watchdog_register_device(&drv->wdt); > > release_mem: > mcb_release_mem(mem); ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] watchdog: menz069_wdt: fix timeout setting 2023-04-18 17:25 [PATCH 0/2] watchdog: fixes for menz069_wdt driver Johannes Thumshirn 2023-04-18 17:25 ` [PATCH 1/2] watchdog: menz069_wdt: fix watchdog initialisation Johannes Thumshirn @ 2023-04-18 17:25 ` Johannes Thumshirn 2023-04-18 18:21 ` Guenter Roeck 1 sibling, 1 reply; 5+ messages in thread From: Johannes Thumshirn @ 2023-04-18 17:25 UTC (permalink / raw) To: Wim Van Sebroeck, Guenter Roeck Cc: linux-watchdog, linux-kernel, Johannes Thumshirn When setting the timeout for the menz069_wdt watchdog driver, we erroneously read from the 'watchdog value register' (WVR) instead of the 'watchdog timer register' (WTR) and then write the value back into WTR. This can potentially lead to wrong timeouts and wrong enable bit settings. Signed-off-by: Johannes Thumshirn <jth@kernel.org> --- drivers/watchdog/menz69_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/menz69_wdt.c b/drivers/watchdog/menz69_wdt.c index bca0938f3429..3c98030b9fcd 100644 --- a/drivers/watchdog/menz69_wdt.c +++ b/drivers/watchdog/menz69_wdt.c @@ -77,7 +77,7 @@ static int men_z069_wdt_set_timeout(struct watchdog_device *wdt, wdt->timeout = timeout; val = timeout * MEN_Z069_TIMER_FREQ; - reg = readw(drv->base + MEN_Z069_WVR); + reg = readw(drv->base + MEN_Z069_WTR); ena = reg & MEN_Z069_WTR_WDEN; reg = ena | val; writew(reg, drv->base + MEN_Z069_WTR); -- 2.39.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] watchdog: menz069_wdt: fix timeout setting 2023-04-18 17:25 ` [PATCH 2/2] watchdog: menz069_wdt: fix timeout setting Johannes Thumshirn @ 2023-04-18 18:21 ` Guenter Roeck 0 siblings, 0 replies; 5+ messages in thread From: Guenter Roeck @ 2023-04-18 18:21 UTC (permalink / raw) To: Johannes Thumshirn, Wim Van Sebroeck; +Cc: linux-watchdog, linux-kernel On 4/18/23 10:25, Johannes Thumshirn wrote: > When setting the timeout for the menz069_wdt watchdog driver, we > erroneously read from the 'watchdog value register' (WVR) instead of the > 'watchdog timer register' (WTR) and then write the value back into WTR. > > This can potentially lead to wrong timeouts and wrong enable bit settings. > > Signed-off-by: Johannes Thumshirn <jth@kernel.org> Reviewed-by: Guenter Roeck <linux@roeck-us.net> > --- > drivers/watchdog/menz69_wdt.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/watchdog/menz69_wdt.c b/drivers/watchdog/menz69_wdt.c > index bca0938f3429..3c98030b9fcd 100644 > --- a/drivers/watchdog/menz69_wdt.c > +++ b/drivers/watchdog/menz69_wdt.c > @@ -77,7 +77,7 @@ static int men_z069_wdt_set_timeout(struct watchdog_device *wdt, > wdt->timeout = timeout; > val = timeout * MEN_Z069_TIMER_FREQ; > > - reg = readw(drv->base + MEN_Z069_WVR); > + reg = readw(drv->base + MEN_Z069_WTR); > ena = reg & MEN_Z069_WTR_WDEN; > reg = ena | val; > writew(reg, drv->base + MEN_Z069_WTR); ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-04-18 18:21 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-04-18 17:25 [PATCH 0/2] watchdog: fixes for menz069_wdt driver Johannes Thumshirn 2023-04-18 17:25 ` [PATCH 1/2] watchdog: menz069_wdt: fix watchdog initialisation Johannes Thumshirn 2023-04-18 18:20 ` Guenter Roeck 2023-04-18 17:25 ` [PATCH 2/2] watchdog: menz069_wdt: fix timeout setting Johannes Thumshirn 2023-04-18 18:21 ` Guenter Roeck
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox