From: Jan Kiszka <jan.kis...@siemens.com>

This particularly ensures that Linux guests do not consider CPUs dead
because of the potential high latency between submitting INIT and
getting the target CPU into wait_for_sipi state. On real hardware, the
Delivery Status bit which is polled by Linux synchronizes the sender.
Emulating this would be way more complex than making the INIT IPI
submission synchronous. Delaying this is fine because kicking off
secondary CPUs should never be a hot path.

In case of cross-posting between cores or when there is a management
request pending, we have to check for events and process them while
waiting for INIT to arrive.

The issue manifested in failing to online CPUs again under the root cell
Linux on an Intel NUC6CAY (Apollo Lake Atom).

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>
---

Changes in v2:
 - check events while waiting

 hypervisor/arch/x86/control.c            | 13 +++++++++++++
 hypervisor/arch/x86/include/asm/percpu.h |  2 +-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/hypervisor/arch/x86/control.c b/hypervisor/arch/x86/control.c
index 681fc991..7f171838 100644
--- a/hypervisor/arch/x86/control.c
+++ b/hypervisor/arch/x86/control.c
@@ -194,6 +194,19 @@ void x86_send_init_sipi(unsigned int cpu_id, enum 
x86_init_sipi type,
 
        if (send_nmi)
                apic_send_nmi_ipi(target_data);
+
+       /*
+        * On real hardware, the Delivery Status flag signals that the
+        * INIT request has not yet arrived. But we can't easily associate that
+        * flag on the sender side with the target state. Therefore, emulate
+        * this feedback channel by delaying the requester during submission.
+        */
+       if (type == X86_INIT) {
+               while (target_data->init_signaled) {
+                       x86_check_events();
+                       cpu_relax();
+               }
+       }
 }
 
 /* control_lock has to be held */
diff --git a/hypervisor/arch/x86/include/asm/percpu.h 
b/hypervisor/arch/x86/include/asm/percpu.h
index 5c4cc710..d87a2ba6 100644
--- a/hypervisor/arch/x86/include/asm/percpu.h
+++ b/hypervisor/arch/x86/include/asm/percpu.h
@@ -43,7 +43,7 @@
        /** True if CPU is waiting for SIPI. */                         \
        volatile bool wait_for_sipi;                                    \
        /** Set to true for pending an INIT signal. */                  \
-       bool init_signaled;                                             \
+       volatile bool init_signaled;                                    \
        /** Pending SIPI vector; -1 if none is pending. */              \
        int sipi_vector;                                                \
        /** Set to true for pending cache allocation updates (Intel     \

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jailhouse-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to