linux-rtc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] rtc: armada38x: fix possible race condition
@ 2018-09-24 14:25 Alexandre Belloni
  2018-09-24 14:25 ` [PATCH 2/3] rtc: armada38x: add range Alexandre Belloni
  2018-09-24 14:25 ` [PATCH 3/3] rtc: armada38x: switch to rtc_time64_to_tm/rtc_tm_to_time64 Alexandre Belloni
  0 siblings, 2 replies; 4+ messages in thread
From: Alexandre Belloni @ 2018-09-24 14:25 UTC (permalink / raw)
  To: linux-rtc
  Cc: Gregory Clement, Thomas Petazzoni, linux-kernel,
	Alexandre Belloni

The IRQ is requested before the struct rtc is allocated and registered, but
this struct is used in the IRQ handler. This may lead to a NULL pointer
dereference.

Switch to devm_rtc_allocate_device/rtc_register_device to allocate the rtc
before requesting the IRQ.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-armada38x.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
index bde53c8ccee2..b74338d6dde6 100644
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -514,7 +514,6 @@ MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table);
 
 static __init int armada38x_rtc_probe(struct platform_device *pdev)
 {
-	const struct rtc_class_ops *ops;
 	struct resource *res;
 	struct armada38x_rtc *rtc;
 	const struct of_device_id *match;
@@ -551,6 +550,11 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "no irq\n");
 		return rtc->irq;
 	}
+
+	rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
+	if (IS_ERR(rtc->rtc_dev))
+		return PTR_ERR(rtc->rtc_dev);
+
 	if (devm_request_irq(&pdev->dev, rtc->irq, armada38x_rtc_alarm_irq,
 				0, pdev->name, rtc) < 0) {
 		dev_warn(&pdev->dev, "Interrupt not available.\n");
@@ -560,28 +564,24 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
 
 	if (rtc->irq != -1) {
 		device_init_wakeup(&pdev->dev, 1);
-		ops = &armada38x_rtc_ops;
+		rtc->rtc_dev->ops = &armada38x_rtc_ops;
 	} else {
 		/*
 		 * If there is no interrupt available then we can't
 		 * use the alarm
 		 */
-		ops = &armada38x_rtc_ops_noirq;
+		rtc->rtc_dev->ops = &armada38x_rtc_ops_noirq;
 	}
 	rtc->data = (struct armada38x_rtc_data *)match->data;
 
-
 	/* Update RTC-MBUS bridge timing parameters */
 	rtc->data->update_mbus_timing(rtc);
 
-	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
-						ops, THIS_MODULE);
-	if (IS_ERR(rtc->rtc_dev)) {
-		ret = PTR_ERR(rtc->rtc_dev);
+	ret = rtc_register_device(rtc->rtc_dev);
+	if (ret)
 		dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
-		return ret;
-	}
-	return 0;
+
+	return ret;
 }
 
 #ifdef CONFIG_PM_SLEEP
-- 
2.19.0

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] rtc: armada38x: add range
  2018-09-24 14:25 [PATCH 1/3] rtc: armada38x: fix possible race condition Alexandre Belloni
@ 2018-09-24 14:25 ` Alexandre Belloni
  2018-09-24 15:44   ` Gregory CLEMENT
  2018-09-24 14:25 ` [PATCH 3/3] rtc: armada38x: switch to rtc_time64_to_tm/rtc_tm_to_time64 Alexandre Belloni
  1 sibling, 1 reply; 4+ messages in thread
From: Alexandre Belloni @ 2018-09-24 14:25 UTC (permalink / raw)
  To: linux-rtc
  Cc: Gregory Clement, Thomas Petazzoni, linux-kernel,
	Alexandre Belloni

The RTC is a 32bit seconds counter.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-armada38x.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
index b74338d6dde6..d0278ad0a7f9 100644
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -577,6 +577,8 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
 	/* Update RTC-MBUS bridge timing parameters */
 	rtc->data->update_mbus_timing(rtc);
 
+	rtc->rtc_dev->range_max = U32_MAX;
+
 	ret = rtc_register_device(rtc->rtc_dev);
 	if (ret)
 		dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
-- 
2.19.0

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] rtc: armada38x: switch to rtc_time64_to_tm/rtc_tm_to_time64
  2018-09-24 14:25 [PATCH 1/3] rtc: armada38x: fix possible race condition Alexandre Belloni
  2018-09-24 14:25 ` [PATCH 2/3] rtc: armada38x: add range Alexandre Belloni
