x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector
authorZhao Yakui <yakui.zhao@intel.com>
Tue, 30 Apr 2019 03:45:25 +0000 (11:45 +0800)
committerBorislav Petkov <bp@suse.de>
Tue, 11 Jun 2019 19:31:31 +0000 (21:31 +0200)
Use the HYPERVISOR_CALLBACK_VECTOR to notify an ACRN guest.

Co-developed-by: Jason Chen CJ <jason.cj.chen@intel.com>
Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com>
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/1559108037-18813-4-git-send-email-yakui.zhao@intel.com
arch/x86/Kconfig
arch/x86/entry/entry_64.S
arch/x86/include/asm/acrn.h [new file with mode: 0644]
arch/x86/kernel/cpu/acrn.c

index 8a95c50..0ddcce7 100644 (file)
@@ -838,6 +838,7 @@ config JAILHOUSE_GUEST
 config ACRN_GUEST
        bool "ACRN Guest support"
        depends on X86_64
+       select X86_HV_CALLBACK_VECTOR
        help
          This option allows to run Linux as guest in the ACRN hypervisor. ACRN is
          a flexible, lightweight reference open-source hypervisor, built with
index 11aa3b2..2fe6289 100644 (file)
@@ -1142,6 +1142,11 @@ apicinterrupt3 HYPERV_STIMER0_VECTOR \
        hv_stimer0_callback_vector hv_stimer0_vector_handler
 #endif /* CONFIG_HYPERV */
 
+#if IS_ENABLED(CONFIG_ACRN_GUEST)
+apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+       acrn_hv_callback_vector acrn_hv_vector_handler
+#endif
+
 idtentry debug                 do_debug                has_error_code=0        paranoid=1 shift_ist=IST_INDEX_DB ist_offset=DB_STACK_OFFSET
 idtentry int3                  do_int3                 has_error_code=0        create_gap=1
 idtentry stack_segment         do_stack_segment        has_error_code=1
diff --git a/arch/x86/include/asm/acrn.h b/arch/x86/include/asm/acrn.h
new file mode 100644 (file)
index 0000000..4adb13f
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_ACRN_H
+#define _ASM_X86_ACRN_H
+
+extern void acrn_hv_callback_vector(void);
+#ifdef CONFIG_TRACING
+#define trace_acrn_hv_callback_vector acrn_hv_callback_vector
+#endif
+
+extern void acrn_hv_vector_handler(struct pt_regs *regs);
+#endif /* _ASM_X86_ACRN_H */
index 6d365e9..676022e 100644 (file)
@@ -9,7 +9,12 @@
  *
  */
 
+#include <linux/interrupt.h>
+#include <asm/acrn.h>
+#include <asm/apic.h>
+#include <asm/desc.h>
 #include <asm/hypervisor.h>
+#include <asm/irq_regs.h>
 
 static uint32_t __init acrn_detect(void)
 {
@@ -18,6 +23,8 @@ static uint32_t __init acrn_detect(void)
 
 static void __init acrn_init_platform(void)
 {
+       /* Setup the IDT for ACRN hypervisor callback */
+       alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, acrn_hv_callback_vector);
 }
 
 static bool acrn_x2apic_available(void)
@@ -30,6 +37,29 @@ static bool acrn_x2apic_available(void)
        return false;
 }
 
+static void (*acrn_intr_handler)(void);
+
+__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs)
+{
+       struct pt_regs *old_regs = set_irq_regs(regs);
+
+       /*
+        * The hypervisor requires that the APIC EOI should be acked.
+        * If the APIC EOI is not acked, the APIC ISR bit for the
+        * HYPERVISOR_CALLBACK_VECTOR will not be cleared and then it
+        * will block the interrupt whose vector is lower than
+        * HYPERVISOR_CALLBACK_VECTOR.
+        */
+       entering_ack_irq();
+       inc_irq_stat(irq_hv_callback_count);
+
+       if (acrn_intr_handler)
+               acrn_intr_handler();
+
+       exiting_irq();
+       set_irq_regs(old_regs);
+}
+
 const __initconst struct hypervisor_x86 x86_hyper_acrn = {
        .name                   = "ACRN",
        .detect                 = acrn_detect,