0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/interrupt.h>
0013
0014 #include <asm/acrn.h>
0015 #include <asm/apic.h>
0016 #include <asm/cpufeatures.h>
0017 #include <asm/desc.h>
0018 #include <asm/hypervisor.h>
0019 #include <asm/idtentry.h>
0020 #include <asm/irq_regs.h>
0021
0022 static u32 __init acrn_detect(void)
0023 {
0024 return acrn_cpuid_base();
0025 }
0026
0027 static void __init acrn_init_platform(void)
0028 {
0029
0030 alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_acrn_hv_callback);
0031 }
0032
0033 static bool acrn_x2apic_available(void)
0034 {
0035 return boot_cpu_has(X86_FEATURE_X2APIC);
0036 }
0037
0038 static void (*acrn_intr_handler)(void);
0039
0040 DEFINE_IDTENTRY_SYSVEC(sysvec_acrn_hv_callback)
0041 {
0042 struct pt_regs *old_regs = set_irq_regs(regs);
0043
0044
0045
0046
0047
0048
0049
0050
0051 ack_APIC_irq();
0052 inc_irq_stat(irq_hv_callback_count);
0053
0054 if (acrn_intr_handler)
0055 acrn_intr_handler();
0056
0057 set_irq_regs(old_regs);
0058 }
0059
0060 void acrn_setup_intr_handler(void (*handler)(void))
0061 {
0062 acrn_intr_handler = handler;
0063 }
0064 EXPORT_SYMBOL_GPL(acrn_setup_intr_handler);
0065
0066 void acrn_remove_intr_handler(void)
0067 {
0068 acrn_intr_handler = NULL;
0069 }
0070 EXPORT_SYMBOL_GPL(acrn_remove_intr_handler);
0071
0072 const __initconst struct hypervisor_x86 x86_hyper_acrn = {
0073 .name = "ACRN",
0074 .detect = acrn_detect,
0075 .type = X86_HYPER_ACRN,
0076 .init.init_platform = acrn_init_platform,
0077 .init.x2apic_available = acrn_x2apic_available,
0078 };