Skip to content

Commit d817951

Browse files
junjiemao1lijinxia
authored andcommitted
HV: io: add post-work for PCICFG and WP requests
Currently no post-work is done for I/O requests of type PCICFG or WP. The impacts include: 1. ''valid'' in VHM request buffers are left as 1 even after the I/O request completes. This violates the pre-condition of acrn_insert_request_wait() but does not cause failures since a new I/O request can never happen before the previous one completes. 2. Values read from PCI configuration spaces are never passed to UOS. This patch adds the post-work for these two kinds of I/O requests. The post-work for port I/O is invoked for PCICFG since it is essentially a port I/O and the request structure is compatible. No post-work is needed for WP as it is only triggered for EPT violations on writes, while post-work is mainly for reads. v2 -> v3: * Consistently use 0/1 (not false/true) for the ''valid'' member. * Add comments to suggest when the hypervisor can see REQ_PCICFG and why dm_emulate_pio_post also works in such cases. * Rename: mark_ioreq_done -> complete_ioreq * Rename: complete_request -> emulate_io_post * Rename: hcall_notify_req_finish -> hcall_notify_ioreq_finish Signed-off-by: Junjie Mao <junjie.mao@intel.com> Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
1 parent 26ab2c9 commit d817951

File tree

3 files changed

+29
-12
lines changed

3 files changed

+29
-12
lines changed

hypervisor/arch/x86/guest/vmcall.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ int vmcall_vmexit_handler(struct vcpu *vcpu)
103103
case HC_NOTIFY_REQUEST_FINISH:
104104
/* param1: vmid
105105
* param2: vcpu_id */
106-
ret = hcall_notify_req_finish((uint16_t)param1,
106+
ret = hcall_notify_ioreq_finish((uint16_t)param1,
107107
(uint16_t)param2);
108108
break;
109109

hypervisor/common/hypercall.c

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -361,20 +361,27 @@ int32_t hcall_set_ioreq_buffer(struct vm *vm, uint16_t vmid, uint64_t param)
361361
return ret;
362362
}
363363

364-
static void complete_request(struct vcpu *vcpu)
364+
static void complete_ioreq(struct vcpu *vcpu)
365+
{
366+
union vhm_request_buffer *req_buf;
367+
struct vhm_request *vhm_req;
368+
369+
req_buf = (union vhm_request_buffer *)
370+
vcpu->vm->sw.io_shared_page;
371+
vhm_req = &req_buf->req_queue[vcpu->vcpu_id];
372+
373+
vhm_req->valid = 0;
374+
atomic_store32(&vcpu->ioreq_pending, 0U);
375+
}
376+
377+
static void emulate_io_post(struct vcpu *vcpu)
365378
{
366379
/*
367380
* If vcpu is in Zombie state and will be destroyed soon. Just
368381
* mark ioreq done and don't resume vcpu.
369382
*/
370383
if (vcpu->state == VCPU_ZOMBIE) {
371-
union vhm_request_buffer *req_buf;
372-
373-
req_buf = (union vhm_request_buffer *)
374-
vcpu->vm->sw.io_shared_page;
375-
req_buf->req_queue[vcpu->vcpu_id].valid = false;
376-
atomic_store32(&vcpu->ioreq_pending, 0U);
377-
384+
complete_ioreq(vcpu);
378385
return;
379386
}
380387

@@ -384,17 +391,27 @@ static void complete_request(struct vcpu *vcpu)
384391
break;
385392

386393
case REQ_PORTIO:
394+
case REQ_PCICFG:
395+
/* REQ_PORTIO on 0xcf8 & 0xcfc may switch to REQ_PCICFG in some
396+
* cases. It works to apply the post-work for REQ_PORTIO on
397+
* REQ_PCICFG because the format of the first 28 bytes of
398+
* REQ_PORTIO & REQ_PCICFG requests are exactly the same and
399+
* post-work is mainly interested in the read value.
400+
*/
387401
dm_emulate_pio_post(vcpu);
388402
break;
389403

390404
default:
405+
/* REQ_WP can only be triggered on writes which do not need
406+
* post-work. Just mark the ioreq done. */
407+
complete_ioreq(vcpu);
391408
break;
392409
}
393410

394411
resume_vcpu(vcpu);
395412
}
396413

397-
int32_t hcall_notify_req_finish(uint16_t vmid, uint16_t vcpu_id)
414+
int32_t hcall_notify_ioreq_finish(uint16_t vmid, uint16_t vcpu_id)
398415
{
399416
union vhm_request_buffer *req_buf;
400417
struct vhm_request *req;
@@ -423,7 +440,7 @@ int32_t hcall_notify_req_finish(uint16_t vmid, uint16_t vcpu_id)
423440
if ((req->valid != 0) &&
424441
((req->processed == REQ_STATE_SUCCESS) ||
425442
(req->processed == REQ_STATE_FAILED))) {
426-
complete_request(vcpu);
443+
emulate_io_post(vcpu);
427444
}
428445

429446
return 0;

hypervisor/include/common/hypercall.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ int32_t hcall_set_ioreq_buffer(struct vm *vm, uint16_t vmid, uint64_t param);
203203
*
204204
* @return 0 on success, non-zero on error.
205205
*/
206-
int32_t hcall_notify_req_finish(uint16_t vmid, uint16_t vcpu_id);
206+
int32_t hcall_notify_ioreq_finish(uint16_t vmid, uint16_t vcpu_id);
207207

208208
/**
209209
* @brief setup ept memory mapping

0 commit comments

Comments
 (0)