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

[PATCH] lockdep: HPET/RTC fix

Joseph Fannin reported that hpet_rtc_interrupt() enables hardirqs
in irq context:

[ 25.628000] [<c014af4e>] trace_hardirqs_on+0xce/0x200
[ 25.628000] [<c036cf21>] _spin_unlock_irq+0x31/0x70
[ 25.628000] [<c0296584>] rtc_get_rtc_time+0x44/0x1a0
[ 25.628000] [<c01198bb>] hpet_rtc_interrupt+0x21b/0x280
[ 25.628000] [<c0161141>] handle_IRQ_event+0x31/0x70
[ 25.628000] [<c0162d37>] handle_edge_irq+0xe7/0x210
[ 25.628000] [<c0106192>] do_IRQ+0x92/0x120
[ 25.628000] [<c0104121>] common_interrupt+0x25/0x2c

the call of rtc_get_rtc_time() is highly suspect. At a minimum we
need the patch below to save/restore hardirq state.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Cc: Joseph Fannin <jfannin@gmail.com>
Cc: John Stultz <johnstul@us.ibm.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Ingo Molnar and committed by
Linus Torvalds
0f749646 a29b0b74

+3 -3
+3 -3
drivers/char/rtc.c
··· 1245 1245 1246 1246 void rtc_get_rtc_time(struct rtc_time *rtc_tm) 1247 1247 { 1248 - unsigned long uip_watchdog = jiffies; 1248 + unsigned long uip_watchdog = jiffies, flags; 1249 1249 unsigned char ctrl; 1250 1250 #ifdef CONFIG_MACH_DECSTATION 1251 1251 unsigned int real_year; ··· 1272 1272 * RTC has RTC_DAY_OF_WEEK, we should usually ignore it, as it is 1273 1273 * only updated by the RTC when initially set to a non-zero value. 1274 1274 */ 1275 - spin_lock_irq(&rtc_lock); 1275 + spin_lock_irqsave(&rtc_lock, flags); 1276 1276 rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); 1277 1277 rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); 1278 1278 rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); ··· 1286 1286 real_year = CMOS_READ(RTC_DEC_YEAR); 1287 1287 #endif 1288 1288 ctrl = CMOS_READ(RTC_CONTROL); 1289 - spin_unlock_irq(&rtc_lock); 1289 + spin_unlock_irqrestore(&rtc_lock, flags); 1290 1290 1291 1291 if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) 1292 1292 {