hv: HLT emulation in hypervisor
HLT emulation is import to CPU resource maximum utilization. vcpu doing HLT means it is idle and can give up CPU proactively. Thus, we pause the vcpu thread in HLT emulation and resume it while event happens. When vcpu enter HLT, its vcpu thread will sleep, but the vcpu state is still 'Running'. VM ID PCPU ID VCPU ID VCPU ROLE VCPU STATE ===== ======= ======= ========= ========== 0 0 0 PRIMARY Running 0 1 1 SECONDARY Running Tracked-On: #4329 Signed-off-by: Shuo A Liu <shuo.a.liu@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
a8f6bdd479
commit
4303ccb1a0
|
@ -590,6 +590,7 @@ static void vlapic_accept_intr(struct acrn_vlapic *vlapic, uint32_t vector, bool
|
|||
if ((lapic->svr.v & APIC_SVR_ENABLE) == 0U) {
|
||||
dev_dbg(ACRN_DBG_LAPIC, "vlapic is software disabled, ignoring interrupt %u", vector);
|
||||
} else {
|
||||
signal_event(&vlapic->vcpu->events[VCPU_EVENT_VIRTUAL_INTERRUPT]);
|
||||
vlapic->ops->accept_intr(vlapic, vector, level);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -272,7 +272,7 @@ static void init_exec_ctrl(struct acrn_vcpu *vcpu)
|
|||
value32 = check_vmx_ctrl(MSR_IA32_VMX_PROCBASED_CTLS,
|
||||
VMX_PROCBASED_CTLS_TSC_OFF | VMX_PROCBASED_CTLS_TPR_SHADOW |
|
||||
VMX_PROCBASED_CTLS_IO_BITMAP | VMX_PROCBASED_CTLS_MSR_BITMAP |
|
||||
VMX_PROCBASED_CTLS_SECONDARY);
|
||||
VMX_PROCBASED_CTLS_HLT | VMX_PROCBASED_CTLS_SECONDARY);
|
||||
|
||||
/*Disable VM_EXIT for CR3 access*/
|
||||
value32 &= ~(VMX_PROCBASED_CTLS_CR3_LOAD | VMX_PROCBASED_CTLS_CR3_STORE);
|
||||
|
|
|
@ -31,6 +31,7 @@ static int32_t xsetbv_vmexit_handler(struct acrn_vcpu *vcpu);
|
|||
static int32_t wbinvd_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||
static int32_t undefined_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||
static int32_t pause_vmexit_handler(__unused struct acrn_vcpu *vcpu);
|
||||
static int32_t hlt_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||
|
||||
/* VM Dispatch table for Exit condition handling */
|
||||
static const struct vm_exit_dispatch dispatch_table[NR_VMX_EXIT_REASONS] = {
|
||||
|
@ -59,7 +60,7 @@ static const struct vm_exit_dispatch dispatch_table[NR_VMX_EXIT_REASONS] = {
|
|||
[VMX_EXIT_REASON_GETSEC] = {
|
||||
.handler = unhandled_vmexit_handler},
|
||||
[VMX_EXIT_REASON_HLT] = {
|
||||
.handler = unhandled_vmexit_handler},
|
||||
.handler = hlt_vmexit_handler},
|
||||
[VMX_EXIT_REASON_INVD] = {
|
||||
.handler = unhandled_vmexit_handler},
|
||||
[VMX_EXIT_REASON_INVLPG] = {
|
||||
|
@ -284,6 +285,14 @@ static int32_t pause_vmexit_handler(__unused struct acrn_vcpu *vcpu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t hlt_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
if ((vcpu->arch.pending_req == 0UL) && (!vlapic_has_pending_intr(vcpu))) {
|
||||
wait_event(&vcpu->events[VCPU_EVENT_VIRTUAL_INTERRUPT]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t cpuid_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
uint64_t rax, rbx, rcx, rdx;
|
||||
|
|
|
@ -40,6 +40,7 @@ void vcpu_thread(struct thread_object *obj)
|
|||
continue;
|
||||
}
|
||||
|
||||
reset_event(&vcpu->events[VCPU_EVENT_VIRTUAL_INTERRUPT]);
|
||||
profiling_vmenter_handler(vcpu);
|
||||
|
||||
TRACE_2L(TRACE_VM_ENTER, 0UL, 0UL);
|
||||
|
|
Loading…
Reference in New Issue