diff --git a/hypervisor/arch/x86/io.c b/hypervisor/arch/x86/io.c index 57b91a1ef..0ecef8abf 100644 --- a/hypervisor/arch/x86/io.c +++ b/hypervisor/arch/x86/io.c @@ -107,6 +107,68 @@ int32_t dm_emulate_mmio_post(struct vcpu *vcpu) return emulate_mmio_post(vcpu, io_req); } +static void complete_ioreq(struct vcpu *vcpu) +{ + union vhm_request_buffer *req_buf; + struct vhm_request *vhm_req; + + req_buf = (union vhm_request_buffer *) + vcpu->vm->sw.io_shared_page; + vhm_req = &req_buf->req_queue[vcpu->vcpu_id]; + + vhm_req->valid = 0; + atomic_store32(&vcpu->ioreq_pending, 0U); +} + +void emulate_io_post(struct vcpu *vcpu) +{ + union vhm_request_buffer *req_buf; + struct vhm_request *vhm_req; + + req_buf = (union vhm_request_buffer *)vcpu->vm->sw.io_shared_page; + vhm_req = &req_buf->req_queue[vcpu->vcpu_id]; + + if ((vhm_req->valid == 0) || + ((vhm_req->processed != REQ_STATE_SUCCESS) && + (vhm_req->processed != REQ_STATE_FAILED))) { + return; + } + + /* + * If vcpu is in Zombie state and will be destroyed soon. Just + * mark ioreq done and don't resume vcpu. + */ + if (vcpu->state == VCPU_ZOMBIE) { + complete_ioreq(vcpu); + return; + } + + switch (vcpu->req.type) { + case REQ_MMIO: + request_vcpu_pre_work(vcpu, ACRN_VCPU_MMIO_COMPLETE); + break; + + case REQ_PORTIO: + case REQ_PCICFG: + /* REQ_PORTIO on 0xcf8 & 0xcfc may switch to REQ_PCICFG in some + * cases. It works to apply the post-work for REQ_PORTIO on + * REQ_PCICFG because the format of the first 28 bytes of + * REQ_PORTIO & REQ_PCICFG requests are exactly the same and + * post-work is mainly interested in the read value. + */ + dm_emulate_pio_post(vcpu); + break; + + default: + /* REQ_WP can only be triggered on writes which do not need + * post-work. Just mark the ioreq done. */ + complete_ioreq(vcpu); + break; + } + + resume_vcpu(vcpu); +} + /** * Try handling the given request by any port I/O handler registered in the * hypervisor. diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 6d38187a4..21f784aff 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -361,60 +361,8 @@ int32_t hcall_set_ioreq_buffer(struct vm *vm, uint16_t vmid, uint64_t param) return ret; } -static void complete_ioreq(struct vcpu *vcpu) -{ - union vhm_request_buffer *req_buf; - struct vhm_request *vhm_req; - - req_buf = (union vhm_request_buffer *) - vcpu->vm->sw.io_shared_page; - vhm_req = &req_buf->req_queue[vcpu->vcpu_id]; - - vhm_req->valid = 0; - atomic_store32(&vcpu->ioreq_pending, 0U); -} - -static void emulate_io_post(struct vcpu *vcpu) -{ - /* - * If vcpu is in Zombie state and will be destroyed soon. Just - * mark ioreq done and don't resume vcpu. - */ - if (vcpu->state == VCPU_ZOMBIE) { - complete_ioreq(vcpu); - return; - } - - switch (vcpu->req.type) { - case REQ_MMIO: - request_vcpu_pre_work(vcpu, ACRN_VCPU_MMIO_COMPLETE); - break; - - case REQ_PORTIO: - case REQ_PCICFG: - /* REQ_PORTIO on 0xcf8 & 0xcfc may switch to REQ_PCICFG in some - * cases. It works to apply the post-work for REQ_PORTIO on - * REQ_PCICFG because the format of the first 28 bytes of - * REQ_PORTIO & REQ_PCICFG requests are exactly the same and - * post-work is mainly interested in the read value. - */ - dm_emulate_pio_post(vcpu); - break; - - default: - /* REQ_WP can only be triggered on writes which do not need - * post-work. Just mark the ioreq done. */ - complete_ioreq(vcpu); - break; - } - - resume_vcpu(vcpu); -} - int32_t hcall_notify_ioreq_finish(uint16_t vmid, uint16_t vcpu_id) { - union vhm_request_buffer *req_buf; - struct vhm_request *req; struct vcpu *vcpu; struct vm *target_vm = get_vm_from_vmid(vmid); @@ -434,14 +382,7 @@ int32_t hcall_notify_ioreq_finish(uint16_t vmid, uint16_t vcpu_id) return -EINVAL; } - req_buf = (union vhm_request_buffer *)target_vm->sw.io_shared_page; - req = req_buf->req_queue + vcpu_id; - - if ((req->valid != 0) && - ((req->processed == REQ_STATE_SUCCESS) || - (req->processed == REQ_STATE_FAILED))) { - emulate_io_post(vcpu); - } + emulate_io_post(vcpu); return 0; } diff --git a/hypervisor/include/arch/x86/ioreq.h b/hypervisor/include/arch/x86/ioreq.h index 97bf0c9ef..8c0dee9ee 100644 --- a/hypervisor/include/arch/x86/ioreq.h +++ b/hypervisor/include/arch/x86/ioreq.h @@ -115,7 +115,6 @@ void allow_guest_io_access(struct vm *vm, uint32_t address_arg, uint32_t nbyte void register_io_emulation_handler(struct vm *vm, struct vm_io_range *range, io_read_fn_t io_read_fn_ptr, io_write_fn_t io_write_fn_ptr); -int dm_emulate_pio_post(struct vcpu *vcpu); int register_mmio_emulation_handler(struct vm *vm, hv_mem_io_handler_t read_write, uint64_t start, @@ -126,6 +125,7 @@ int32_t emulate_mmio_post(struct vcpu *vcpu, struct io_request *io_req); int32_t dm_emulate_mmio_post(struct vcpu *vcpu); int32_t emulate_io(struct vcpu *vcpu, struct io_request *io_req); +void emulate_io_post(struct vcpu *vcpu); int32_t acrn_insert_request_wait(struct vcpu *vcpu, struct io_request *req);