mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-21 13:08:42 +00:00
HV: io: add structure and API docs
This patch adds more comments to describe the structures and functions that are public to the other components in the hypervisor. The comments are in doxygen-style for document generation. v2 -> v3: * Reformat the flow in the doc for vhm_io_request. v1 -> v2: * Fix typos and inconsistencies in the comments. * Wrap the text-based diagram in the doc for vhm_request in @verbatim Tracked-On: #1595 Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
a4be10f375
commit
e0fcb70daa
@ -15,6 +15,8 @@ static void complete_ioreq(struct vhm_request *vhm_req)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Post-work for port I/O emulation
|
||||
*
|
||||
* @pre io_req->type == REQ_PORTIO
|
||||
*
|
||||
* @remark This function must be called when \p io_req is completed, after
|
||||
@ -37,6 +39,8 @@ emulate_pio_post(struct vcpu *vcpu, const struct io_request *io_req)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Post-work of VHM requests for port I/O emulation
|
||||
*
|
||||
* @pre vcpu->req.type == REQ_PORTIO
|
||||
*
|
||||
* @remark This function must be called after the VHM request corresponding to
|
||||
@ -62,11 +66,16 @@ void dm_emulate_pio_post(struct vcpu *vcpu)
|
||||
}
|
||||
|
||||
/**
|
||||
* @pre vcpu->req.type == REQ_MMIO
|
||||
* @brief General post-work for MMIO emulation
|
||||
*
|
||||
* @param vcpu The virtual CPU that triggers the MMIO access
|
||||
* @param io_req The I/O request holding the details of the MMIO access
|
||||
*
|
||||
* @pre io_req->type == REQ_MMIO
|
||||
*
|
||||
* @remark This function must be called when \p io_req is completed, after
|
||||
* either a previous call to emulate_io() returning 0 or the corresponding VHM
|
||||
* request having transferred to the COMPLETE state.
|
||||
* request transferring to the COMPLETE state.
|
||||
*/
|
||||
void emulate_mmio_post(const struct vcpu *vcpu, const struct io_request *io_req)
|
||||
{
|
||||
@ -79,6 +88,10 @@ void emulate_mmio_post(const struct vcpu *vcpu, const struct io_request *io_req)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Post-work of VHM requests for MMIO emulation
|
||||
*
|
||||
* @param vcpu The virtual CPU that triggers the MMIO access
|
||||
*
|
||||
* @pre vcpu->req.type == REQ_MMIO
|
||||
*
|
||||
* @remark This function must be called after the VHM request corresponding to
|
||||
@ -114,6 +127,11 @@ static void io_instr_dest_handler(struct io_request *io_req)
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief General post-work for all kinds of VHM requests for I/O emulation
|
||||
*
|
||||
* @param vcpu The virtual CPU that triggers the MMIO access
|
||||
*/
|
||||
void emulate_io_post(struct vcpu *vcpu)
|
||||
{
|
||||
union vhm_request_buffer *req_buf;
|
||||
@ -266,12 +284,18 @@ hv_emulate_mmio(struct vcpu *vcpu, struct io_request *io_req)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Emulate \p io_req for \p vcpu
|
||||
*
|
||||
* Handle an I/O request by either invoking a hypervisor-internal handler or
|
||||
* deliver to VHM.
|
||||
*
|
||||
* @param vcpu The virtual CPU that triggers the MMIO access
|
||||
* @param io_req The I/O request holding the details of the MMIO access
|
||||
*
|
||||
* @return 0 - Successfully emulated by registered handlers.
|
||||
* @return IOREQ_PENDING - The I/O request is delivered to VHM.
|
||||
* @return -EIO - The request spans multiple devices and cannot be emulated.
|
||||
* @return -EINVAL - \p io_req has an invalid type.
|
||||
* @return Negative on other errors during emulation.
|
||||
*/
|
||||
int32_t
|
||||
@ -328,6 +352,11 @@ emulate_io(struct vcpu *vcpu, struct io_request *io_req)
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The handler of VM exits on I/O instructions
|
||||
*
|
||||
* @param vcpu The virtual CPU which triggers the VM exit on I/O instruction
|
||||
*/
|
||||
int32_t pio_instr_vmexit_handler(struct vcpu *vcpu)
|
||||
{
|
||||
int32_t status;
|
||||
@ -387,11 +416,26 @@ static void empty_io_handler_list(struct vm *vm)
|
||||
vm->arch_vm.io_handler = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free I/O bitmaps and port I/O handlers of \p vm
|
||||
*
|
||||
* @param vm The VM whose I/O bitmaps and handlers are to be freed
|
||||
*/
|
||||
void free_io_emulation_resource(struct vm *vm)
|
||||
{
|
||||
empty_io_handler_list(vm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allow a VM to access a port I/O range
|
||||
*
|
||||
* This API enables direct access from the given \p vm to the port I/O space
|
||||
* starting from \p port_address to \p port_address + \p nbytes - 1.
|
||||
*
|
||||
* @param vm The VM whose port I/O access permissions is to be changed
|
||||
* @param port_address The start address of the port I/O range
|
||||
* @param nbytes The size of the range, in bytes
|
||||
*/
|
||||
void allow_guest_pio_access(struct vm *vm, uint16_t port_address,
|
||||
uint32_t nbytes)
|
||||
{
|
||||
@ -441,6 +485,11 @@ static struct vm_io_handler *create_io_handler(uint32_t port, uint32_t len,
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the I/O bitmap for \p vm
|
||||
*
|
||||
* @param vm The VM whose I/O bitmap is to be initialized
|
||||
*/
|
||||
void setup_io_bitmap(struct vm *vm)
|
||||
{
|
||||
if (is_vm0(vm)) {
|
||||
@ -451,6 +500,14 @@ void setup_io_bitmap(struct vm *vm)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a port I/O handler
|
||||
*
|
||||
* @param vm The VM to which the port I/O handlers are registered
|
||||
* @param range The port I/O range that the given handlers can emulate
|
||||
* @param io_read_fn_ptr The handler for emulating reads from the given range
|
||||
* @param io_write_fn_ptr The handler for emulating writes to the given range
|
||||
*/
|
||||
void register_io_emulation_handler(struct vm *vm, const struct vm_io_range *range,
|
||||
io_read_fn_t io_read_fn_ptr,
|
||||
io_write_fn_t io_write_fn_ptr)
|
||||
@ -472,6 +529,20 @@ void register_io_emulation_handler(struct vm *vm, const struct vm_io_range *rang
|
||||
register_io_handler(vm, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a MMIO handler
|
||||
*
|
||||
* This API registers a MMIO handler to \p vm before it is launched.
|
||||
*
|
||||
* @param vm The VM to which the MMIO handler is registered
|
||||
* @param read_write The handler for emulating accesses to the given range
|
||||
* @param start The base address of the range \p read_write can emulate
|
||||
* @param end The end of the range (exclusive) \p read_write can emulate
|
||||
* @param handler_private_data Handler-specific data which will be passed to \p read_write when called
|
||||
*
|
||||
* @return 0 - Registration succeeds
|
||||
* @return -EINVAL - \p read_write is NULL, \p end is not larger than \p start or \p vm has been launched
|
||||
*/
|
||||
int register_mmio_emulation_handler(struct vm *vm,
|
||||
hv_mem_io_handler_t read_write, uint64_t start,
|
||||
uint64_t end, void *handler_private_data)
|
||||
@ -522,6 +593,13 @@ int register_mmio_emulation_handler(struct vm *vm,
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister a MMIO handler
|
||||
*
|
||||
* @param vm The VM from which MMIO handlers are unregistered
|
||||
* @param start The base address of the range the to-be-unregistered handler is for
|
||||
* @param end The end of the range (exclusive) the to-be-unregistered handler is for
|
||||
*/
|
||||
void unregister_mmio_emulation_handler(struct vm *vm, uint64_t start,
|
||||
uint64_t end)
|
||||
{
|
||||
|
@ -55,11 +55,15 @@ static void acrn_print_request(uint16_t vcpu_id, const struct vhm_request *req)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Deliver \p io_req to SOS and suspend \p vcpu till its completion
|
||||
*
|
||||
* @param vcpu The virtual CPU that triggers the MMIO access
|
||||
* @param io_req The I/O request holding the details of the MMIO access
|
||||
*
|
||||
* @pre vcpu != NULL && io_req != NULL
|
||||
*/
|
||||
int32_t
|
||||
acrn_insert_request_wait(struct vcpu *vcpu, const struct io_request *io_req)
|
||||
int32_t acrn_insert_request_wait(struct vcpu *vcpu, const struct io_request *io_req)
|
||||
{
|
||||
union vhm_request_buffer *req_buf = NULL;
|
||||
struct vhm_request *vhm_req;
|
||||
|
@ -10,24 +10,41 @@
|
||||
#include <types.h>
|
||||
#include <acrn_common.h>
|
||||
|
||||
/**
|
||||
* @brief I/O Emulation
|
||||
*
|
||||
* @defgroup ioemul ACRN I/O Emulation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* The return value of emulate_io() indicating the I/O request is delivered to
|
||||
* VHM but not finished yet. */
|
||||
#define IOREQ_PENDING 1
|
||||
|
||||
/* Internal representation of a I/O request. */
|
||||
/**
|
||||
* @brief Internal representation of a I/O request.
|
||||
*/
|
||||
struct io_request {
|
||||
/** Type of the request (PIO, MMIO, etc). Refer to vhm_request. */
|
||||
/**
|
||||
* @brief Type of the request (PIO, MMIO, etc).
|
||||
*
|
||||
* Refer to vhm_request for detailed description of I/O request types.
|
||||
*/
|
||||
uint32_t type;
|
||||
|
||||
/** Details of this request in the same format as vhm_request. */
|
||||
/**
|
||||
* @brief Details of this request in the same format as vhm_request.
|
||||
*/
|
||||
union vhm_io_request reqs;
|
||||
};
|
||||
|
||||
/* Definition of a IO port range */
|
||||
/**
|
||||
* @brief Definition of a IO port range
|
||||
*/
|
||||
struct vm_io_range {
|
||||
uint16_t base; /* IO port base */
|
||||
uint16_t len; /* IO port range */
|
||||
uint32_t flags; /* IO port attributes */
|
||||
uint16_t base; /**< IO port base */
|
||||
uint16_t len; /**< IO port range */
|
||||
uint32_t flags; /**< IO port attributes */
|
||||
};
|
||||
|
||||
struct vm_io_handler;
|
||||
@ -40,15 +57,23 @@ uint32_t (*io_read_fn_t)(struct vm *vm, uint16_t port, size_t size);
|
||||
typedef
|
||||
void (*io_write_fn_t)(struct vm *vm, uint16_t port, size_t size, uint32_t val);
|
||||
|
||||
/* Describes a single IO handler description entry. */
|
||||
/**
|
||||
* @brief Describes a single IO handler description entry.
|
||||
*/
|
||||
struct vm_io_handler_desc {
|
||||
|
||||
/** The base address of the IO range for this description. */
|
||||
/**
|
||||
* @brief The base address of the IO range for this description.
|
||||
*/
|
||||
uint16_t addr;
|
||||
/** The number of bytes covered by this description. */
|
||||
|
||||
/**
|
||||
* @brief The number of bytes covered by this description.
|
||||
*/
|
||||
size_t len;
|
||||
|
||||
/** A pointer to the "read" function.
|
||||
/**
|
||||
* @brief A pointer to the "read" function.
|
||||
*
|
||||
* The read function is called from the hypervisor whenever
|
||||
* a read access to a range described in "ranges" occur.
|
||||
@ -62,9 +87,10 @@ struct vm_io_handler_desc {
|
||||
*
|
||||
* If the pointer is null, a read of 1's is assumed.
|
||||
*/
|
||||
|
||||
io_read_fn_t io_read;
|
||||
/** A pointer to the "write" function.
|
||||
|
||||
/**
|
||||
* @brief A pointer to the "write" function.
|
||||
*
|
||||
* The write function is called from the hypervisor code
|
||||
* whenever a write access to a range described in "ranges"
|
||||
@ -78,8 +104,7 @@ struct vm_io_handler_desc {
|
||||
* The implementation must write the value to the port.
|
||||
*
|
||||
* If the pointer is null, the write access is ignored.
|
||||
*/
|
||||
|
||||
*/
|
||||
io_write_fn_t io_write;
|
||||
};
|
||||
|
||||
@ -96,38 +121,194 @@ struct vm_io_handler {
|
||||
struct mmio_request;
|
||||
typedef int (*hv_mem_io_handler_t)(struct io_request *io_req, void *handler_private_data);
|
||||
|
||||
/* Structure for MMIO handler node */
|
||||
/**
|
||||
* @brief Structure for MMIO handler node
|
||||
*/
|
||||
struct mem_io_node {
|
||||
/**
|
||||
* @brief A pointer to the handler
|
||||
*
|
||||
* The function for handling MMIO accesses to the specified range.
|
||||
*/
|
||||
hv_mem_io_handler_t read_write;
|
||||
|
||||
/**
|
||||
* @brief Private data used by the handler
|
||||
*
|
||||
* The pointer to any data specified at registration. This pointer is
|
||||
* passed to the handler whenever the handler is called.
|
||||
*/
|
||||
void *handler_private_data;
|
||||
|
||||
/**
|
||||
* @brief The struct to make a bi-directional linked list
|
||||
*/
|
||||
struct list_head list;
|
||||
|
||||
/**
|
||||
* @brief The starting address
|
||||
*
|
||||
* This member is used in pair with \p range_end. See the documentation
|
||||
* of \p range_end for details.
|
||||
*/
|
||||
uint64_t range_start;
|
||||
|
||||
/**
|
||||
* @brief The ending address
|
||||
*
|
||||
* \p range_start (inclusive) and \p range_end (exclusive) together
|
||||
* specify the address range that this handler is expected to
|
||||
* emulate. Note that the bytes to be accessed shall completely fall in
|
||||
* the range before the handler is called to emulate that access, or
|
||||
* more specifically
|
||||
*
|
||||
* \p range_start <= address < address + size <= \p end
|
||||
*
|
||||
* where address and size are the starting address of the MMIO access
|
||||
* and the number of bytes to be accessed, respectively. Otherwise the
|
||||
* behavior is undefined.
|
||||
*/
|
||||
uint64_t range_end;
|
||||
};
|
||||
|
||||
/* External Interfaces */
|
||||
|
||||
/**
|
||||
* @brief The handler of VM exits on I/O instructions
|
||||
*
|
||||
* @param vcpu The virtual CPU which triggers the VM exit on I/O instruction
|
||||
*/
|
||||
int32_t pio_instr_vmexit_handler(struct vcpu *vcpu);
|
||||
|
||||
/**
|
||||
* @brief Initialize the I/O bitmap for \p vm
|
||||
*
|
||||
* @param vm The VM whose I/O bitmaps are to be initialized
|
||||
*/
|
||||
void setup_io_bitmap(struct vm *vm);
|
||||
|
||||
/**
|
||||
* @brief Free I/O bitmaps and port I/O handlers of \p vm
|
||||
*
|
||||
* @param vm The VM whose I/O bitmaps and handlers are to be freed
|
||||
*/
|
||||
void free_io_emulation_resource(struct vm *vm);
|
||||
|
||||
/**
|
||||
* @brief Allow a VM to access a port I/O range
|
||||
*
|
||||
* This API enables direct access from the given \p vm to the port I/O space
|
||||
* starting from \p port_address to \p port_address + \p nbytes - 1.
|
||||
*
|
||||
* @param vm The VM whose port I/O access permissions is to be changed
|
||||
* @param port_address The start address of the port I/O range
|
||||
* @param nbytes The size of the range, in bytes
|
||||
*/
|
||||
void allow_guest_pio_access(struct vm *vm, uint16_t port_address,
|
||||
uint32_t nbytes);
|
||||
|
||||
/**
|
||||
* @brief Register a port I/O handler
|
||||
*
|
||||
* @param vm The VM to which the port I/O handlers are registered
|
||||
* @param range The port I/O range that the given handlers can emulate
|
||||
* @param io_read_fn_ptr The handler for emulating reads from the given range
|
||||
* @param io_write_fn_ptr The handler for emulating writes to the given range
|
||||
*/
|
||||
void register_io_emulation_handler(struct vm *vm, const struct vm_io_range *range,
|
||||
io_read_fn_t io_read_fn_ptr,
|
||||
io_write_fn_t io_write_fn_ptr);
|
||||
|
||||
/**
|
||||
* @brief Register a MMIO handler
|
||||
*
|
||||
* This API registers a MMIO handler to \p vm before it is launched.
|
||||
*
|
||||
* @param vm The VM to which the MMIO handler is registered
|
||||
* @param read_write The handler for emulating accesses to the given range
|
||||
* @param start The base address of the range \p read_write can emulate
|
||||
* @param end The end of the range (exclusive) \p read_write can emulate
|
||||
* @param handler_private_data Handler-specific data which will be passed to \p read_write when called
|
||||
*
|
||||
* @return 0 - Registration succeeds
|
||||
* @return -EINVAL - \p read_write is NULL, \p end is not larger than \p start or \p vm has been launched
|
||||
*/
|
||||
int register_mmio_emulation_handler(struct vm *vm,
|
||||
hv_mem_io_handler_t read_write, uint64_t start,
|
||||
uint64_t end, void *handler_private_data);
|
||||
|
||||
/**
|
||||
* @brief Unregister a MMIO handler
|
||||
*
|
||||
* @param vm The VM from which MMIO handlers are unregistered
|
||||
* @param start The base address of the range the to-be-unregistered handler is for
|
||||
* @param end The end of the range (exclusive) the to-be-unregistered handler is for
|
||||
*/
|
||||
void unregister_mmio_emulation_handler(struct vm *vm, uint64_t start,
|
||||
uint64_t end);
|
||||
|
||||
/**
|
||||
* @brief General post-work for MMIO emulation
|
||||
*
|
||||
* @param vcpu The virtual CPU that triggers the MMIO access
|
||||
* @param io_req The I/O request holding the details of the MMIO access
|
||||
*
|
||||
* @pre io_req->type == REQ_MMIO
|
||||
*
|
||||
* @remark This function must be called when \p io_req is completed, after
|
||||
* either a previous call to emulate_io() returning 0 or the corresponding VHM
|
||||
* request transferring to the COMPLETE state.
|
||||
*/
|
||||
void emulate_mmio_post(const struct vcpu *vcpu, const struct io_request *io_req);
|
||||
|
||||
/**
|
||||
* @brief Post-work of VHM requests for MMIO emulation
|
||||
*
|
||||
* @param vcpu The virtual CPU that triggers the MMIO access
|
||||
*
|
||||
* @pre vcpu->req.type == REQ_MMIO
|
||||
*
|
||||
* @remark This function must be called after the VHM request corresponding to
|
||||
* \p vcpu being transferred to the COMPLETE state.
|
||||
*/
|
||||
void dm_emulate_mmio_post(struct vcpu *vcpu);
|
||||
|
||||
/**
|
||||
* @brief Emulate \p io_req for \p vcpu
|
||||
*
|
||||
* Handle an I/O request by either invoking a hypervisor-internal handler or
|
||||
* deliver to VHM.
|
||||
*
|
||||
* @param vcpu The virtual CPU that triggers the MMIO access
|
||||
* @param io_req The I/O request holding the details of the MMIO access
|
||||
*
|
||||
* @return 0 - Successfully emulated by registered handlers.
|
||||
* @return IOREQ_PENDING - The I/O request is delivered to VHM.
|
||||
* @return -EIO - The request spans multiple devices and cannot be emulated.
|
||||
* @return -EINVAL - \p io_req has an invalid type.
|
||||
* @return Negative on other errors during emulation.
|
||||
*/
|
||||
int32_t emulate_io(struct vcpu *vcpu, struct io_request *io_req);
|
||||
|
||||
/**
|
||||
* @brief General post-work for all kinds of VHM requests for I/O emulation
|
||||
*
|
||||
* @param vcpu The virtual CPU that triggers the MMIO access
|
||||
*/
|
||||
void emulate_io_post(struct vcpu *vcpu);
|
||||
/*
|
||||
|
||||
/**
|
||||
* @brief Deliver \p io_req to SOS and suspend \p vcpu till its completion
|
||||
*
|
||||
* @param vcpu The virtual CPU that triggers the MMIO access
|
||||
* @param io_req The I/O request holding the details of the MMIO access
|
||||
*
|
||||
* @pre vcpu != NULL && io_req != NULL
|
||||
*/
|
||||
int32_t acrn_insert_request_wait(struct vcpu *vcpu, const struct io_request *io_req);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* IOREQ_H */
|
||||
|
@ -56,30 +56,114 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Representation of a MMIO request
|
||||
*/
|
||||
struct mmio_request {
|
||||
/**
|
||||
* @brief Direction of the access
|
||||
*
|
||||
* Either \p REQUEST_READ or \p REQUEST_WRITE.
|
||||
*/
|
||||
uint32_t direction;
|
||||
|
||||
/**
|
||||
* @brief reserved
|
||||
*/
|
||||
uint32_t reserved;
|
||||
|
||||
/**
|
||||
* @brief Address of the I/O access
|
||||
*/
|
||||
uint64_t address;
|
||||
|
||||
/**
|
||||
* @brief Width of the I/O access in byte
|
||||
*/
|
||||
uint64_t size;
|
||||
|
||||
/**
|
||||
* @brief The value read for I/O reads or to be written for I/O writes
|
||||
*/
|
||||
uint64_t value;
|
||||
} __aligned(8);
|
||||
|
||||
/**
|
||||
* @brief Representation of a port I/O request
|
||||
*/
|
||||
struct pio_request {
|
||||
/**
|
||||
* @brief Direction of the access
|
||||
*
|
||||
* Either \p REQUEST_READ or \p REQUEST_WRITE.
|
||||
*/
|
||||
uint32_t direction;
|
||||
|
||||
/**
|
||||
* @brief reserved
|
||||
*/
|
||||
uint32_t reserved;
|
||||
|
||||
/**
|
||||
* @brief Port address of the I/O access
|
||||
*/
|
||||
uint64_t address;
|
||||
|
||||
/**
|
||||
* @brief Width of the I/O access in byte
|
||||
*/
|
||||
uint64_t size;
|
||||
|
||||
/**
|
||||
* @brief The value read for I/O reads or to be written for I/O writes
|
||||
*/
|
||||
uint32_t value;
|
||||
} __aligned(8);
|
||||
|
||||
/**
|
||||
* @brief Representation of a PCI configuration space access
|
||||
*/
|
||||
struct pci_request {
|
||||
/**
|
||||
* @brief Direction of the access
|
||||
*
|
||||
* Either \p REQUEST_READ or \p REQUEST_WRITE.
|
||||
*/
|
||||
uint32_t direction;
|
||||
|
||||
/**
|
||||
* @brief Reserved
|
||||
*/
|
||||
uint32_t reserved[3];/* need keep same header fields with pio_request */
|
||||
|
||||
/**
|
||||
* @brief Width of the I/O access in byte
|
||||
*/
|
||||
int64_t size;
|
||||
|
||||
/**
|
||||
* @brief The value read for I/O reads or to be written for I/O writes
|
||||
*/
|
||||
int32_t value;
|
||||
|
||||
/**
|
||||
* @brief The \p bus part of the BDF of the device
|
||||
*/
|
||||
int32_t bus;
|
||||
|
||||
/**
|
||||
* @brief The \p device part of the BDF of the device
|
||||
*/
|
||||
int32_t dev;
|
||||
|
||||
/**
|
||||
* @brief The \p function part of the BDF of the device
|
||||
*/
|
||||
int32_t func;
|
||||
|
||||
/**
|
||||
* @brief The register to be accessed in the configuration space
|
||||
*/
|
||||
int32_t reg;
|
||||
} __aligned(8);
|
||||
|
||||
@ -107,33 +191,56 @@ union vhm_io_request {
|
||||
* Based on the rules above, a typical VHM request lifecycle should looks like
|
||||
* the following.
|
||||
*
|
||||
* (assume the initial state is FREE)
|
||||
* @verbatim embed:rst:leading-asterisk
|
||||
*
|
||||
* SOS vCPU 0 SOS vCPU x UOS vCPU y
|
||||
* +-----------------------+-------------------------+----------------------+
|
||||
* | SOS vCPU 0 | SOS vCPU x | UOS vCPU y |
|
||||
* +=======================+=========================+======================+
|
||||
* | | | **Hypervisor**: |
|
||||
* | | | |
|
||||
* | | | - Fill in type, |
|
||||
* | | | addr, etc. |
|
||||
* | | | - Pause UOS vCPU y |
|
||||
* | | | - Set state to |
|
||||
* | | | PENDING **(a)** |
|
||||
* | | | - Fire upcall to |
|
||||
* | | | SOS vCPU 0 |
|
||||
* | | | |
|
||||
* +-----------------------+-------------------------+----------------------+
|
||||
* | **VHM**: | | |
|
||||
* | | | |
|
||||
* | - Scan for pending | | |
|
||||
* | requests | | |
|
||||
* | - Set state to | | |
|
||||
* | PROCESSING **(b)** | | |
|
||||
* | - Assign requests to | | |
|
||||
* | clients **(c)** | | |
|
||||
* | | | |
|
||||
* +-----------------------+-------------------------+----------------------+
|
||||
* | | **Client**: | |
|
||||
* | | | |
|
||||
* | | - Scan for assigned | |
|
||||
* | | requests | |
|
||||
* | | - Handle the | |
|
||||
* | | requests **(d)** | |
|
||||
* | | - Set state to COMPLETE | |
|
||||
* | | - Notify the hypervisor | |
|
||||
* | | | |
|
||||
* +-----------------------+-------------------------+----------------------+
|
||||
* | | **Hypervisor**: | |
|
||||
* | | | |
|
||||
* | | - resume UOS vCPU y | |
|
||||
* | | **(e)** | |
|
||||
* | | | |
|
||||
* +-----------------------+-------------------------+----------------------+
|
||||
* | | | **Hypervisor**: |
|
||||
* | | | |
|
||||
* | | | - Post-work **(f)** |
|
||||
* | | | - set state to FREE |
|
||||
* | | | |
|
||||
* +-----------------------+-------------------------+----------------------+
|
||||
*
|
||||
* hypervisor:
|
||||
* fill in type, addr, etc.
|
||||
* pause UOS vcpu y
|
||||
* set state to PENDING (a)
|
||||
* fire upcall to SOS vCPU 0
|
||||
*
|
||||
* VHM:
|
||||
* scan for pending requests
|
||||
* set state to PROCESSING (b)
|
||||
* assign requests to clients (c)
|
||||
*
|
||||
* client:
|
||||
* scan for assigned requests
|
||||
* handle the requests (d)
|
||||
* set state to COMPLETE
|
||||
* notify the hypervisor
|
||||
*
|
||||
* hypervisor:
|
||||
* resume UOS vcpu y (e)
|
||||
*
|
||||
* hypervisor:
|
||||
* post-work (f)
|
||||
* set state to FREE
|
||||
* @endverbatim
|
||||
*
|
||||
* Note that the following shall hold.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user