mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-24 02:08:04 +00:00
HV: io: refine state transitions of VHM requests
Instead of using two members for maintaining the state of a VHM request, this patch replaces the transitions with a single state. Basically the lifecycle of a VHM request shall be: FREE -> PENDING -> PROCESSING -> COMPLETE -> FREE -> ... The structure header of vhm_request has more details of the transitions access limitations under different states. Also drop the set but unused member vcpu.ioreq_pending. For backward-compatibility, the obsolete 'valid' member is still kept and maintained before SOS and DM adapts to the new state transitions. v2 -> v3: * Use complete_ioreq to mark an I/O request finished in dm_emulate_(pio|mmio)_post. Signed-off-by: Junjie Mao <junjie.mao@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
@@ -334,6 +334,8 @@ int32_t hcall_set_ioreq_buffer(struct vm *vm, uint16_t vmid, uint64_t param)
|
||||
uint64_t hpa = 0UL;
|
||||
struct acrn_set_ioreq_buffer iobuf;
|
||||
struct vm *target_vm = get_vm_from_vmid(vmid);
|
||||
union vhm_request_buffer *req_buf;
|
||||
uint16_t i;
|
||||
|
||||
if (target_vm == NULL) {
|
||||
return -1;
|
||||
@@ -358,6 +360,11 @@ int32_t hcall_set_ioreq_buffer(struct vm *vm, uint16_t vmid, uint64_t param)
|
||||
|
||||
target_vm->sw.io_shared_page = HPA2HVA(hpa);
|
||||
|
||||
req_buf = target_vm->sw.io_shared_page;
|
||||
for (i = 0U; i < VHM_REQUEST_MAX; i++) {
|
||||
atomic_store32(&req_buf->req_queue[i].processed, REQ_STATE_FREE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -72,12 +72,14 @@ acrn_insert_request_wait(struct vcpu *vcpu, struct io_request *io_req)
|
||||
}
|
||||
|
||||
req_buf = (union vhm_request_buffer *)(vcpu->vm->sw.io_shared_page);
|
||||
|
||||
/* ACRN insert request to VHM and inject upcall */
|
||||
cur = vcpu->vcpu_id;
|
||||
vhm_req = &req_buf->req_queue[cur];
|
||||
|
||||
ASSERT(atomic_load32(&vhm_req->processed) == REQ_STATE_FREE,
|
||||
"VHM request buffer is busy");
|
||||
|
||||
/* ACRN insert request to VHM and inject upcall */
|
||||
vhm_req->type = io_req->type;
|
||||
vhm_req->processed = io_req->processed;
|
||||
(void)memcpy_s(&vhm_req->reqs, sizeof(union vhm_io_request),
|
||||
&io_req->reqs, sizeof(union vhm_io_request));
|
||||
|
||||
@@ -85,15 +87,15 @@ acrn_insert_request_wait(struct vcpu *vcpu, struct io_request *io_req)
|
||||
* TODO: when pause_vcpu changed to switch vcpu out directlly, we
|
||||
* should fix the race issue between req.valid = true and vcpu pause
|
||||
*/
|
||||
atomic_store32(&vcpu->ioreq_pending, 1U);
|
||||
pause_vcpu(vcpu, VCPU_PAUSED);
|
||||
|
||||
/* Must clear the signal before we mark req valid
|
||||
* Once we mark to valid, VHM may process req and signal us
|
||||
/* 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
|
||||
*/
|
||||
vhm_req->valid = 1;
|
||||
atomic_store32(&vhm_req->processed, REQ_STATE_PENDING);
|
||||
|
||||
acrn_print_request(vcpu->vcpu_id, vhm_req);
|
||||
|
||||
@@ -140,7 +142,7 @@ static void _get_req_info_(struct vhm_request *req, int *id, char *type,
|
||||
}
|
||||
|
||||
switch (req->processed) {
|
||||
case REQ_STATE_SUCCESS:
|
||||
case REQ_STATE_COMPLETE:
|
||||
(void)strcpy_s(state, 16U, "SUCCESS");
|
||||
break;
|
||||
case REQ_STATE_PENDING:
|
||||
|
Reference in New Issue
Block a user