From 9f3c723d0ab4dcd46ff05a84bd0038ce69801be9 Mon Sep 17 00:00:00 2001 From: Jason Chen CJ Date: Tue, 20 Mar 2018 00:27:50 +0800 Subject: [PATCH] uefi: remove old interrupt injection method we added uefi stub for hv, and want vm0 continue running under uefi env to boot other uefi payload (osloader or bzImage). during this, the uefi timer irq need be handled elegantly. there are 3 types for uefi timer: 1. 8254 based on IRQ0 of PIC 2. HPET based on IOAPIC 3. HPET based on MSI currently, we only support type 3 (HPET+MSI). But we are following a in-correct flow to handle this timer interrupt: - we set VMX_ENTRY_INT_INFO_FIELD directly if a timer interrupt happened before vcpu launching, this will make its vlapic mess up, which finally cause hpet timer stop. this patch remove this in-correct approach, the new approach patch will be followed by next patch. Signed-off-by: Jason Chen CJ --- arch/x86/interrupt.c | 7 ++++--- arch/x86/irq.c | 13 ++++++------- arch/x86/vmx.c | 15 ++++----------- bsp/uefi/uefi.c | 25 ++----------------------- include/arch/x86/irq.h | 4 ++-- 5 files changed, 18 insertions(+), 46 deletions(-) diff --git a/arch/x86/interrupt.c b/arch/x86/interrupt.c index 9952a3df1..8edead074 100644 --- a/arch/x86/interrupt.c +++ b/arch/x86/interrupt.c @@ -270,9 +270,10 @@ int external_interrupt_handler(struct vcpu *vcpu) struct intr_ctx ctx; ctx.vector = vector; - /* do not RETAIN RIP for spurious interrupt */ - if (dispatch_interrupt(&ctx) == 0) - VCPU_RETAIN_RIP(vcpu); + + dispatch_interrupt(&ctx); + + VCPU_RETAIN_RIP(vcpu); TRACE_2L(TRC_VMEXIT_EXTERNAL_INTERRUPT, vector, 0); diff --git a/arch/x86/irq.c b/arch/x86/irq.c index d709c4dfd..0363e7534 100644 --- a/arch/x86/irq.c +++ b/arch/x86/irq.c @@ -443,7 +443,7 @@ void dispatch_exception(struct intr_ctx *ctx) cpu_halt(cpu_id); } -int handle_spurious_interrupt(int vector) +void handle_spurious_interrupt(int vector) { send_lapic_eoi(); @@ -452,13 +452,11 @@ int handle_spurious_interrupt(int vector) pr_warn("Spurious vector: 0x%x.", vector); if (spurious_handler) - return spurious_handler(vector); - else - return 0; + spurious_handler(vector); } /* do_IRQ() */ -int dispatch_interrupt(struct intr_ctx *ctx) +void dispatch_interrupt(struct intr_ctx *ctx) { int vr = ctx->vector; int irq = vector_to_irq[vr]; @@ -479,9 +477,10 @@ int dispatch_interrupt(struct intr_ctx *ctx) } desc->irq_handler(desc, desc->handler_data); - return 0; + return; ERR: - return handle_spurious_interrupt(vr); + handle_spurious_interrupt(vr); + return; } int handle_level_interrupt_common(struct irq_desc *desc, diff --git a/arch/x86/vmx.c b/arch/x86/vmx.c index 75af69974..91ff349fd 100644 --- a/arch/x86/vmx.c +++ b/arch/x86/vmx.c @@ -36,7 +36,6 @@ #ifdef CONFIG_EFI_STUB #include extern struct efi_ctx* efi_ctx; -extern int efi_launch_vector; #endif #define PAT_POWER_ON_VALUE (PAT_MEM_TYPE_WB + \ @@ -1282,16 +1281,10 @@ static void override_uefi_vmcs(struct vcpu *vcpu) } /* Interrupt */ - if (efi_launch_vector > 0) { - field = VMX_GUEST_RFLAGS; - cur_context->rflags = 0x2; - cur_context->rflags |= 1 << 9; /* enable intr for efi stub */ - exec_vmwrite(field, cur_context->rflags); - exec_vmwrite(VMX_ENTRY_INT_INFO_FIELD, - VMX_INT_INFO_VALID | - (efi_launch_vector & 0xFF)); - efi_launch_vector = -1; - } + field = VMX_GUEST_RFLAGS; + cur_context->rflags = 0x2; + cur_context->rflags |= 1 << 9; /* enable intr for efi stub */ + exec_vmwrite(field, cur_context->rflags); } #endif diff --git a/bsp/uefi/uefi.c b/bsp/uefi/uefi.c index 52e25318c..44aa9a18c 100644 --- a/bsp/uefi/uefi.c +++ b/bsp/uefi/uefi.c @@ -56,32 +56,12 @@ uint32_t efi_physical_available_ap_bitmap = 0; uint32_t efi_wake_up_ap_bitmap = 0; struct efi_ctx* efi_ctx = NULL; -int efi_launch_vector; extern uint32_t up_count; extern unsigned long pcpu_sync; -bool in_efi_boot_svc(void) +void efi_spurious_handler(int vector) { - return (efi_wake_up_ap_bitmap != efi_physical_available_ap_bitmap); -} - -int efi_spurious_handler(int vector) -{ - struct vcpu* vcpu; - - if (get_cpu_id() != 0) - return 0; - - vcpu = per_cpu(vcpu, 0); - if (vcpu && vcpu->launched) { - int ret = vlapic_set_intr(vcpu, vector, 0); - if (ret && in_efi_boot_svc()) - exec_vmwrite(VMX_ENTRY_INT_INFO_FIELD, - VMX_INT_INFO_VALID | vector); - } else - efi_launch_vector = vector; - - return 1; + return; } int sipi_from_efi_boot_service_exit(uint32_t dest, uint32_t mode, uint32_t vec) @@ -155,6 +135,5 @@ void init_bsp(void) vm_sw_loader = uefi_sw_loader; spurious_handler = efi_spurious_handler; - efi_launch_vector = -1; #endif } diff --git a/include/arch/x86/irq.h b/include/arch/x86/irq.h index d0172c166..fdd2d7faf 100644 --- a/include/arch/x86/irq.h +++ b/include/arch/x86/irq.h @@ -111,7 +111,7 @@ void update_irq_handler(int irq, irq_handler_t func); int init_default_irqs(unsigned int cpu); -int dispatch_interrupt(struct intr_ctx *ctx); +void dispatch_interrupt(struct intr_ctx *ctx); struct dev_handler_node* pri_register_handler(int irq, @@ -133,7 +133,7 @@ int get_cpu_interrupt_info(char *str, int str_max); void setup_notification(void); -typedef int (*spurious_handler_t)(int); +typedef void (*spurious_handler_t)(int); extern spurious_handler_t spurious_handler; /*