diff mbox series

rtc-cmos: take rtc_lock while accessing CMOS

Message ID 20210830172541.62588-1-mat.jonczyk@o2.pl
State Superseded
Headers show
Series rtc-cmos: take rtc_lock while accessing CMOS | expand

Commit Message

Mateusz Jończyk Aug. 30, 2021, 5:25 p.m. UTC
Reading from the CMOS involves writing to the index register and then
reading from the data register. Therefore access to the CMOS has to be
serialized with a spinlock. An invocation in cmos_set_alarm was not
serialized with rtc_lock, fix this.

Use spin_lock_irq() like the rest of the function.

Nothing in kernel modifies the RTC_DM_BINARY bit, so use a separate pair
of spin_lock_irq() / spin_unlock_irq() before doing the math.

Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: stable@vger.kernel.org
---
 drivers/rtc/rtc-cmos.c | 3 +++
 1 file changed, 3 insertions(+)

Comments

Nobuhiro Iwamatsu Aug. 31, 2021, 11:20 p.m. UTC | #1
Hi,

2021年8月31日(火) 2:26 Mateusz Jończyk <mat.jonczyk@o2.pl>:
>

> Reading from the CMOS involves writing to the index register and then

> reading from the data register. Therefore access to the CMOS has to be

> serialized with a spinlock. An invocation in cmos_set_alarm was not

> serialized with rtc_lock, fix this.

>

> Use spin_lock_irq() like the rest of the function.

>

> Nothing in kernel modifies the RTC_DM_BINARY bit, so use a separate pair

> of spin_lock_irq() / spin_unlock_irq() before doing the math.

>

> Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl>

> Cc: Alessandro Zummo <a.zummo@towertech.it>

> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>

> Cc: stable@vger.kernel.org

> ---

>  drivers/rtc/rtc-cmos.c | 3 +++

>  1 file changed, 3 insertions(+)


Reviewed-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>


Best regards,
  Nobuhiro

>

> diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c

> index 0fa66d1039b9..e6ff0fb7591b 100644

> --- a/drivers/rtc/rtc-cmos.c

> +++ b/drivers/rtc/rtc-cmos.c

> @@ -463,7 +463,10 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)

>         min = t->time.tm_min;

>         sec = t->time.tm_sec;

>

> +       spin_lock_irq(&rtc_lock);

>         rtc_control = CMOS_READ(RTC_CONTROL);

> +       spin_unlock_irq(&rtc_lock);

> +

>         if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {

>                 /* Writing 0xff means "don't care" or "match all".  */

>                 mon = (mon <= 12) ? bin2bcd(mon) : 0xff;

> --

> 2.25.1

>



-- 
Nobuhiro Iwamatsu
   iwamatsu at {nigauri.org / debian.org}
   GPG ID: 40AD1FA6
diff mbox series

Patch

diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 0fa66d1039b9..e6ff0fb7591b 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -463,7 +463,10 @@  static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 	min = t->time.tm_min;
 	sec = t->time.tm_sec;
 
+	spin_lock_irq(&rtc_lock);
 	rtc_control = CMOS_READ(RTC_CONTROL);
+	spin_unlock_irq(&rtc_lock);
+
 	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
 		/* Writing 0xff means "don't care" or "match all".  */
 		mon = (mon <= 12) ? bin2bcd(mon) : 0xff;