diff --git a/hypervisor/arch/x86/lapic.c b/hypervisor/arch/x86/lapic.c index 8f48186f7..3b92d2715 100644 --- a/hypervisor/arch/x86/lapic.c +++ b/hypervisor/arch/x86/lapic.c @@ -213,22 +213,13 @@ send_startup_ipi(uint16_t dest_pcpu_id, uint64_t cpu_startup_start_address) void send_dest_ipi_mask(uint32_t dest_mask, uint32_t vector) { - union apic_icr icr; uint16_t pcpu_id; uint32_t mask = dest_mask; - icr.value_32.lo_32 = vector | (INTR_LAPIC_ICR_PHYSICAL << 11U); - pcpu_id = ffs64(mask); - while (pcpu_id < MAX_PCPU_NUM) { bitmap32_clear_nolock(pcpu_id, &mask); - if (is_pcpu_active(pcpu_id)) { - icr.value_32.hi_32 = per_cpu(lapic_id, pcpu_id); - msr_write(MSR_IA32_EXT_APIC_ICR, icr.value); - } else { - pr_err("pcpu_id %d not in active!", pcpu_id); - } + send_single_ipi(pcpu_id, vector); pcpu_id = ffs64(mask); } } @@ -238,13 +229,17 @@ void send_single_ipi(uint16_t pcpu_id, uint32_t vector) union apic_icr icr; if (is_pcpu_active(pcpu_id)) { - /* Set the destination field to the target processor. */ - icr.value_32.hi_32 = per_cpu(lapic_id, pcpu_id); + if (get_pcpu_id() == pcpu_id) { + msr_write(MSR_IA32_EXT_APIC_SELF_IPI, vector); + } else { + /* Set the destination field to the target processor. */ + icr.value_32.hi_32 = per_cpu(lapic_id, pcpu_id); - /* Write the vector ID to ICR. */ - icr.value_32.lo_32 = vector | (INTR_LAPIC_ICR_PHYSICAL << 11U); + /* Write the vector ID to ICR. */ + icr.value_32.lo_32 = vector | (INTR_LAPIC_ICR_PHYSICAL << 11U); - msr_write(MSR_IA32_EXT_APIC_ICR, icr.value); + msr_write(MSR_IA32_EXT_APIC_ICR, icr.value); + } } else { pr_err("pcpu_id %d not in active!", pcpu_id); }