@ 2018-09-24 14:25 ` Alexandre Belloni
  1 sibling, 0 replies; 4+ messages in thread
From: Alexandre Belloni @ 2018-09-24 14:25 UTC (permalink / raw)
  To: linux-rtc
  Cc: Gregory Clement, Thomas Petazzoni, linux-kernel,
	Alexandre Belloni

Call the 64bit versions of rtc_time_to_tm and rtc_tm_to_time now that the
range is enforced by the core.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-armada38x.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
index d0278ad0a7f9..9e78f004670b 100644
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -224,7 +224,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
 	time = rtc->data->read_rtc_reg(rtc, RTC_TIME);
 	spin_unlock_irqrestore(&rtc->lock, flags);
 
-	rtc_time_to_tm(time, tm);
+	rtc_time64_to_tm(time, tm);
 
 	return 0;
 }
@@ -249,13 +249,9 @@ static void armada38x_rtc_reset(struct armada38x_rtc *rtc)
 static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
 	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
-	int ret = 0;
 	unsigned long time, flags;
 
-	ret = rtc_tm_to_time(tm, &time);
-
-	if (ret)
-		goto out;
+	time = rtc_tm_to_time64(tm);
 
 	if (!rtc->initialized)
 		armada38x_rtc_reset(rtc);
@@ -264,8 +260,7 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	rtc_delayed_write(time, rtc, RTC_TIME);
 	spin_unlock_irqrestore(&rtc->lock, flags);
 
-out:
-	return ret;
+	return 0;
 }
 
 static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
@@ -284,7 +279,7 @@ static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	spin_unlock_irqrestore(&rtc->lock, flags);
 
 	alrm->enabled = val ? 1 : 0;
-	rtc_time_to_tm(time,  &alrm->time);
+	rtc_time64_to_tm(time,  &alrm->time);
 
 	return 0;
 }
@@ -295,12 +290,8 @@ static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm);
 	u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm);
 	unsigned long time, flags;
-	int ret = 0;
 
-	ret = rtc_tm_to_time(&alrm->time, &time);
-
-	if (ret)
-		goto out;
+	time = rtc_tm_to_time64(&alrm->time);
 
 	spin_lock_irqsave(&rtc->lock, flags);
 
@@ -313,8 +304,7 @@ static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 	spin_unlock_irqrestore(&rtc->lock, flags);
 
-out:
-	return ret;
+	return 0;
 }
 
 static int armada38x_rtc_alarm_irq_enable(struct device *dev,
-- 
2.19.0

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/3] rtc: armada38x: add range
  2018-09-24 14:25 ` [PATCH 2/3] rtc: armada38x: add range Alexandre Belloni
@ 2018-09-24 15:44   ` Gregory CLEMENT
  0 siblings, 0 replies; 4+ messages in thread
From: Gregory CLEMENT @ 2018-09-24 15:44 UTC (permalink / raw)
  To: Alexandre Belloni; +Cc: linux-rtc, Thomas Petazzoni, linux-kernel

Hi Alexandre,
 
 On lun., sept. 24 2018, Alexandre Belloni <alexandre.belloni@bootlin.com> wrote:

> The RTC is a 32bit seconds counter.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

I checked that with a 64bits userspace setting the date further than
2106 doesn't wrap silently anymore.

Tested-by: Gregory CLEMENT <gregory.clement@bootlin.com>

Thanks,

Gregory

> ---
>  drivers/rtc/rtc-armada38x.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
> index b74338d6dde6..d0278ad0a7f9 100644
> --- a/drivers/rtc/rtc-armada38x.c
> +++ b/drivers/rtc/rtc-armada38x.c
> @@ -577,6 +577,8 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
>  	/* Update RTC-MBUS bridge timing parameters */
>  	rtc->data->update_mbus_timing(rtc);
>  
> +	rtc->rtc_dev->range_max = U32_MAX;
> +
>  	ret = rtc_register_device(rtc->rtc_dev);
>  	if (ret)
>  		dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
> -- 
> 2.19.0
>

-- 
Gregory Clement, Bootlin
Embedded Linux and Kernel engineering
http://bootlin.com

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-09-24 21:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-09-24 14:25 [PATCH 1/3] rtc: armada38x: fix possible race condition Alexandre Belloni
2018-09-24 14:25 ` [PATCH 2/3] rtc: armada38x: add range Alexandre Belloni
2018-09-24 15:44   ` Gregory CLEMENT
2018-09-24 14:25 ` [PATCH 3/3] rtc: armada38x: switch to rtc_time64_to_tm/rtc_tm_to_time64 Alexandre Belloni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).