hv: reset vcpu events in reset_vcpu

On UEFI UP2 board, APs might execute HLT before SOS kernel INIT them.
After SOS kernel take over and will re-init the APs directly. The flows
from HV perspective is like:
    HLT trap:
       wait_event(VCPU_EVENT_VIRTUAL_INTERRUPT) -> sleep_thread
    SOS kernel INIT, SIPI APs:
       pause_vcpu(ZOMBIE) -> sleep_thread
    -> reset_vcpu
    -> launch_vcpu -> wake_vcpu

However, the last wake_vcpu will fail because the cpu event
VCPU_EVENT_VIRTUAL_INTERRUPT had not got signaled.

This patch will reset all vcpu events in reset_vcpu. If the thread was
previously waiting for a event, its waiting status will be cleared and
launch_vcpu will wake it to running.

Tracked-On: #4402
Signed-off-by: Shuo A Liu <shuo.a.liu@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Shuo A Liu 2020-02-14 00:05:51 +08:00 committed by wenlingz
parent cf3544b4ec
commit 53de3a727c
2 changed files with 6 additions and 2 deletions

View File

@ -220,6 +220,10 @@ static void vcpu_reset_internal(struct acrn_vcpu *vcpu, enum reset_mode mode)
vlapic_reset(vlapic, apicv_ops, mode);
reset_vcpu_regs(vcpu);
for (i = 0; i < VCPU_EVENT_NUM; i++) {
reset_event(&vcpu->events[i]);
}
}
struct acrn_vcpu *get_running_vcpu(uint16_t pcpu_id)

View File

@ -32,8 +32,8 @@ void wait_event(struct sched_event *event)
spinlock_irqsave_obtain(&event->lock, &rflag);
ASSERT((event->waiting_thread == NULL), "only support exclusive waiting");
while (!event->set) {
event->waiting_thread = sched_get_current(get_pcpu_id());
event->waiting_thread = sched_get_current(get_pcpu_id());
while (!event->set && (event->waiting_thread != NULL)) {
sleep_thread(event->waiting_thread);
spinlock_irqrestore_release(&event->lock, rflag);
schedule();