Message ID | 20210830172541.62588-1-mat.jonczyk@o2.pl |
---|---|
State | Superseded |
Headers | show |
Series | rtc-cmos: take rtc_lock while accessing CMOS | expand |
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 --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;
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(+)