提交 9328d04a 编写于 作者: A Andre Przywara 提交者: Zheng Zengkai

rtc: sun6i: Fix time overflow handling

stable inclusion
from stable-v5.10.118
commit 703c80ff4330377a70aa5662db256d55ee12961e
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5L686

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=703c80ff4330377a70aa5662db256d55ee12961e

--------------------------------

[ Upstream commit 9f6cd82e ]

Using "unsigned long" for UNIX timestamps is never a good idea, and
comparing the value of such a variable against U32_MAX does not do
anything useful on 32-bit systems.

Use the proper time64_t type when dealing with timestamps, and avoid
cutting down the time range unnecessarily. This also fixes the flawed
check for the alarm time being too far into the future.

The check for this condition is actually somewhat theoretical, as the
RTC counts till 2033 only anyways, and 2^32 seconds from now is not
before the year 2157 - at which point I hope nobody will be using this
hardware anymore.
Signed-off-by: NAndre Przywara <andre.przywara@arm.com>
Reviewed-by: NJernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: NAlexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/20220211122643.1343315-4-andre.przywara@arm.comSigned-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
Acked-by: NXie XiuQi <xiexiuqi@huawei.com>
上级 1ce90f2c
......@@ -138,7 +138,7 @@ struct sun6i_rtc_dev {
const struct sun6i_rtc_clk_data *data;
void __iomem *base;
int irq;
unsigned long alarm;
time64_t alarm;
struct clk_hw hw;
struct clk_hw *int_osc;
......@@ -510,10 +510,8 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
struct rtc_time *alrm_tm = &wkalrm->time;
struct rtc_time tm_now;
unsigned long time_now = 0;
unsigned long time_set = 0;
unsigned long time_gap = 0;
int ret = 0;
time64_t time_now, time_set;
int ret;
ret = sun6i_rtc_gettime(dev, &tm_now);
if (ret < 0) {
......@@ -528,9 +526,7 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
return -EINVAL;
}
time_gap = time_set - time_now;
if (time_gap > U32_MAX) {
if ((time_set - time_now) > U32_MAX) {
dev_err(dev, "Date too far in the future\n");
return -EINVAL;
}
......@@ -539,7 +535,7 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
writel(0, chip->base + SUN6I_ALRM_COUNTER);
usleep_range(100, 300);
writel(time_gap, chip->base + SUN6I_ALRM_COUNTER);
writel(time_set - time_now, chip->base + SUN6I_ALRM_COUNTER);
chip->alarm = time_set;
sun6i_rtc_setaie(wkalrm->enabled, chip);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册