We fire off the IPI, but don't wait for the other cpu to pickk up
the function and data before returning.

Fix by making the other cpu ACK the receipt of the IPI (but still
execute the result asynchrously).

Signed-off-by: Avi Kivity <a...@redhat.com>
---
 lib/x86/smp.c |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/lib/x86/smp.c b/lib/x86/smp.c
index 241f755..8da614a 100644
--- a/lib/x86/smp.c
+++ b/lib/x86/smp.c
@@ -7,15 +7,27 @@
 #define IPI_VECTOR 0x20
 
 static struct spinlock ipi_lock;
-static void (*ipi_function)(void *data);
-static void *ipi_data;
+static volatile void (*ipi_function)(void *data);
+static volatile void *ipi_data;
 static volatile int ipi_done;
+static volatile bool ipi_wait;
+static int _cpu_count;
 
 static __attribute__((used)) void ipi()
 {
-    ipi_function(ipi_data);
-    apic_write(APIC_EOI, 0);
-    ipi_done = 1;
+    void (*function)(void *data) = ipi_function;
+    void *data = ipi_data;
+    bool wait = ipi_wait;
+
+    if (!wait) {
+       ipi_done = 1;
+       apic_write(APIC_EOI, 0);
+    }
+    function(data);
+    if (wait) {
+       ipi_done = 1;
+       apic_write(APIC_EOI, 0);
+    }
 }
 
 asm (
@@ -92,13 +104,12 @@ static void __on_cpu(int cpu, void (*function)(void 
*data), void *data,
        ipi_done = 0;
        ipi_function = function;
        ipi_data = data;
+       ipi_wait = wait;
        apic_icr_write(APIC_INT_ASSERT | APIC_DEST_PHYSICAL | APIC_DM_FIXED
                        | IPI_VECTOR,
                        cpu);
-       if (wait) {
-               while (!ipi_done)
-                   ;
-       }
+       while (!ipi_done)
+           ;
     }
     spin_unlock(&ipi_lock);
 }
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to