mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-20 12:42:54 +00:00
hv: dispatch asyncio request
For an IO request, hv will check if it was registered in asyncio desc list. If yes, put the corresponding fd to the shared buffer. If the shared buffer is full, yield the vcpu and try again later. Tracked-On: #8209 Signed-off-by: Conghui <conghui.chen@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
4c79354798
commit
17f94605f0
@ -64,6 +64,8 @@ uint32_t sbuf_put(struct shared_buf *sbuf, uint8_t *data)
|
||||
to = (void *)sbuf + SBUF_HEAD_SIZE + sbuf->tail;
|
||||
|
||||
(void)memcpy_s(to, sbuf->ele_size, data, sbuf->ele_size);
|
||||
/* make sure write data before update head */
|
||||
cpu_write_memory_barrier();
|
||||
|
||||
if (trigger_overwrite) {
|
||||
sbuf->head = sbuf_next_ptr(sbuf->head,
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <asm/irq.h>
|
||||
#include <errno.h>
|
||||
#include <logmsg.h>
|
||||
#include <sbuf.h>
|
||||
|
||||
#define DBG_LEVEL_IOREQ 6U
|
||||
|
||||
@ -126,6 +127,73 @@ static inline bool has_complete_ioreq(const struct acrn_vcpu *vcpu)
|
||||
return (get_io_req_state(vcpu->vm, vcpu->vcpu_id) == ACRN_IOREQ_STATE_COMPLETE);
|
||||
}
|
||||
|
||||
static struct asyncio_desc *get_asyncio_desc(struct acrn_vcpu *vcpu, const struct io_request *io_req)
|
||||
{
|
||||
uint64_t addr = 0UL;
|
||||
uint32_t type;
|
||||
struct list_head *pos;
|
||||
struct asyncio_desc *iter_desc;
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
struct asyncio_desc *ret = NULL;
|
||||
struct shared_buf *sbuf =
|
||||
(struct shared_buf *)vm->sw.asyncio_sbuf;
|
||||
|
||||
if (sbuf != NULL) {
|
||||
switch (io_req->io_type) {
|
||||
case ACRN_IOREQ_TYPE_PORTIO:
|
||||
addr = io_req->reqs.pio_request.address;
|
||||
type = ACRN_ASYNCIO_PIO;
|
||||
break;
|
||||
|
||||
case ACRN_IOREQ_TYPE_MMIO:
|
||||
addr = io_req->reqs.mmio_request.address;
|
||||
type = ACRN_ASYNCIO_MMIO;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (addr != 0UL) {
|
||||
spinlock_obtain(&vm->asyncio_lock);
|
||||
list_for_each(pos, &vm->aiodesc_queue) {
|
||||
iter_desc = container_of(pos, struct asyncio_desc, list);
|
||||
if ((iter_desc->addr == addr) && (iter_desc->type == type)) {
|
||||
ret = iter_desc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spinlock_release(&vm->asyncio_lock);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
static int acrn_insert_asyncio(struct acrn_vcpu *vcpu, const uint64_t asyncio_fd)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
struct shared_buf *sbuf =
|
||||
(struct shared_buf *)vm->sw.asyncio_sbuf;
|
||||
int ret = -ENODEV;
|
||||
|
||||
if (sbuf != NULL) {
|
||||
spinlock_obtain(&vm->asyncio_lock);
|
||||
while (sbuf_put(sbuf, (uint8_t *)&asyncio_fd) == 0U) {
|
||||
/* sbuf is full, try later.. */
|
||||
spinlock_release(&vm->asyncio_lock);
|
||||
asm_pause();
|
||||
if (need_reschedule(pcpuid_from_vcpu(vcpu))) {
|
||||
schedule();
|
||||
}
|
||||
spinlock_obtain(&vm->asyncio_lock);
|
||||
}
|
||||
|
||||
spinlock_release(&vm->asyncio_lock);
|
||||
arch_fire_hsm_interrupt();
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief Deliver \p io_req to Service VM and suspend \p vcpu till its completion
|
||||
*
|
||||
@ -615,6 +683,7 @@ emulate_io(struct acrn_vcpu *vcpu, struct io_request *io_req)
|
||||
{
|
||||
int32_t status;
|
||||
struct acrn_vm_config *vm_config;
|
||||
struct asyncio_desc *aio_desc;
|
||||
|
||||
vm_config = get_vm_config(vcpu->vm->vm_id);
|
||||
|
||||
@ -644,10 +713,16 @@ emulate_io(struct acrn_vcpu *vcpu, struct io_request *io_req)
|
||||
*
|
||||
* ACRN insert request to HSM and inject upcall.
|
||||
*/
|
||||
status = acrn_insert_request(vcpu, io_req);
|
||||
if (status == 0) {
|
||||
dm_emulate_io_complete(vcpu);
|
||||
aio_desc = get_asyncio_desc(vcpu, io_req);
|
||||
if (aio_desc) {
|
||||
status = acrn_insert_asyncio(vcpu, aio_desc->fd);
|
||||
} else {
|
||||
status = acrn_insert_request(vcpu, io_req);
|
||||
if (status == 0) {
|
||||
dm_emulate_io_complete(vcpu);
|
||||
}
|
||||
}
|
||||
if (status != 0) {
|
||||
/* here for both IO & MMIO, the direction, address,
|
||||
* size definition is same
|
||||
*/
|
||||
|
@ -725,6 +725,9 @@ struct acrn_vdev {
|
||||
uint8_t args[128];
|
||||
};
|
||||
|
||||
#define ACRN_ASYNCIO_PIO (0x01U)
|
||||
#define ACRN_ASYNCIO_MMIO (0x02U)
|
||||
|
||||
#define SBUF_MAGIC 0x5aa57aa71aa13aa3UL
|
||||
#define SBUF_MAX_SIZE (1UL << 22U)
|
||||
#define SBUF_HEAD_SIZE 64U
|
||||
|
Loading…
Reference in New Issue
Block a user