Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtc: cmos: take rtc_lock while reading from CMOS

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 rtc_lock. This invocation of CMOS_READ was not
serialized, which could cause trouble when other code is accessing CMOS
at the same time.

Use spin_lock_irq() like the rest of the function.

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

Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl>
Reviewed-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: stable@vger.kernel.org
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/20211210200131.153887-2-mat.jonczyk@o2.pl

authored by

Mateusz Jończyk and committed by
Alexandre Belloni
454f47ff c636783d

+3
+3
drivers/rtc/rtc-cmos.c
··· 457 457 min = t->time.tm_min; 458 458 sec = t->time.tm_sec; 459 459 460 + spin_lock_irq(&rtc_lock); 460 461 rtc_control = CMOS_READ(RTC_CONTROL); 462 + spin_unlock_irq(&rtc_lock); 463 + 461 464 if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 462 465 /* Writing 0xff means "don't care" or "match all". */ 463 466 mon = (mon <= 12) ? bin2bcd(mon) : 0xff;