From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
To: Gregory CLEMENT <gregory.clement@free-electrons.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>,
rtc-linux@googlegroups.com, Arnaud Ebalard <arno@natisbad.org>,
Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>,
Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>,
Thomas Petazzoni <thomas.petazzoni@free-electrons.com>,
Ezequiel Garcia <ezequiel.garcia@free-electrons.com>,
linux-arm-kernel@lists.infradead.org,
Lior Amsalem <alior@marvell.com>,
Tawfik Bayouk <tawfik@marvell.com>,
Nadav Haklai <nadavh@marvell.com>,
stable@vger.kernel.org
Subject: [rtc-linux] Re: [PATCH] rtc: armada38x: Fix concurrency access in armada38x_rtc_set_time
Date: Fri, 17 Apr 2015 15:42:08 +0200 [thread overview]
Message-ID: <20150417134208.GH29796@piout.net> (raw)
In-Reply-To: <1429103633-24376-1-git-send-email-gregory.clement@free-electrons.com>
On 15/04/2015 at 15:13:53 +0200, Gregory CLEMENT wrote :
> While setting the time, the RTC TIME register should not be
> accessed. However due to hardware constraints, setting the RTC time
> involves sleeping during 100ms. This sleep was done outside the
> critical section protected by the spinlock, so it was possible to read
> the RTC TIME register and get an incorrect value. This patch
> introduces a mutex for protecting the RTC TIME access, unlike the
> spinlock it is allowed to sleep in a critical section protected by a
> mutex. The RTC STATUS register can still be used from the interrupt
> handler but it has no effect on setting the time.
>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> Cc: <stable@vger.kernel.org> #v4.0
> ---
> Hi,
>
> I finally got more information about the RTC behavior and while it is
> fine accessing RTC_STATUS register during between RTC_STATUS reset and
> writing time in RTC_TIME register, reading RTC_TIME during this period
> might five incorrect value.
>
> It is too late to fix 4.0, but we are in time for 4.1 and this patch
> was tagged to be applied to the stable version of 4.0.
>
> Gregory
>
>
> drivers/rtc/rtc-armada38x.c | 24 ++++++++++++------------
> 1 file changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
> index 43e04af39e09..cb70ced7e0db 100644
> --- a/drivers/rtc/rtc-armada38x.c
> +++ b/drivers/rtc/rtc-armada38x.c
> @@ -40,6 +40,13 @@ struct armada38x_rtc {
> void __iomem *regs;
> void __iomem *regs_soc;
> spinlock_t lock;
> + /*
> + * While setting the time, the RTC TIME register should not be
> + * accessed. Setting the RTC time involves sleeping during
> + * 100ms, so a mutex instead of a spinlock is used to protect
> + * it
> + */
> + struct mutex mutex_time;
> int irq;
> };
>
> @@ -59,8 +66,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
> struct armada38x_rtc *rtc = dev_get_drvdata(dev);
> unsigned long time, time_check, flags;
>
> - spin_lock_irqsave(&rtc->lock, flags);
> -
> + mutex_lock(&rtc->mutex_time);
> time = readl(rtc->regs + RTC_TIME);
> /*
> * WA for failing time set attempts. As stated in HW ERRATA if
> @@ -71,7 +77,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
> if ((time_check - time) > 1)
> time_check = readl(rtc->regs + RTC_TIME);
>
> - spin_unlock_irqrestore(&rtc->lock, flags);
> + mutex_unlock(&rtc->mutex_time);
>
> rtc_time_to_tm(time_check, tm);
>
> @@ -94,19 +100,12 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
> * then wait for 100ms before writing to the time register to be
> * sure that the data will be taken into account.
> */
> - spin_lock_irqsave(&rtc->lock, flags);
> -
> + mutex_lock(&rtc->mutex_time);
> rtc_delayed_write(0, rtc, RTC_STATUS);
> -
> - spin_unlock_irqrestore(&rtc->lock, flags);
> -
> msleep(100);
> -
> - spin_lock_irqsave(&rtc->lock, flags);
> -
> rtc_delayed_write(time, rtc, RTC_TIME);
> + mutex_unlock(&rtc->mutex_time);
>
> - spin_unlock_irqrestore(&rtc->lock, flags);
> out:
> return ret;
> }
> @@ -230,6 +229,7 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
> return -ENOMEM;
>
> spin_lock_init(&rtc->lock);
> + mutex_init(&rtc->mutex_time);
>
> res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
> rtc->regs = devm_ioremap_resource(&pdev->dev, res);
> --
> 2.1.0
>
--
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
--
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
prev parent reply other threads:[~2015-04-17 13:42 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-15 13:13 [rtc-linux] [PATCH] rtc: armada38x: Fix concurrency access in armada38x_rtc_set_time Gregory CLEMENT
2015-04-15 19:27 ` [rtc-linux] " Andrew Lunn
2015-04-17 13:13 ` Gregory CLEMENT
2015-04-17 13:17 ` Andrew Lunn
2015-04-17 13:42 ` Alexandre Belloni [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150417134208.GH29796@piout.net \
--to=alexandre.belloni@free-electrons.com \
--cc=a.zummo@towertech.it \
--cc=alior@marvell.com \
--cc=andrew@lunn.ch \
--cc=arno@natisbad.org \
--cc=ezequiel.garcia@free-electrons.com \
--cc=gregory.clement@free-electrons.com \
--cc=jason@lakedaemon.net \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=nadavh@marvell.com \
--cc=rtc-linux@googlegroups.com \
--cc=sebastian.hesselbarth@gmail.com \
--cc=stable@vger.kernel.org \
--cc=tawfik@marvell.com \
--cc=thomas.petazzoni@free-electrons.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox