/* control_lock has to be held */ static void x86_enter_wait_for_sipi(struct per_cpu *cpu_data) { cpu_data->init_signaled = false; cpu_data->wait_for_sipi = true; apic_clear(); vmx_cpu_park(); }
int x86_handle_events(struct per_cpu *cpu_data) { int sipi_vector = -1; spin_lock(&cpu_data->control_lock); do { if (cpu_data->init_signaled && !cpu_data->suspend_cpu) { x86_enter_wait_for_sipi(cpu_data); sipi_vector = -1; break; } cpu_data->cpu_suspended = true; spin_unlock(&cpu_data->control_lock); while (cpu_data->suspend_cpu) cpu_relax(); if (cpu_data->shutdown_cpu) { apic_clear(); vcpu_exit(cpu_data); asm volatile("1: hlt; jmp 1b"); } spin_lock(&cpu_data->control_lock); cpu_data->cpu_suspended = false; if (cpu_data->sipi_vector >= 0) { if (!cpu_data->failed) { cpu_data->wait_for_sipi = false; sipi_vector = cpu_data->sipi_vector; } cpu_data->sipi_vector = -1; } } while (cpu_data->init_signaled);