1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * ACRN detection support 4 * 5 * Copyright (C) 2019 Intel Corporation. All rights reserved. 6 * 7 * Jason Chen CJ <jason.cj.chen@intel.com> 8 * Zhao Yakui <yakui.zhao@intel.com> 9 * 10 */ 11 12 #include <linux/interrupt.h> 13 #include <asm/acrn.h> 14 #include <asm/apic.h> 15 #include <asm/desc.h> 16 #include <asm/hypervisor.h> 17 #include <asm/irq_regs.h> 18 19 static uint32_t __init acrn_detect(void) 20 { 21 return hypervisor_cpuid_base("ACRNACRNACRN\0\0", 0); 22 } 23 24 static void __init acrn_init_platform(void) 25 { 26 /* Setup the IDT for ACRN hypervisor callback */ 27 alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, acrn_hv_callback_vector); 28 } 29 30 static bool acrn_x2apic_available(void) 31 { 32 /* 33 * x2apic is not supported for now. Future enablement will have to check 34 * X86_FEATURE_X2APIC to determine whether x2apic is supported in the 35 * guest. 36 */ 37 return false; 38 } 39 40 static void (*acrn_intr_handler)(void); 41 42 __visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs) 43 { 44 struct pt_regs *old_regs = set_irq_regs(regs); 45 46 /* 47 * The hypervisor requires that the APIC EOI should be acked. 48 * If the APIC EOI is not acked, the APIC ISR bit for the 49 * HYPERVISOR_CALLBACK_VECTOR will not be cleared and then it 50 * will block the interrupt whose vector is lower than 51 * HYPERVISOR_CALLBACK_VECTOR. 52 */ 53 entering_ack_irq(); 54 inc_irq_stat(irq_hv_callback_count); 55 56 if (acrn_intr_handler) 57 acrn_intr_handler(); 58 59 exiting_irq(); 60 set_irq_regs(old_regs); 61 } 62 63 const __initconst struct hypervisor_x86 x86_hyper_acrn = { 64 .name = "ACRN", 65 .detect = acrn_detect, 66 .type = X86_HYPER_ACRN, 67 .init.init_platform = acrn_init_platform, 68 .init.x2apic_available = acrn_x2apic_available, 69 }; 70