hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/arch/x86/kernel/time.c
....@@ -10,6 +10,7 @@
1010 *
1111 */
1212
13
+#include <linux/clocksource.h>
1314 #include <linux/clockchips.h>
1415 #include <linux/interrupt.h>
1516 #include <linux/irq.h>
....@@ -32,8 +33,7 @@
3233 #ifdef CONFIG_FRAME_POINTER
3334 return *(unsigned long *)(regs->bp + sizeof(long));
3435 #else
35
- unsigned long *sp =
36
- (unsigned long *)kernel_stack_pointer(regs);
36
+ unsigned long *sp = (unsigned long *)regs->sp;
3737 /*
3838 * Return address is either directly at stack pointer
3939 * or above a saved flags. Eflags has bits 22-31 zero,
....@@ -58,39 +58,50 @@
5858 return IRQ_HANDLED;
5959 }
6060
61
-static struct irqaction irq0 = {
62
- .handler = timer_interrupt,
63
- .flags = IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
64
- .name = "timer"
65
-};
66
-
6761 static void __init setup_default_timer_irq(void)
6862 {
63
+ unsigned long flags = IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER;
64
+
6965 /*
70
- * Unconditionally register the legacy timer; even without legacy
71
- * PIC/PIT we need this for the HPET0 in legacy replacement mode.
66
+ * Unconditionally register the legacy timer interrupt; even
67
+ * without legacy PIC/PIT we need this for the HPET0 in legacy
68
+ * replacement mode.
7269 */
73
- if (setup_irq(0, &irq0))
70
+ if (request_irq(0, timer_interrupt, flags, "timer", NULL))
7471 pr_info("Failed to register legacy timer interrupt\n");
7572 }
7673
7774 /* Default timer init function */
7875 void __init hpet_time_init(void)
7976 {
80
- if (!hpet_enable())
81
- setup_pit_timer();
77
+ if (!hpet_enable()) {
78
+ if (!pit_timer_init())
79
+ return;
80
+ }
81
+
8282 setup_default_timer_irq();
8383 }
8484
8585 static __init void x86_late_time_init(void)
8686 {
87
- x86_init.timers.timer_init();
8887 /*
89
- * After PIT/HPET timers init, select and setup
90
- * the final interrupt mode for delivering IRQs.
88
+ * Before PIT/HPET init, select the interrupt mode. This is required
89
+ * to make the decision whether PIT should be initialized correct.
90
+ */
91
+ x86_init.irqs.intr_mode_select();
92
+
93
+ /* Setup the legacy timers */
94
+ x86_init.timers.timer_init();
95
+
96
+ /*
97
+ * After PIT/HPET timers init, set up the final interrupt mode for
98
+ * delivering IRQs.
9199 */
92100 x86_init.irqs.intr_mode_init();
93101 tsc_init();
102
+
103
+ if (static_cpu_has(X86_FEATURE_WAITPKG))
104
+ use_tpause_delay();
94105 }
95106
96107 /*
....@@ -101,3 +112,18 @@
101112 {
102113 late_time_init = x86_late_time_init;
103114 }
115
+
116
+/*
117
+ * Sanity check the vdso related archdata content.
118
+ */
119
+void clocksource_arch_init(struct clocksource *cs)
120
+{
121
+ if (cs->vdso_clock_mode == VDSO_CLOCKMODE_NONE)
122
+ return;
123
+
124
+ if (cs->mask != CLOCKSOURCE_MASK(64)) {
125
+ pr_warn("clocksource %s registered with invalid mask %016llx for VDSO. Disabling VDSO support.\n",
126
+ cs->name, cs->mask);
127
+ cs->vdso_clock_mode = VDSO_CLOCKMODE_NONE;
128
+ }
129
+}