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(+)
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;
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
linux-stable-mirror@lists.linaro.org