diff --git a/hypervisor/arch/x86/guest/instr_emul.c b/hypervisor/arch/x86/guest/instr_emul.c index 4bb49eb2f..509da4573 100644 --- a/hypervisor/arch/x86/guest/instr_emul.c +++ b/hypervisor/arch/x86/guest/instr_emul.c @@ -271,50 +271,75 @@ static void encode_vmcs_seg_desc(enum cpu_reg_name seg, **/ static uint32_t get_vmcs_field(enum cpu_reg_name ident) { + uint32_t ret; + switch (ident) { case CPU_REG_CR0: - return VMX_GUEST_CR0; + ret = VMX_GUEST_CR0; + break; case CPU_REG_CR3: - return VMX_GUEST_CR3; + ret = VMX_GUEST_CR3; + break; case CPU_REG_CR4: - return VMX_GUEST_CR4; + ret = VMX_GUEST_CR4; + break; case CPU_REG_DR7: - return VMX_GUEST_DR7; + ret = VMX_GUEST_DR7; + break; case CPU_REG_RSP: - return VMX_GUEST_RSP; + ret = VMX_GUEST_RSP; + break; case CPU_REG_RIP: - return VMX_GUEST_RIP; + ret = VMX_GUEST_RIP; + break; case CPU_REG_RFLAGS: - return VMX_GUEST_RFLAGS; + ret = VMX_GUEST_RFLAGS; + break; case CPU_REG_ES: - return VMX_GUEST_ES_SEL; + ret = VMX_GUEST_ES_SEL; + break; case CPU_REG_CS: - return VMX_GUEST_CS_SEL; + ret = VMX_GUEST_CS_SEL; + break; case CPU_REG_SS: - return VMX_GUEST_SS_SEL; + ret = VMX_GUEST_SS_SEL; + break; case CPU_REG_DS: - return VMX_GUEST_DS_SEL; + ret = VMX_GUEST_DS_SEL; + break; case CPU_REG_FS: - return VMX_GUEST_FS_SEL; + ret = VMX_GUEST_FS_SEL; + break; case CPU_REG_GS: - return VMX_GUEST_GS_SEL; + ret = VMX_GUEST_GS_SEL; + break; case CPU_REG_TR: - return VMX_GUEST_TR_SEL; + ret = VMX_GUEST_TR_SEL; + break; case CPU_REG_LDTR: - return VMX_GUEST_LDTR_SEL; + ret = VMX_GUEST_LDTR_SEL; + break; case CPU_REG_EFER: - return VMX_GUEST_IA32_EFER_FULL; + ret = VMX_GUEST_IA32_EFER_FULL; + break; case CPU_REG_PDPTE0: - return VMX_GUEST_PDPTE0_FULL; + ret = VMX_GUEST_PDPTE0_FULL; + break; case CPU_REG_PDPTE1: - return VMX_GUEST_PDPTE1_FULL; + ret = VMX_GUEST_PDPTE1_FULL; + break; case CPU_REG_PDPTE2: - return VMX_GUEST_PDPTE2_FULL; + ret = VMX_GUEST_PDPTE2_FULL; + break; case CPU_REG_PDPTE3: - return VMX_GUEST_PDPTE3_FULL; + ret = VMX_GUEST_PDPTE3_FULL; + break; default: /* Never get here */ - return VMX_INVALID_VMCS_FIELD; + ret = VMX_INVALID_VMCS_FIELD; + break; } + + return ret; } /** diff --git a/hypervisor/common/io_request.c b/hypervisor/common/io_request.c index 332ae8dad..0b12824b0 100644 --- a/hypervisor/common/io_request.c +++ b/hypervisor/common/io_request.c @@ -91,73 +91,76 @@ int32_t acrn_insert_request_wait(struct acrn_vcpu *vcpu, const struct io_request union vhm_request_buffer *req_buf = NULL; struct vhm_request *vhm_req; bool is_polling = false; + int32_t ret; uint16_t cur; - if (vcpu->vm->sw.io_shared_page == NULL) { - return -EINVAL; - } + if (vcpu->vm->sw.io_shared_page != NULL) { + ASSERT(get_vhm_req_state(vcpu->vm, vcpu->vcpu_id) == REQ_STATE_FREE, + "VHM request buffer is busy"); - ASSERT(get_vhm_req_state(vcpu->vm, vcpu->vcpu_id) == REQ_STATE_FREE, - "VHM request buffer is busy"); + req_buf = (union vhm_request_buffer *)(vcpu->vm->sw.io_shared_page); + cur = vcpu->vcpu_id; - req_buf = (union vhm_request_buffer *)(vcpu->vm->sw.io_shared_page); - cur = vcpu->vcpu_id; + stac(); + vhm_req = &req_buf->req_queue[cur]; + /* ACRN insert request to VHM and inject upcall */ + vhm_req->type = io_req->type; + (void)memcpy_s(&vhm_req->reqs, sizeof(union vhm_io_request), + &io_req->reqs, sizeof(union vhm_io_request)); + if (vcpu->vm->sw.is_completion_polling) { + vhm_req->completion_polling = 1U; + is_polling = true; + } + clac(); - stac(); - vhm_req = &req_buf->req_queue[cur]; - /* ACRN insert request to VHM and inject upcall */ - vhm_req->type = io_req->type; - (void)memcpy_s(&vhm_req->reqs, sizeof(union vhm_io_request), - &io_req->reqs, sizeof(union vhm_io_request)); - if (vcpu->vm->sw.is_completion_polling) { - vhm_req->completion_polling = 1U; - is_polling = true; - } - clac(); + /* pause vcpu in notification mode , wait for VHM to handle the MMIO request. + * TODO: when pause_vcpu changed to switch vcpu out directlly, we + * should fix the race issue between req.processed update and vcpu pause + */ + if (!is_polling) { + pause_vcpu(vcpu, VCPU_PAUSED); + } - /* pause vcpu in notification mode , wait for VHM to handle the MMIO request. - * TODO: when pause_vcpu changed to switch vcpu out directlly, we - * should fix the race issue between req.processed update and vcpu pause - */ - if (!is_polling) { - pause_vcpu(vcpu, VCPU_PAUSED); - } - - /* Must clear the signal before we mark req as pending - * Once we mark it pending, VHM may process req and signal us - * before we perform upcall. - * because VHM can work in pulling mode without wait for upcall - */ - set_vhm_req_state(vcpu->vm, vcpu->vcpu_id, REQ_STATE_PENDING); + /* Must clear the signal before we mark req as pending + * Once we mark it pending, VHM may process req and signal us + * before we perform upcall. + * because VHM can work in pulling mode without wait for upcall + */ + set_vhm_req_state(vcpu->vm, vcpu->vcpu_id, REQ_STATE_PENDING); #if defined(HV_DEBUG) - stac(); - acrn_print_request(vcpu->vcpu_id, vhm_req); - clac(); + stac(); + acrn_print_request(vcpu->vcpu_id, vhm_req); + clac(); #endif - /* signal VHM */ - fire_vhm_interrupt(); + /* signal VHM */ + fire_vhm_interrupt(); - /* Polling completion of the request in polling mode */ - if (is_polling) { - /* - * Now, we only have one case that will schedule out this vcpu - * from IO completion polling status, it's pause_vcpu to VCPU_ZOMBIE. - * In this case, we cannot come back to polling status again. Currently, - * it's OK as we needn't handle IO completion in zombie status. - */ - while (!need_reschedule(vcpu->pcpu_id)) { - if (has_complete_ioreq(vcpu)) { - /* we have completed ioreq pending */ - emulate_io_post(vcpu); - break; + /* Polling completion of the request in polling mode */ + if (is_polling) { + /* + * Now, we only have one case that will schedule out this vcpu + * from IO completion polling status, it's pause_vcpu to VCPU_ZOMBIE. + * In this case, we cannot come back to polling status again. Currently, + * it's OK as we needn't handle IO completion in zombie status. + */ + while (!need_reschedule(vcpu->pcpu_id)) { + if (has_complete_ioreq(vcpu)) { + /* we have completed ioreq pending */ + emulate_io_post(vcpu); + break; + } + asm_pause(); } - asm_pause(); } + ret = 0; + } else { + ret = -EINVAL; } - return 0; + + return ret; } uint32_t get_vhm_req_state(struct acrn_vm *vm, uint16_t vhm_req_id) diff --git a/hypervisor/common/schedule.c b/hypervisor/common/schedule.c index eac7a7b4c..70b121475 100644 --- a/hypervisor/common/schedule.c +++ b/hypervisor/common/schedule.c @@ -186,7 +186,6 @@ void schedule(void) if (prev == next) { release_schedule_lock(pcpu_id); - return; } else { prepare_switch(prev, next); release_schedule_lock(pcpu_id);