From 26627bd1fca3421d20340f790e0d6130fdd57a4f Mon Sep 17 00:00:00 2001 From: Yin Fengwei Date: Sat, 29 Sep 2018 20:58:51 +0800 Subject: [PATCH] hv: add function to set AP entry With reset_vcpu_regs as pre-condition, we only need to set cs_selector and cs_base for AP. We call set_ap_entry in two places: 1. When emulation AP SIPI 2. When sos BSP resume from S3. The BSP is resumed to real mode with entry set to wakeup_vec. We call set_ap_entry API here with entry twisted from wakeup_vec. Tracked-On: #1231 Signed-off-by: Yin Fengwei Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/vcpu.c | 11 +++++++++++ hypervisor/arch/x86/guest/vlapic.c | 4 ++-- hypervisor/arch/x86/guest/vm.c | 10 +++++++--- hypervisor/include/arch/x86/guest/vcpu.h | 1 + 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c index 608e40e0d..cc66bbb8e 100644 --- a/hypervisor/arch/x86/guest/vcpu.c +++ b/hypervisor/arch/x86/guest/vcpu.c @@ -252,6 +252,17 @@ void reset_vcpu_regs(struct vcpu *vcpu) set_vcpu_regs(vcpu, &realmode_init_regs); } +void set_ap_entry(struct vcpu *vcpu, uint64_t entry) +{ + struct ext_context *ectx; + + ectx = &(vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].ext_ctx); + ectx->cs.selector = (uint16_t)((entry >> 4UL) & 0xFFFFU); + ectx->cs.base = ectx->cs.selector << 4UL; + + vcpu_set_rip(vcpu, 0UL); +} + /*********************************************************************** * * @pre vm != NULL && rtn_vcpu_handle != NULL diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index 7c4dcf34e..de8420bd6 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -1207,11 +1207,11 @@ vlapic_icrlo_write_handler(struct acrn_vlapic *vlapic) continue; } - target_vcpu->arch_vcpu.cpu_mode = CPU_MODE_REAL; - target_vcpu->arch_vcpu.sipi_vector = vec; pr_err("Start Secondary VCPU%hu for VM[%d]...", target_vcpu->vcpu_id, target_vcpu->vm->vm_id); + target_vcpu->arch_vcpu.cpu_mode = CPU_MODE_REAL; + set_ap_entry(target_vcpu, vec << 12U); schedule_vcpu(target_vcpu); } else if (mode == APIC_DELMODE_SMI) { pr_info("vlapic: SMI IPI do not support\n"); diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 0527ec8eb..bedf4cfea 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -374,10 +374,14 @@ void resume_vm_from_s3(struct vm *vm, uint32_t wakeup_vec) vm->state = VM_STARTED; reset_vcpu(bsp); - bsp->entry_addr = (void *)(uint64_t)wakeup_vec; - bsp->arch_vcpu.cpu_mode = CPU_MODE_REAL; - init_vmcs(bsp); + /* When SOS resume from S3, it will return to real mode + * with entry set to wakeup_vec. + */ + bsp->arch_vcpu.cpu_mode = CPU_MODE_REAL; + set_ap_entry(bsp, wakeup_vec); + + init_vmcs(bsp); schedule_vcpu(bsp); } diff --git a/hypervisor/include/arch/x86/guest/vcpu.h b/hypervisor/include/arch/x86/guest/vcpu.h index 4f4271d52..1c4d3e1bd 100644 --- a/hypervisor/include/arch/x86/guest/vcpu.h +++ b/hypervisor/include/arch/x86/guest/vcpu.h @@ -287,6 +287,7 @@ uint64_t vcpu_get_pat_ext(struct vcpu *vcpu); void vcpu_set_pat_ext(struct vcpu *vcpu, uint64_t val); void set_vcpu_regs(struct vcpu *vcpu, struct acrn_vcpu_regs *vcpu_regs); void reset_vcpu_regs(struct vcpu *vcpu); +void set_ap_entry(struct vcpu *vcpu, uint64_t entry); static inline bool is_long_mode(struct vcpu *vcpu) {