aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/mshyperv.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/mshyperv.c')
-rw-r--r--arch/x86/kernel/cpu/mshyperv.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 9340f41ce8d3..4488cf0dd499 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -37,6 +37,7 @@ EXPORT_SYMBOL_GPL(ms_hyperv);
37 37
38#if IS_ENABLED(CONFIG_HYPERV) 38#if IS_ENABLED(CONFIG_HYPERV)
39static void (*vmbus_handler)(void); 39static void (*vmbus_handler)(void);
40static void (*hv_stimer0_handler)(void);
40static void (*hv_kexec_handler)(void); 41static void (*hv_kexec_handler)(void);
41static void (*hv_crash_handler)(struct pt_regs *regs); 42static void (*hv_crash_handler)(struct pt_regs *regs);
42 43
@@ -69,6 +70,41 @@ void hv_remove_vmbus_irq(void)
69EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq); 70EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq);
70EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq); 71EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq);
71 72
73/*
74 * Routines to do per-architecture handling of stimer0
75 * interrupts when in Direct Mode
76 */
77
78__visible void __irq_entry hv_stimer0_vector_handler(struct pt_regs *regs)
79{
80 struct pt_regs *old_regs = set_irq_regs(regs);
81
82 entering_irq();
83 inc_irq_stat(hyperv_stimer0_count);
84 if (hv_stimer0_handler)
85 hv_stimer0_handler();
86 ack_APIC_irq();
87
88 exiting_irq();
89 set_irq_regs(old_regs);
90}
91
92int hv_setup_stimer0_irq(int *irq, int *vector, void (*handler)(void))
93{
94 *vector = HYPERV_STIMER0_VECTOR;
95 *irq = 0; /* Unused on x86/x64 */
96 hv_stimer0_handler = handler;
97 return 0;
98}
99EXPORT_SYMBOL_GPL(hv_setup_stimer0_irq);
100
101void hv_remove_stimer0_irq(int irq)
102{
103 /* We have no way to deallocate the interrupt gate */
104 hv_stimer0_handler = NULL;
105}
106EXPORT_SYMBOL_GPL(hv_remove_stimer0_irq);
107
72void hv_setup_kexec_handler(void (*handler)(void)) 108void hv_setup_kexec_handler(void (*handler)(void))
73{ 109{
74 hv_kexec_handler = handler; 110 hv_kexec_handler = handler;
@@ -257,6 +293,10 @@ static void __init ms_hyperv_init_platform(void)
257 alloc_intr_gate(HYPERV_REENLIGHTENMENT_VECTOR, 293 alloc_intr_gate(HYPERV_REENLIGHTENMENT_VECTOR,
258 hyperv_reenlightenment_vector); 294 hyperv_reenlightenment_vector);
259 295
296 /* Setup the IDT for stimer0 */
297 if (ms_hyperv.misc_features & HV_X64_STIMER_DIRECT_MODE_AVAILABLE)
298 alloc_intr_gate(HYPERV_STIMER0_VECTOR,
299 hv_stimer0_callback_vector);
260#endif 300#endif
261} 301}
262 302