hv: dm: Use new I/O request data structures

struct vhm_request		->	struct acrn_io_request
union vhm_request_buffer	->	struct acrn_io_request_buffer
struct pio_request		->	struct acrn_pio_request
struct mmio_request		->	struct acrn_mmio_request
struct ioreq_notify		->	struct acrn_ioreq_notify

VHM_REQ_PIO_INVAL		->	IOREQ_PIO_INVAL
VHM_REQ_MMIO_INVAL		->	IOREQ_MMIO_INVAL
REQ_PORTIO			->	ACRN_IOREQ_TYPE_PORTIO
REQ_MMIO			->	ACRN_IOREQ_TYPE_MMIO
REQ_PCICFG			->	ACRN_IOREQ_TYPE_PCICFG
REQ_WP				->	ACRN_IOREQ_TYPE_WP

REQUEST_READ			->	ACRN_IOREQ_DIR_READ
REQUEST_WRITE			->	ACRN_IOREQ_DIR_WRITE
REQ_STATE_PROCESSING		->	ACRN_IOREQ_STATE_PROCESSING
REQ_STATE_PENDING		->	ACRN_IOREQ_STATE_PENDING
REQ_STATE_COMPLETE		->	ACRN_IOREQ_STATE_COMPLETE
REQ_STATE_FREE			->	ACRN_IOREQ_STATE_FREE

IC_CREATE_IOREQ_CLIENT		->	ACRN_IOCTL_CREATE_IOREQ_CLIENT
IC_DESTROY_IOREQ_CLIENT		->	ACRN_IOCTL_DESTROY_IOREQ_CLIENT
IC_ATTACH_IOREQ_CLIENT		->	ACRN_IOCTL_ATTACH_IOREQ_CLIENT
IC_NOTIFY_REQUEST_FINISH	->	ACRN_IOCTL_NOTIFY_REQUEST_FINISH
IC_CLEAR_VM_IOREQ		->	ACRN_IOCTL_CLEAR_VM_IOREQ
HYPERVISOR_CALLBACK_VHM_VECTOR	->	HYPERVISOR_CALLBACK_HSM_VECTOR

arch_fire_vhm_interrupt()	->	arch_fire_hsm_interrupt()
get_vhm_notification_vector()	->	get_hsm_notification_vector()
set_vhm_notification_vector()	->	set_hsm_notification_vector()
acrn_vhm_notification_vector	->	acrn_hsm_notification_vector
get_vhm_req_state()		->	get_io_req_state()
set_vhm_req_state()		->	set_io_req_state()

Below structures have slight difference with former ones.

  struct acrn_ioreq_notify
  strcut acrn_io_request

Tracked-On: #6282
Signed-off-by: Shuo A Liu <shuo.a.liu@intel.com>
This commit is contained in:
Shuo A Liu 2021-07-07 15:38:07 +08:00 committed by wenlingz
parent 3c66ba7ef5
commit 9c910bae44
30 changed files with 307 additions and 304 deletions

View File

@ -87,7 +87,7 @@ register_default_iohandler(int start, int size)
}
int
emulate_inout(struct vmctx *ctx, int *pvcpu, struct pio_request *pio_request)
emulate_inout(struct vmctx *ctx, int *pvcpu, struct acrn_pio_request *pio_request)
{
int bytes, flags, in, port;
inout_func_t handler;
@ -95,7 +95,7 @@ emulate_inout(struct vmctx *ctx, int *pvcpu, struct pio_request *pio_request)
int retval;
bytes = pio_request->size;
in = (pio_request->direction == REQUEST_READ);
in = (pio_request->direction == ACRN_IOREQ_DIR_READ);
port = pio_request->address;
if ((port + bytes - 1 >= MAX_IOPORTS) ||
@ -106,7 +106,7 @@ emulate_inout(struct vmctx *ctx, int *pvcpu, struct pio_request *pio_request)
flags = inout_handlers[port].flags;
arg = inout_handlers[port].arg;
if (pio_request->direction == REQUEST_READ) {
if (pio_request->direction == ACRN_IOREQ_DIR_READ) {
if (!(flags & IOPORT_F_IN))
return -1;
} else {

View File

@ -73,11 +73,11 @@
#define GUEST_NIO_PORT 0x488 /* guest upcalls via i/o port */
/* Values returned for reads on invalid I/O requests. */
#define VHM_REQ_PIO_INVAL (~0U)
#define VHM_REQ_MMIO_INVAL (~0UL)
#define IOREQ_PIO_INVAL (~0U)
#define IOREQ_MMIO_INVAL (~0UL)
typedef void (*vmexit_handler_t)(struct vmctx *,
struct vhm_request *, int *vcpu);
struct acrn_io_request *, int *vcpu);
char *vmname;
@ -114,10 +114,10 @@ static cpuset_t cpumask;
static void vm_loop(struct vmctx *ctx);
static char vhm_request_page[4096] __aligned(4096);
static char io_request_page[4096] __aligned(4096);
static struct vhm_request *vhm_req_buf =
(struct vhm_request *)&vhm_request_page;
static struct acrn_io_request *ioreq_buf =
(struct acrn_io_request *)&io_request_page;
struct dmstats {
uint64_t vmexit_bogus;
@ -302,16 +302,16 @@ notify_vmloop_thread(void)
#endif
static void
vmexit_inout(struct vmctx *ctx, struct vhm_request *vhm_req, int *pvcpu)
vmexit_inout(struct vmctx *ctx, struct acrn_io_request *io_req, int *pvcpu)
{
int error;
int bytes, port, in;
port = vhm_req->reqs.pio.address;
bytes = vhm_req->reqs.pio.size;
in = (vhm_req->reqs.pio.direction == REQUEST_READ);
port = io_req->reqs.pio_request.address;
bytes = io_req->reqs.pio_request.size;
in = (io_req->reqs.pio_request.direction == ACRN_IOREQ_DIR_READ);
error = emulate_inout(ctx, pvcpu, &vhm_req->reqs.pio);
error = emulate_inout(ctx, pvcpu, &io_req->reqs.pio_request);
if (error) {
pr_err("Unhandled %s%c 0x%04x\n",
in ? "in" : "out",
@ -319,56 +319,56 @@ vmexit_inout(struct vmctx *ctx, struct vhm_request *vhm_req, int *pvcpu)
port);
if (in) {
vhm_req->reqs.pio.value = VHM_REQ_PIO_INVAL;
io_req->reqs.pio_request.value = IOREQ_PIO_INVAL;
}
}
}
static void
vmexit_mmio_emul(struct vmctx *ctx, struct vhm_request *vhm_req, int *pvcpu)
vmexit_mmio_emul(struct vmctx *ctx, struct acrn_io_request *io_req, int *pvcpu)
{
int err;
stats.vmexit_mmio_emul++;
err = emulate_mem(ctx, &vhm_req->reqs.mmio);
err = emulate_mem(ctx, &io_req->reqs.mmio_request);
if (err) {
if (err == -ESRCH)
pr_err("Unhandled memory access to 0x%lx\n",
vhm_req->reqs.mmio.address);
io_req->reqs.mmio_request.address);
pr_err("Failed to emulate instruction [");
pr_err("mmio address 0x%lx, size %ld",
vhm_req->reqs.mmio.address,
vhm_req->reqs.mmio.size);
io_req->reqs.mmio_request.address,
io_req->reqs.mmio_request.size);
if (vhm_req->reqs.mmio.direction == REQUEST_READ) {
vhm_req->reqs.mmio.value = VHM_REQ_MMIO_INVAL;
if (io_req->reqs.mmio_request.direction == ACRN_IOREQ_DIR_READ) {
io_req->reqs.mmio_request.value = IOREQ_MMIO_INVAL;
}
}
}
static void
vmexit_pci_emul(struct vmctx *ctx, struct vhm_request *vhm_req, int *pvcpu)
vmexit_pci_emul(struct vmctx *ctx, struct acrn_io_request *io_req, int *pvcpu)
{
int err, in = (vhm_req->reqs.pci.direction == REQUEST_READ);
int err, in = (io_req->reqs.pci_request.direction == ACRN_IOREQ_DIR_READ);
err = emulate_pci_cfgrw(ctx, *pvcpu, in,
vhm_req->reqs.pci.bus,
vhm_req->reqs.pci.dev,
vhm_req->reqs.pci.func,
vhm_req->reqs.pci.reg,
vhm_req->reqs.pci.size,
&vhm_req->reqs.pci.value);
io_req->reqs.pci_request.bus,
io_req->reqs.pci_request.dev,
io_req->reqs.pci_request.func,
io_req->reqs.pci_request.reg,
io_req->reqs.pci_request.size,
&io_req->reqs.pci_request.value);
if (err) {
pr_err("Unhandled pci cfg rw at %x:%x.%x reg 0x%x\n",
vhm_req->reqs.pci.bus,
vhm_req->reqs.pci.dev,
vhm_req->reqs.pci.func,
vhm_req->reqs.pci.reg);
io_req->reqs.pci_request.bus,
io_req->reqs.pci_request.dev,
io_req->reqs.pci_request.func,
io_req->reqs.pci_request.reg);
if (in) {
vhm_req->reqs.pio.value = VHM_REQ_PIO_INVAL;
io_req->reqs.pio_request.value = IOREQ_PIO_INVAL;
}
}
}
@ -397,24 +397,24 @@ static vmexit_handler_t handler[VM_EXITCODE_MAX] = {
};
static void
handle_vmexit(struct vmctx *ctx, struct vhm_request *vhm_req, int vcpu)
handle_vmexit(struct vmctx *ctx, struct acrn_io_request *io_req, int vcpu)
{
enum vm_exitcode exitcode;
exitcode = vhm_req->type;
exitcode = io_req->type;
if (exitcode >= VM_EXITCODE_MAX || handler[exitcode] == NULL) {
pr_err("handle vmexit: unexpected exitcode 0x%x\n",
exitcode);
exit(1);
}
(*handler[exitcode])(ctx, vhm_req, &vcpu);
(*handler[exitcode])(ctx, io_req, &vcpu);
/* We cannot notify the VHM/hypervisor on the request completion at this
/* We cannot notify the HSM/hypervisor on the request completion at this
* point if the UOS is in suspend or system reset mode, as the VM is
* still not paused and a notification can kick off the vcpu to run
* again. Postpone the notification till vm_system_reset() or
* vm_suspend_resume() for resetting the ioreq states in the VHM and
* vm_suspend_resume() for resetting the ioreq states in the HSM and
* hypervisor.
*/
if ((VM_SUSPEND_SYSTEM_RESET == vm_get_suspend_mode()) ||
@ -633,10 +633,10 @@ vm_system_reset(struct vmctx *ctx)
* request which is the APIC PM CR write. VM reset will reset it
*
* When handling emergency mode triggered by one vcpu without
* offlining any other vcpus, there can be multiple VHM requests
* offlining any other vcpus, there can be multiple IO requests
* with various states. We should be careful on potential races
* when resetting especially in SMP SOS. vm_clear_ioreq can be used
* to clear all ioreq status in VHM after VM pause, then let VM
* to clear all ioreq status in HSM after VM pause, then let VM
* reset in hypervisor reset all ioreqs.
*/
vm_clear_ioreq(ctx);
@ -698,17 +698,17 @@ vm_loop(struct vmctx *ctx)
while (1) {
int vcpu_id;
struct vhm_request *vhm_req;
struct acrn_io_request *io_req;
error = vm_attach_ioreq_client(ctx);
if (error)
break;
for (vcpu_id = 0; vcpu_id < guest_ncpus; vcpu_id++) {
vhm_req = &vhm_req_buf[vcpu_id];
if ((atomic_load(&vhm_req->processed) == REQ_STATE_PROCESSING)
&& (vhm_req->client == ctx->ioreq_client))
handle_vmexit(ctx, vhm_req, vcpu_id);
io_req = &ioreq_buf[vcpu_id];
if ((atomic_load(&io_req->processed) == ACRN_IOREQ_STATE_PROCESSING)
&& !io_req->kernel_handled)
handle_vmexit(ctx, io_req, vcpu_id);
}
if (VM_SUSPEND_FULL_RESET == vm_get_suspend_mode() ||
@ -1022,7 +1022,7 @@ main(int argc, char *argv[])
for (;;) {
pr_notice("vm_create: %s\n", vmname);
ctx = vm_create(vmname, (unsigned long)vhm_req_buf, &guest_ncpus);
ctx = vm_create(vmname, (unsigned long)ioreq_buf, &guest_ncpus);
if (!ctx) {
pr_err("vm_create failed");
goto create_fail;

View File

@ -150,7 +150,7 @@ mem_write(void *ctx, int vcpu, uint64_t gpa, uint64_t wval, int size, void *arg)
}
int
emulate_mem(struct vmctx *ctx, struct mmio_request *mmio_req)
emulate_mem(struct vmctx *ctx, struct acrn_mmio_request *mmio_req)
{
uint64_t paddr = mmio_req->address;
int size = mmio_req->size;
@ -179,7 +179,7 @@ emulate_mem(struct vmctx *ctx, struct mmio_request *mmio_req)
if (entry == NULL)
return -EINVAL;
if (mmio_req->direction == REQUEST_READ)
if (mmio_req->direction == ACRN_IOREQ_DIR_READ)
err = mem_read(ctx, 0, paddr, (uint64_t *)&mmio_req->value,
size, &entry->mr_param);
else

View File

@ -259,13 +259,13 @@ err:
int
vm_create_ioreq_client(struct vmctx *ctx)
{
return ioctl(ctx->fd, IC_CREATE_IOREQ_CLIENT, 0);
return ioctl(ctx->fd, ACRN_IOCTL_CREATE_IOREQ_CLIENT, 0);
}
int
vm_destroy_ioreq_client(struct vmctx *ctx)
{
return ioctl(ctx->fd, IC_DESTROY_IOREQ_CLIENT, ctx->ioreq_client);
return ioctl(ctx->fd, ACRN_IOCTL_DESTROY_IOREQ_CLIENT, ctx->ioreq_client);
}
int
@ -273,7 +273,7 @@ vm_attach_ioreq_client(struct vmctx *ctx)
{
int error;
error = ioctl(ctx->fd, IC_ATTACH_IOREQ_CLIENT, ctx->ioreq_client);
error = ioctl(ctx->fd, ACRN_IOCTL_ATTACH_IOREQ_CLIENT, ctx->ioreq_client);
if (error) {
pr_err("attach ioreq client return %d "
@ -289,13 +289,13 @@ int
vm_notify_request_done(struct vmctx *ctx, int vcpu)
{
int error;
struct ioreq_notify notify;
struct acrn_ioreq_notify notify;
bzero(&notify, sizeof(notify));
notify.client_id = ctx->ioreq_client;
notify.vmid = ctx->vmid;
notify.vcpu = vcpu;
error = ioctl(ctx->fd, IC_NOTIFY_REQUEST_FINISH, &notify);
error = ioctl(ctx->fd, ACRN_IOCTL_NOTIFY_REQUEST_FINISH, &notify);
if (error) {
pr_err("failed: notify request finish\n");
@ -488,7 +488,7 @@ vm_reset(struct vmctx *ctx)
void
vm_clear_ioreq(struct vmctx *ctx)
{
ioctl(ctx->fd, IC_CLEAR_VM_IOREQ, NULL);
ioctl(ctx->fd, ACRN_IOCTL_CLEAR_VM_IOREQ, NULL);
}
static enum vm_suspend_how suspend_mode = VM_SUSPEND_NONE;

View File

@ -32,7 +32,6 @@
#include "types.h"
#include "acrn_common.h"
struct vmctx;
struct vhm_request;
/*
* inout emulation handlers return 0 on success and -1 on failure.
@ -71,7 +70,7 @@ struct inout_port {
DATA_SET(inout_port_set, __CONCAT(__inout_port, __LINE__))
void init_inout(void);
int emulate_inout(struct vmctx *ctx, int *pvcpu, struct pio_request *req);
int emulate_inout(struct vmctx *ctx, int *pvcpu, struct acrn_pio_request *req);
int register_inout(struct inout_port *iop);
int unregister_inout(struct inout_port *iop);

View File

@ -50,7 +50,7 @@ struct mem_range {
#define MEM_F_RW (MEM_F_READ | MEM_F_WRITE)
#define MEM_F_IMMUTABLE 0x4 /* mem_range cannot be unregistered */
int emulate_mem(struct vmctx *ctx, struct mmio_request *mmio_req);
int emulate_mem(struct vmctx *ctx, struct acrn_mmio_request *mmio_req);
int register_mem(struct mem_range *memp);
int register_mem_fallback(struct mem_range *memp);
int unregister_mem(struct mem_range *memp);

View File

@ -94,13 +94,16 @@
_IOW(ACRN_IOCTL_TYPE, 0x25, __u64)
/* DM ioreq management */
#define IC_ID_IOREQ_BASE 0x30UL
#define IC_SET_IOREQ_BUFFER _IC_ID(IC_ID, IC_ID_IOREQ_BASE + 0x00)
#define IC_NOTIFY_REQUEST_FINISH _IC_ID(IC_ID, IC_ID_IOREQ_BASE + 0x01)
#define IC_CREATE_IOREQ_CLIENT _IC_ID(IC_ID, IC_ID_IOREQ_BASE + 0x02)
#define IC_ATTACH_IOREQ_CLIENT _IC_ID(IC_ID, IC_ID_IOREQ_BASE + 0x03)
#define IC_DESTROY_IOREQ_CLIENT _IC_ID(IC_ID, IC_ID_IOREQ_BASE + 0x04)
#define IC_CLEAR_VM_IOREQ _IC_ID(IC_ID, IC_ID_IOREQ_BASE + 0x05)
#define ACRN_IOCTL_NOTIFY_REQUEST_FINISH \
_IOW(ACRN_IOCTL_TYPE, 0x31, struct acrn_ioreq_notify)
#define ACRN_IOCTL_CREATE_IOREQ_CLIENT \
_IO(ACRN_IOCTL_TYPE, 0x32)
#define ACRN_IOCTL_ATTACH_IOREQ_CLIENT \
_IO(ACRN_IOCTL_TYPE, 0x33)
#define ACRN_IOCTL_DESTROY_IOREQ_CLIENT \
_IO(ACRN_IOCTL_TYPE, 0x34)
#define ACRN_IOCTL_CLEAR_VM_IOREQ \
_IO(ACRN_IOCTL_TYPE, 0x35)
/* Guest memory management */
#define IC_ID_MEM_BASE 0x40UL
@ -286,11 +289,12 @@ struct ic_ptdev_irq {
/**
* @brief data strcture to notify hypervisor ioreq is handled
*/
struct ioreq_notify {
/** client id to identify ioreq client */
int32_t client_id;
struct acrn_ioreq_notify {
/** VM id to identify ioreq client */
__u16 vmid;
__u16 reserved;
/** identify the ioreq submitter */
uint32_t vcpu;
__u32 vcpu;
};
#define ACRN_PLATFORM_LAPIC_IDS_MAX 64

View File

@ -600,7 +600,7 @@ static void vie_calculate_gla(enum vm_cpu_mode cpu_mode, enum cpu_reg_name seg,
*/
static inline void vie_mmio_read(const struct acrn_vcpu *vcpu, uint64_t *rval)
{
*rval = vcpu->req.reqs.mmio.value;
*rval = vcpu->req.reqs.mmio_request.value;
}
/*
@ -608,7 +608,7 @@ static inline void vie_mmio_read(const struct acrn_vcpu *vcpu, uint64_t *rval)
*/
static inline void vie_mmio_write(struct acrn_vcpu *vcpu, uint64_t wval)
{
vcpu->req.reqs.mmio.value = wval;
vcpu->req.reqs.mmio_request.value = wval;
}
static void vie_calc_bytereg(const struct instr_emul_vie *vie,
@ -1087,7 +1087,7 @@ static int32_t emulate_movs(struct acrn_vcpu *vcpu, const struct instr_emul_vie
/* update the Memory Operand byte size if necessary */
opsize = ((vie->op.op_flags & VIE_OP_F_BYTE_OP) != 0U) ? 1U : vie->opsize;
is_mmio_write = (vcpu->req.reqs.mmio.direction == REQUEST_WRITE);
is_mmio_write = (vcpu->req.reqs.mmio_request.direction == ACRN_IOREQ_DIR_WRITE);
/*
* XXX although the MOVS instruction is only supposed to be used with
@ -2325,7 +2325,7 @@ static int32_t instr_check_gva(struct acrn_vcpu *vcpu, enum vm_cpu_mode cpu_mode
}
ret = -EFAULT;
} else {
err_code = (vcpu->req.reqs.mmio.direction == REQUEST_WRITE) ? PAGE_FAULT_WR_FLAG : 0U;
err_code = (vcpu->req.reqs.mmio_request.direction == ACRN_IOREQ_DIR_WRITE) ? PAGE_FAULT_WR_FLAG : 0U;
ret = gva2gpa(vcpu, gva, &gpa, &err_code);
if (ret < 0) {

View File

@ -143,7 +143,7 @@ static inline uint8_t get_slp_typx(uint32_t pm1_cnt)
static bool pm1ab_io_read(struct acrn_vcpu *vcpu, uint16_t addr, size_t width)
{
struct pio_request *pio_req = &vcpu->req.reqs.pio;
struct acrn_pio_request *pio_req = &vcpu->req.reqs.pio_request;
pio_req->value = pio_read(addr, width);
@ -314,7 +314,7 @@ static void register_rt_vm_pm1a_ctl_handler(struct acrn_vm *vm)
*/
static bool prelaunched_vm_sleep_io_read(struct acrn_vcpu *vcpu, __unused uint16_t addr, __unused size_t width)
{
vcpu->req.reqs.pio.value = 0U;
vcpu->req.reqs.pio_request.value = 0U;
return true;
}

View File

@ -2383,7 +2383,7 @@ int32_t apic_access_vmexit_handler(struct acrn_vcpu *vcpu)
uint32_t offset;
uint64_t qual, access_type;
struct acrn_vlapic *vlapic;
struct mmio_request *mmio;
struct acrn_mmio_request *mmio;
qual = vcpu->arch.exit_qualification;
access_type = apic_access_type(qual);
@ -2407,7 +2407,7 @@ int32_t apic_access_vmexit_handler(struct acrn_vcpu *vcpu)
(decode_instruction(vcpu) >= 0)) {
vlapic = vcpu_vlapic(vcpu);
offset = (uint32_t)apic_access_offset(qual);
mmio = &vcpu->req.reqs.mmio;
mmio = &vcpu->req.reqs.mmio_request;
if (access_type == TYPE_LINEAR_APIC_INST_WRITE) {
err = emulate_instruction(vcpu);
if (err == 0) {

View File

@ -22,11 +22,11 @@ void triple_fault_shutdown_vm(struct acrn_vcpu *vcpu)
struct io_request *io_req = &vcpu->req;
/* Device model emulates PM1A for post-launched VMs */
io_req->io_type = REQ_PORTIO;
io_req->reqs.pio.direction = REQUEST_WRITE;
io_req->reqs.pio.address = VIRTUAL_PM1A_CNT_ADDR;
io_req->reqs.pio.size = 2UL;
io_req->reqs.pio.value = (VIRTUAL_PM1A_SLP_EN | (5U << 10U));
io_req->io_type = ACRN_IOREQ_TYPE_PORTIO;
io_req->reqs.pio_request.direction = ACRN_IOREQ_DIR_WRITE;
io_req->reqs.pio_request.address = VIRTUAL_PM1A_CNT_ADDR;
io_req->reqs.pio_request.size = 2UL;
io_req->reqs.pio_request.value = (VIRTUAL_PM1A_SLP_EN | (5U << 10U));
/* Inject pm1a S5 request to SOS to shut down the guest */
(void)emulate_io(vcpu, io_req);
@ -76,7 +76,7 @@ static bool handle_reset_reg_read(struct acrn_vcpu *vcpu, __unused uint16_t addr
* - reset control register 0xcf9: hide this from guests for now.
* - FADT reset register: the read behavior is not defined in spec, keep it simple to return all '1'.
*/
vcpu->req.reqs.pio.value = ~0U;
vcpu->req.reqs.pio_request.value = ~0U;
}
return ret;
@ -139,10 +139,10 @@ static bool handle_kb_read(struct acrn_vcpu *vcpu, uint16_t addr, size_t bytes)
{
if (is_sos_vm(vcpu->vm) && (bytes == 1U)) {
/* In case i8042 is defined as ACPI PNP device in BIOS, HV need expose physical 0x64 port. */
vcpu->req.reqs.pio.value = pio_read8(addr);
vcpu->req.reqs.pio_request.value = pio_read8(addr);
} else {
/* ACRN will not expose kbd controller to the guest in this case. */
vcpu->req.reqs.pio.value = ~0U;
vcpu->req.reqs.pio_request.value = ~0U;
}
return true;
}

View File

@ -18,7 +18,7 @@
#include <trace.h>
#include <logmsg.h>
void arch_fire_vhm_interrupt(void)
void arch_fire_hsm_interrupt(void)
{
/*
* use vLAPIC to inject vector to SOS vcpu 0 if vlapic is enabled
@ -30,25 +30,25 @@ void arch_fire_vhm_interrupt(void)
sos_vm = get_sos_vm();
vcpu = vcpu_from_vid(sos_vm, BSP_CPU_ID);
vlapic_set_intr(vcpu, get_vhm_notification_vector(), LAPIC_TRIG_EDGE);
vlapic_set_intr(vcpu, get_hsm_notification_vector(), LAPIC_TRIG_EDGE);
}
/**
* @brief General complete-work for port I/O emulation
*
* @pre io_req->io_type == REQ_PORTIO
* @pre io_req->io_type == ACRN_IOREQ_TYPE_PORTIO
*
* @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
* either a previous call to emulate_io() returning 0 or the corresponding IO
* request having transferred to the COMPLETE state.
*/
void
emulate_pio_complete(struct acrn_vcpu *vcpu, const struct io_request *io_req)
{
const struct pio_request *pio_req = &io_req->reqs.pio;
const struct acrn_pio_request *pio_req = &io_req->reqs.pio_request;
uint64_t mask = 0xFFFFFFFFUL >> (32UL - (8UL * pio_req->size));
if (pio_req->direction == REQUEST_READ) {
if (pio_req->direction == ACRN_IOREQ_DIR_READ) {
uint64_t value = (uint64_t)pio_req->value;
uint64_t rax = vcpu_get_gpreg(vcpu, CPU_REG_RAX);
@ -70,19 +70,19 @@ int32_t pio_instr_vmexit_handler(struct acrn_vcpu *vcpu)
uint32_t mask;
int32_t cur_context_idx = vcpu->arch.cur_context;
struct io_request *io_req = &vcpu->req;
struct pio_request *pio_req = &io_req->reqs.pio;
struct acrn_pio_request *pio_req = &io_req->reqs.pio_request;
exit_qual = vcpu->arch.exit_qualification;
io_req->io_type = REQ_PORTIO;
io_req->io_type = ACRN_IOREQ_TYPE_PORTIO;
pio_req->size = vm_exit_io_instruction_size(exit_qual) + 1UL;
pio_req->address = vm_exit_io_instruction_port_number(exit_qual);
if (vm_exit_io_instruction_access_direction(exit_qual) == 0UL) {
mask = 0xFFFFFFFFU >> (32U - (8U * pio_req->size));
pio_req->direction = REQUEST_WRITE;
pio_req->direction = ACRN_IOREQ_DIR_WRITE;
pio_req->value = (uint32_t)vcpu_get_gpreg(vcpu, CPU_REG_RAX) & mask;
} else {
pio_req->direction = REQUEST_READ;
pio_req->direction = ACRN_IOREQ_DIR_READ;
}
TRACE_4I(TRACE_VMEXIT_IO_INSTRUCTION,
@ -102,7 +102,7 @@ int32_t ept_violation_vmexit_handler(struct acrn_vcpu *vcpu)
uint64_t exit_qual;
uint64_t gpa;
struct io_request *io_req = &vcpu->req;
struct mmio_request *mmio_req = &io_req->reqs.mmio;
struct acrn_mmio_request *mmio_req = &io_req->reqs.mmio_request;
/* Handle page fault from guest */
exit_qual = vcpu->arch.exit_qualification;
@ -125,21 +125,21 @@ int32_t ept_violation_vmexit_handler(struct acrn_vcpu *vcpu)
status = 0;
} else {
io_req->io_type = REQ_MMIO;
io_req->io_type = ACRN_IOREQ_TYPE_MMIO;
/* Specify if read or write operation */
if ((exit_qual & 0x2UL) != 0UL) {
/* Write operation */
mmio_req->direction = REQUEST_WRITE;
mmio_req->direction = ACRN_IOREQ_DIR_WRITE;
mmio_req->value = 0UL;
/* XXX: write access while EPT perm RX -> WP */
if ((exit_qual & 0x38UL) == 0x28UL) {
io_req->io_type = REQ_WP;
io_req->io_type = ACRN_IOREQ_TYPE_WP;
}
} else {
/* Read operation */
mmio_req->direction = REQUEST_READ;
mmio_req->direction = ACRN_IOREQ_DIR_READ;
/* TODO: Need to determine how sign extension is determined for
* reads
@ -160,7 +160,7 @@ int32_t ept_violation_vmexit_handler(struct acrn_vcpu *vcpu)
*/
/* Determine value being written. */
if (mmio_req->direction == REQUEST_WRITE) {
if (mmio_req->direction == ACRN_IOREQ_DIR_WRITE) {
status = emulate_instruction(vcpu);
if (status != 0) {
ret = -EFAULT;

View File

@ -527,8 +527,7 @@ int32_t hcall_inject_msi(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, __un
*
* @param vcpu Pointer to vCPU that initiates the hypercall
* @param target_vm Pointer to target VM data structure
* @param param2 guest physical address. This gpa points to
* struct acrn_set_ioreq_buffer
* @param param2 guest physical address. This gpa points to buffer address
*
* @pre is_sos_vm(vcpu->vm)
* @return 0 on success, non-zero on error.
@ -542,21 +541,21 @@ int32_t hcall_set_ioreq_buffer(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm
int32_t ret = -1;
if (is_created_vm(target_vm)) {
struct acrn_set_ioreq_buffer iobuf;
uint64_t iobuf;
if (copy_from_gpa(vm, &iobuf, param2, sizeof(iobuf)) == 0) {
dev_dbg(DBG_LEVEL_HYCALL, "[%d] SET BUFFER=0x%p",
target_vm->vm_id, iobuf.req_buf);
target_vm->vm_id, iobuf);
hpa = gpa2hpa(vm, iobuf.req_buf);
hpa = gpa2hpa(vm, iobuf);
if (hpa == INVALID_HPA) {
pr_err("%s,vm[%hu] gpa 0x%lx,GPA is unmapping.",
__func__, vm->vm_id, iobuf.req_buf);
__func__, vm->vm_id, iobuf);
target_vm->sw.io_shared_page = NULL;
} else {
target_vm->sw.io_shared_page = hpa2hva(hpa);
for (i = 0U; i < VHM_REQUEST_MAX; i++) {
set_vhm_req_state(target_vm, i, REQ_STATE_FREE);
for (i = 0U; i < ACRN_IO_REQUEST_MAX; i++) {
set_io_req_state(target_vm, i, ACRN_IOREQ_STATE_FREE);
}
ret = 0;
}
@ -1232,7 +1231,7 @@ int32_t hcall_set_callback_vector(__unused struct acrn_vcpu *vcpu, __unused stru
pr_err("%s: Invalid passed vector\n", __func__);
ret = -EINVAL;
} else {
set_vhm_notification_vector((uint32_t)param1);
set_hsm_notification_vector((uint32_t)param1);
ret = 0;
}

View File

@ -10,34 +10,34 @@
#define DBG_LEVEL_IOREQ 6U
static uint32_t acrn_vhm_notification_vector = HYPERVISOR_CALLBACK_VHM_VECTOR;
static uint32_t acrn_hsm_notification_vector = HYPERVISOR_CALLBACK_HSM_VECTOR;
#define MMIO_DEFAULT_VALUE_SIZE_1 (0xFFUL)
#define MMIO_DEFAULT_VALUE_SIZE_2 (0xFFFFUL)
#define MMIO_DEFAULT_VALUE_SIZE_4 (0xFFFFFFFFUL)
#define MMIO_DEFAULT_VALUE_SIZE_8 (0xFFFFFFFFFFFFFFFFUL)
#if defined(HV_DEBUG)
__unused static void acrn_print_request(uint16_t vcpu_id, const struct vhm_request *req)
__unused static void acrn_print_request(uint16_t vcpu_id, const struct acrn_io_request *req)
{
switch (req->type) {
case REQ_MMIO:
case ACRN_IOREQ_TYPE_MMIO:
dev_dbg(DBG_LEVEL_IOREQ, "[vcpu_id=%hu type=MMIO]", vcpu_id);
dev_dbg(DBG_LEVEL_IOREQ,
"gpa=0x%lx, R/W=%d, size=%ld value=0x%lx processed=%lx",
req->reqs.mmio.address,
req->reqs.mmio.direction,
req->reqs.mmio.size,
req->reqs.mmio.value,
req->reqs.mmio_request.address,
req->reqs.mmio_request.direction,
req->reqs.mmio_request.size,
req->reqs.mmio_request.value,
req->processed);
break;
case REQ_PORTIO:
case ACRN_IOREQ_TYPE_PORTIO:
dev_dbg(DBG_LEVEL_IOREQ, "[vcpu_id=%hu type=PORTIO]", vcpu_id);
dev_dbg(DBG_LEVEL_IOREQ,
"IO=0x%lx, R/W=%d, size=%ld value=0x%lx processed=%lx",
req->reqs.pio.address,
req->reqs.pio.direction,
req->reqs.pio.size,
req->reqs.pio.value,
req->reqs.pio_request.address,
req->reqs.pio_request.direction,
req->reqs.pio_request.size,
req->reqs.pio_request.value,
req->processed);
break;
default:
@ -59,14 +59,14 @@ void reset_vm_ioreqs(struct acrn_vm *vm)
{
uint16_t i;
for (i = 0U; i < VHM_REQUEST_MAX; i++) {
set_vhm_req_state(vm, i, REQ_STATE_FREE);
for (i = 0U; i < ACRN_IO_REQUEST_MAX; i++) {
set_io_req_state(vm, i, ACRN_IOREQ_STATE_FREE);
}
}
static inline bool has_complete_ioreq(const struct acrn_vcpu *vcpu)
{
return (get_vhm_req_state(vcpu->vm, vcpu->vcpu_id) == REQ_STATE_COMPLETE);
return (get_io_req_state(vcpu->vm, vcpu->vcpu_id) == ACRN_IOREQ_STATE_COMPLETE);
}
/**
@ -79,42 +79,42 @@ static inline bool has_complete_ioreq(const struct acrn_vcpu *vcpu)
*/
int32_t acrn_insert_request(struct acrn_vcpu *vcpu, const struct io_request *io_req)
{
union vhm_request_buffer *req_buf = NULL;
struct vhm_request *vhm_req;
struct acrn_io_request_buffer *req_buf = NULL;
struct acrn_io_request *acrn_io_req;
bool is_polling = false;
int32_t ret = 0;
uint16_t cur;
if ((vcpu->vm->sw.io_shared_page != NULL)
&& (get_vhm_req_state(vcpu->vm, vcpu->vcpu_id) == REQ_STATE_FREE)) {
&& (get_io_req_state(vcpu->vm, vcpu->vcpu_id) == ACRN_IOREQ_STATE_FREE)) {
req_buf = (union vhm_request_buffer *)(vcpu->vm->sw.io_shared_page);
req_buf = (struct acrn_io_request_buffer *)(vcpu->vm->sw.io_shared_page);
cur = vcpu->vcpu_id;
stac();
vhm_req = &req_buf->req_queue[cur];
/* ACRN insert request to VHM and inject upcall */
vhm_req->type = io_req->io_type;
(void)memcpy_s(&vhm_req->reqs, sizeof(union vhm_io_request),
&io_req->reqs, sizeof(union vhm_io_request));
acrn_io_req = &req_buf->req_slot[cur];
/* ACRN insert request to HSM and inject upcall */
acrn_io_req->type = io_req->io_type;
(void)memcpy_s(&acrn_io_req->reqs, sizeof(acrn_io_req->reqs),
&io_req->reqs, sizeof(acrn_io_req->reqs));
if (vcpu->vm->sw.is_polling_ioreq) {
vhm_req->completion_polling = 1U;
acrn_io_req->completion_polling = 1U;
is_polling = true;
}
clac();
/* Before updating the vhm_req state, enforce all fill vhm_req operations done */
/* Before updating the acrn_io_req state, enforce all fill acrn_io_req operations done */
cpu_write_memory_barrier();
/* Must clear the signal before we mark req as pending
* Once we mark it pending, VHM may process req and signal us
* Once we mark it pending, HSM may process req and signal us
* before we perform upcall.
* because VHM can work in pulling mode without wait for upcall
* because HSM can work in pulling mode without wait for upcall
*/
set_vhm_req_state(vcpu->vm, vcpu->vcpu_id, REQ_STATE_PENDING);
set_io_req_state(vcpu->vm, vcpu->vcpu_id, ACRN_IOREQ_STATE_PENDING);
/* signal VHM */
arch_fire_vhm_interrupt();
/* signal HSM */
arch_fire_hsm_interrupt();
/* Polling completion of the request in polling mode */
if (is_polling) {
@ -138,53 +138,53 @@ int32_t acrn_insert_request(struct acrn_vcpu *vcpu, const struct io_request *io_
return ret;
}
uint32_t get_vhm_req_state(struct acrn_vm *vm, uint16_t vhm_req_id)
uint32_t get_io_req_state(struct acrn_vm *vm, uint16_t vcpu_id)
{
uint32_t state;
union vhm_request_buffer *req_buf = NULL;
struct vhm_request *vhm_req;
struct acrn_io_request_buffer *req_buf = NULL;
struct acrn_io_request *acrn_io_req;
req_buf = (union vhm_request_buffer *)vm->sw.io_shared_page;
req_buf = (struct acrn_io_request_buffer *)vm->sw.io_shared_page;
if (req_buf == NULL) {
state = 0xffffffffU;
} else {
stac();
vhm_req = &req_buf->req_queue[vhm_req_id];
state = vhm_req->processed;
acrn_io_req = &req_buf->req_slot[vcpu_id];
state = acrn_io_req->processed;
clac();
}
return state;
}
void set_vhm_req_state(struct acrn_vm *vm, uint16_t vhm_req_id, uint32_t state)
void set_io_req_state(struct acrn_vm *vm, uint16_t vcpu_id, uint32_t state)
{
union vhm_request_buffer *req_buf = NULL;
struct vhm_request *vhm_req;
struct acrn_io_request_buffer *req_buf = NULL;
struct acrn_io_request *acrn_io_req;
req_buf = (union vhm_request_buffer *)vm->sw.io_shared_page;
req_buf = (struct acrn_io_request_buffer *)vm->sw.io_shared_page;
if (req_buf != NULL) {
stac();
vhm_req = &req_buf->req_queue[vhm_req_id];
acrn_io_req = &req_buf->req_slot[vcpu_id];
/*
* HV will only set processed to REQ_STATE_PENDING or REQ_STATE_FREE.
* HV will only set processed to ACRN_IOREQ_STATE_PENDING or ACRN_IOREQ_STATE_FREE.
* we don't need to sfence here is that even if the SOS/DM sees the previous state,
* the only side effect is that it will defer the processing of the new IOReq.
* It won't lead wrong processing.
*/
vhm_req->processed = state;
acrn_io_req->processed = state;
clac();
}
}
void set_vhm_notification_vector(uint32_t vector)
void set_hsm_notification_vector(uint32_t vector)
{
acrn_vhm_notification_vector = vector;
acrn_hsm_notification_vector = vector;
}
uint32_t get_vhm_notification_vector(void)
uint32_t get_hsm_notification_vector(void)
{
return acrn_vhm_notification_vector;
return acrn_hsm_notification_vector;
}
/**
@ -193,17 +193,17 @@ uint32_t get_vhm_notification_vector(void)
* @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->io_type == REQ_MMIO
* @pre io_req->io_type == ACRN_IOREQ_TYPE_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
* either a previous call to emulate_io() returning 0 or the corresponding HSM
* request transferring to the COMPLETE state.
*/
static void emulate_mmio_complete(struct acrn_vcpu *vcpu, const struct io_request *io_req)
{
const struct mmio_request *mmio_req = &io_req->reqs.mmio;
const struct acrn_mmio_request *mmio_req = &io_req->reqs.mmio_request;
if (mmio_req->direction == REQUEST_READ) {
if (mmio_req->direction == ACRN_IOREQ_DIR_READ) {
/* Emulate instruction and update vcpu register set */
(void)emulate_instruction(vcpu);
}
@ -211,21 +211,21 @@ static void emulate_mmio_complete(struct acrn_vcpu *vcpu, const struct io_reques
static void complete_ioreq(struct acrn_vcpu *vcpu, struct io_request *io_req)
{
union vhm_request_buffer *req_buf = NULL;
struct vhm_request *vhm_req;
struct acrn_io_request_buffer *req_buf = NULL;
struct acrn_io_request *acrn_io_req;
req_buf = (union vhm_request_buffer *)(vcpu->vm->sw.io_shared_page);
req_buf = (struct acrn_io_request_buffer *)(vcpu->vm->sw.io_shared_page);
stac();
vhm_req = &req_buf->req_queue[vcpu->vcpu_id];
acrn_io_req = &req_buf->req_slot[vcpu->vcpu_id];
if (io_req != NULL) {
switch (vcpu->req.io_type) {
case REQ_PORTIO:
io_req->reqs.pio.value = vhm_req->reqs.pio.value;
case ACRN_IOREQ_TYPE_PORTIO:
io_req->reqs.pio_request.value = acrn_io_req->reqs.pio_request.value;
break;
case REQ_MMIO:
io_req->reqs.mmio.value = vhm_req->reqs.mmio.value;
case ACRN_IOREQ_TYPE_MMIO:
io_req->reqs.mmio_request.value = acrn_io_req->reqs.mmio_request.value;
break;
default:
@ -235,19 +235,19 @@ static void complete_ioreq(struct acrn_vcpu *vcpu, struct io_request *io_req)
}
/*
* Only HV will check whether processed is REQ_STATE_FREE on per-vCPU before inject a ioreq.
* Only HV will set processed to REQ_STATE_FREE when ioreq is done.
* Only HV will check whether processed is ACRN_IOREQ_STATE_FREE on per-vCPU before inject a ioreq.
* Only HV will set processed to ACRN_IOREQ_STATE_FREE when ioreq is done.
*/
vhm_req->processed = REQ_STATE_FREE;
acrn_io_req->processed = ACRN_IOREQ_STATE_FREE;
clac();
}
/**
* @brief Complete-work of VHM requests for port I/O emulation
* @brief Complete-work of HSM requests for port I/O emulation
*
* @pre vcpu->req.io_type == REQ_PORTIO
* @pre vcpu->req.io_type == ACRN_IOREQ_TYPE_PORTIO
*
* @remark This function must be called after the VHM request corresponding to
* @remark This function must be called after the HSM request corresponding to
* \p vcpu being transferred to the COMPLETE state.
*/
static void dm_emulate_pio_complete(struct acrn_vcpu *vcpu)
@ -260,13 +260,13 @@ static void dm_emulate_pio_complete(struct acrn_vcpu *vcpu)
}
/**
* @brief Complete-work of VHM requests for MMIO emulation
* @brief Complete-work of HSM requests for MMIO emulation
*
* @param vcpu The virtual CPU that triggers the MMIO access
*
* @pre vcpu->req.io_type == REQ_MMIO
* @pre vcpu->req.io_type == ACRN_IOREQ_TYPE_MMIO
*
* @remark This function must be called after the VHM request corresponding to
* @remark This function must be called after the HSM request corresponding to
* \p vcpu being transferred to the COMPLETE state.
*/
static void dm_emulate_mmio_complete(struct acrn_vcpu *vcpu)
@ -279,13 +279,13 @@ static void dm_emulate_mmio_complete(struct acrn_vcpu *vcpu)
}
/**
* @brief General complete-work for all kinds of VHM requests for I/O emulation
* @brief General complete-work for all kinds of HSM requests for I/O emulation
*
* @param vcpu The virtual CPU that triggers the MMIO access
*/
static void dm_emulate_io_complete(struct acrn_vcpu *vcpu)
{
if (get_vhm_req_state(vcpu->vm, vcpu->vcpu_id) == REQ_STATE_COMPLETE) {
if (get_io_req_state(vcpu->vm, vcpu->vcpu_id) == ACRN_IOREQ_STATE_COMPLETE) {
/*
* If vcpu is in Zombie state and will be destroyed soon. Just
* mark ioreq done and don't resume vcpu.
@ -294,26 +294,27 @@ static void dm_emulate_io_complete(struct acrn_vcpu *vcpu)
complete_ioreq(vcpu, NULL);
} else {
switch (vcpu->req.io_type) {
case REQ_MMIO:
case ACRN_IOREQ_TYPE_MMIO:
dm_emulate_mmio_complete(vcpu);
break;
case REQ_PORTIO:
case REQ_PCICFG:
case ACRN_IOREQ_TYPE_PORTIO:
case ACRN_IOREQ_TYPE_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.
* ACRN_IOREQ_TYPE_PORTIO on 0xcf8 & 0xcfc may switch to
* ACRN_IOREQ_TYPE_PCICFG in some cases. It works to apply the post-work
* for ACRN_IOREQ_TYPE_PORTIO on ACRN_IOREQ_TYPE_PCICFG because the
* format of the first 28 bytes of ACRN_IOREQ_TYPE_PORTIO &
* ACRN_IOREQ_TYPE_PCICFG requests are exactly the same and post-work
* is mainly interested in the read value.
*/
dm_emulate_pio_complete(vcpu);
break;
default:
/*
* REQ_WP can only be triggered on writes which do not need
* post-work. Just mark the ioreq done.
* ACRN_IOREQ_TYPE_WP can only be triggered on writes which do
* not need post-work. Just mark the ioreq done.
*/
complete_ioreq(vcpu, NULL);
break;
@ -331,7 +332,7 @@ static void dm_emulate_io_complete(struct acrn_vcpu *vcpu)
static bool pio_default_read(struct acrn_vcpu *vcpu,
__unused uint16_t addr, size_t width)
{
struct pio_request *pio_req = &vcpu->req.reqs.pio;
struct acrn_pio_request *pio_req = &vcpu->req.reqs.pio_request;
pio_req->value = (uint32_t)((1UL << (width * 8U)) - 1UL);
@ -356,9 +357,9 @@ static bool pio_default_write(__unused struct acrn_vcpu *vcpu, __unused uint16_t
static int32_t mmio_default_access_handler(struct io_request *io_req,
__unused void *handler_private_data)
{
struct mmio_request *mmio = &io_req->reqs.mmio;
struct acrn_mmio_request *mmio = &io_req->reqs.mmio_request;
if (mmio->direction == REQUEST_READ) {
if (mmio->direction == ACRN_IOREQ_DIR_READ) {
switch (mmio->size) {
case 1U:
mmio->value = MMIO_DEFAULT_VALUE_SIZE_1;
@ -385,7 +386,7 @@ static int32_t mmio_default_access_handler(struct io_request *io_req,
* Try handling the given request by any port I/O handler registered in the
* hypervisor.
*
* @pre io_req->io_type == REQ_PORTIO
* @pre io_req->io_type == ACRN_IOREQ_TYPE_PORTIO
*
* @retval 0 Successfully emulated by registered handlers.
* @retval -ENODEV No proper handler found.
@ -398,7 +399,7 @@ hv_emulate_pio(struct acrn_vcpu *vcpu, struct io_request *io_req)
uint16_t port, size;
uint32_t idx;
struct acrn_vm *vm = vcpu->vm;
struct pio_request *pio_req = &io_req->reqs.pio;
struct acrn_pio_request *pio_req = &io_req->reqs.pio_request;
struct vm_io_handler_desc *handler;
io_read_fn_t io_read = NULL;
io_write_fn_t io_write = NULL;
@ -427,11 +428,11 @@ hv_emulate_pio(struct acrn_vcpu *vcpu, struct io_request *io_req)
break;
}
if ((pio_req->direction == REQUEST_WRITE) && (io_write != NULL)) {
if ((pio_req->direction == ACRN_IOREQ_DIR_WRITE) && (io_write != NULL)) {
if (io_write(vcpu, port, size, pio_req->value)) {
status = 0;
}
} else if ((pio_req->direction == REQUEST_READ) && (io_read != NULL)) {
} else if ((pio_req->direction == ACRN_IOREQ_DIR_READ) && (io_read != NULL)) {
if (io_read(vcpu, port, size)) {
status = 0;
}
@ -440,7 +441,7 @@ hv_emulate_pio(struct acrn_vcpu *vcpu, struct io_request *io_req)
}
pr_dbg("IO %s on port %04x, data %08x",
(pio_req->direction == REQUEST_READ) ? "read" : "write", port, pio_req->value);
(pio_req->direction == ACRN_IOREQ_DIR_READ) ? "read" : "write", port, pio_req->value);
return status;
}
@ -449,7 +450,7 @@ hv_emulate_pio(struct acrn_vcpu *vcpu, struct io_request *io_req)
* Use registered MMIO handlers on the given request if it falls in the range of
* any of them.
*
* @pre io_req->io_type == REQ_MMIO
* @pre io_req->io_type == ACRN_IOREQ_TYPE_MMIO
*
* @retval 0 Successfully emulated by registered handlers.
* @retval -ENODEV No proper handler found.
@ -462,7 +463,7 @@ hv_emulate_mmio(struct acrn_vcpu *vcpu, struct io_request *io_req)
bool hold_lock = true;
uint16_t idx;
uint64_t address, size, base, end;
struct mmio_request *mmio_req = &io_req->reqs.mmio;
struct acrn_mmio_request *mmio_req = &io_req->reqs.mmio_request;
struct mem_io_node *mmio_handler = NULL;
hv_mem_io_handler_t read_write = NULL;
void *handler_private_data = NULL;
@ -518,7 +519,7 @@ hv_emulate_mmio(struct acrn_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.
* deliver to HSM.
*
* @pre vcpu != NULL
* @pre vcpu->vm != NULL
@ -528,7 +529,7 @@ hv_emulate_mmio(struct acrn_vcpu *vcpu, struct io_request *io_req)
* @param io_req The I/O request holding the details of the MMIO access
*
* @retval 0 Successfully emulated by registered handlers.
* @retval IOREQ_PENDING The I/O request is delivered to VHM.
* @retval ACRN_IOREQ_STATE_PENDING The I/O request is delivered to HSM.
* @retval -EIO The request spans multiple devices and cannot be emulated.
* @retval -EINVAL \p io_req has an invalid io_type.
* @retval <0 on other errors during emulation.
@ -542,14 +543,14 @@ emulate_io(struct acrn_vcpu *vcpu, struct io_request *io_req)
vm_config = get_vm_config(vcpu->vm->vm_id);
switch (io_req->io_type) {
case REQ_PORTIO:
case ACRN_IOREQ_TYPE_PORTIO:
status = hv_emulate_pio(vcpu, io_req);
if (status == 0) {
emulate_pio_complete(vcpu, io_req);
}
break;
case REQ_MMIO:
case REQ_WP:
case ACRN_IOREQ_TYPE_MMIO:
case ACRN_IOREQ_TYPE_WP:
status = hv_emulate_mmio(vcpu, io_req);
if (status == 0) {
emulate_mmio_complete(vcpu, io_req);
@ -563,9 +564,9 @@ emulate_io(struct acrn_vcpu *vcpu, struct io_request *io_req)
if ((status == -ENODEV) && (vm_config->load_order == POST_LAUNCHED_VM)) {
/*
* No handler from HV side, search from VHM in Dom0
* No handler from HV side, search from HSM in Service VM
*
* ACRN insert request to VHM and inject upcall.
* ACRN insert request to HSM and inject upcall.
*/
status = acrn_insert_request(vcpu, io_req);
if (status == 0) {
@ -574,7 +575,7 @@ emulate_io(struct acrn_vcpu *vcpu, struct io_request *io_req)
/* here for both IO & MMIO, the direction, address,
* size definition is same
*/
struct pio_request *pio_req = &io_req->reqs.pio;
struct acrn_pio_request *pio_req = &io_req->reqs.pio_request;
pr_fatal("%s Err: access dir %d, io_type %d, addr = 0x%lx, size=%lu", __func__,
pio_req->direction, io_req->io_type,

View File

@ -84,7 +84,7 @@ static uint32_t ioapic_pin_to_vpin(struct acrn_vm *vm, const struct acrn_vm_conf
static int32_t vgpio_mmio_handler(struct io_request *io_req, void *data)
{
struct mmio_request *mmio = &io_req->reqs.mmio;
struct acrn_mmio_request *mmio = &io_req->reqs.mmio_request;
struct acrn_vm *vm = (struct acrn_vm *) data;
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
int32_t ret = 0;
@ -99,7 +99,7 @@ static int32_t vgpio_mmio_handler(struct io_request *io_req, void *data)
/* all gpio registers have 4 bytes size */
if (mmio->size == 4U) {
if (mmio->direction == REQUEST_READ) {
if (mmio->direction == ACRN_IOREQ_DIR_READ) {
padbar = mmio_read32((const void *)hpa2hva((hpa & ~P2SB_PCR_SPACE_MASK) + GPIO_PADBAR));
pad0 = padbar & P2SB_PCR_SPACE_MASK;
value = mmio_read32((const void *)hva);

View File

@ -556,7 +556,7 @@ get_vm_gsicount(const struct acrn_vm *vm)
int32_t vioapic_mmio_access_handler(struct io_request *io_req, void *handler_private_data)
{
struct acrn_single_vioapic *vioapic = (struct acrn_single_vioapic *)handler_private_data;
struct mmio_request *mmio = &io_req->reqs.mmio;
struct acrn_mmio_request *mmio = &io_req->reqs.mmio_request;
uint64_t gpa = mmio->address;
int32_t ret = 0;
@ -564,10 +564,10 @@ int32_t vioapic_mmio_access_handler(struct io_request *io_req, void *handler_pri
if (mmio->size == 4UL) {
uint32_t data = (uint32_t)mmio->value;
if (mmio->direction == REQUEST_READ) {
if (mmio->direction == ACRN_IOREQ_DIR_READ) {
vioapic_mmio_rw(vioapic, gpa, &data, true);
mmio->value = (uint64_t)data;
} else if (mmio->direction == REQUEST_WRITE) {
} else if (mmio->direction == ACRN_IOREQ_DIR_WRITE) {
vioapic_mmio_rw(vioapic, gpa, &data, false);
} else {
ret = -EINVAL;

View File

@ -188,7 +188,7 @@ static void create_ivshmem_device(struct pci_vdev *vdev)
static int32_t ivshmem_mmio_handler(struct io_request *io_req, void *data)
{
union ivshmem_doorbell doorbell;
struct mmio_request *mmio = &io_req->reqs.mmio;
struct acrn_mmio_request *mmio = &io_req->reqs.mmio_request;
struct pci_vdev *vdev = (struct pci_vdev *) data;
struct ivshmem_device *ivs_dev = (struct ivshmem_device *) vdev->priv_data;
uint64_t offset = mmio->address - vdev->vbars[IVSHMEM_MMIO_BAR].base_gpa;
@ -200,7 +200,7 @@ static int32_t ivshmem_mmio_handler(struct io_request *io_req, void *data)
* IVSHMEM_IV_POS_REG is Read-Only register and IVSHMEM_DOORBELL_REG
* is Write-Only register, they are used for interrupt.
*/
if (mmio->direction == REQUEST_READ) {
if (mmio->direction == ACRN_IOREQ_DIR_READ) {
if (offset != IVSHMEM_DOORBELL_REG) {
mmio->value = ivs_dev->mmio.data[offset >> 2U];
} else {

View File

@ -129,7 +129,7 @@ static void remap_one_vmsix_entry(const struct pci_vdev *vdev, uint32_t index)
*/
static int32_t pt_vmsix_handle_table_mmio_access(struct io_request *io_req, void *priv_data)
{
struct mmio_request *mmio = &io_req->reqs.mmio;
struct acrn_mmio_request *mmio = &io_req->reqs.mmio_request;
struct pci_vdev *vdev;
uint32_t index;
int32_t ret = 0;
@ -138,7 +138,7 @@ static int32_t pt_vmsix_handle_table_mmio_access(struct io_request *io_req, void
if (vdev->user == vdev) {
index = rw_vmsix_table(vdev, io_req);
if ((mmio->direction == REQUEST_WRITE) && (index < vdev->msix.table_count)) {
if ((mmio->direction == ACRN_IOREQ_DIR_WRITE) && (index < vdev->msix.table_count)) {
if (vdev->msix.is_vmsix_on_msi) {
remap_one_vmsix_entry_on_msi(vdev, index);
} else {

View File

@ -43,7 +43,7 @@ static int32_t read_vmcs9900_cfg(const struct pci_vdev *vdev,
static int32_t vmcs9900_mmio_handler(struct io_request *io_req, void *data)
{
struct mmio_request *mmio = &io_req->reqs.mmio;
struct acrn_mmio_request *mmio = &io_req->reqs.mmio_request;
struct pci_vdev *vdev = (struct pci_vdev *)data;
struct acrn_vuart *vu = vdev->priv_data;
struct pci_vbar *vbar = &vdev->vbars[MCS9900_MMIO_BAR];
@ -51,7 +51,7 @@ static int32_t vmcs9900_mmio_handler(struct io_request *io_req, void *data)
offset = mmio->address - vbar->base_gpa;
if (mmio->direction == REQUEST_READ) {
if (mmio->direction == ACRN_IOREQ_DIR_READ) {
mmio->value = vuart_read_reg(vu, offset);
} else {
vuart_write_reg(vu, offset, (uint8_t) mmio->value);

View File

@ -67,7 +67,7 @@ bool write_vmsix_cap_reg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes,
*/
uint32_t rw_vmsix_table(struct pci_vdev *vdev, struct io_request *io_req)
{
struct mmio_request *mmio = &io_req->reqs.mmio;
struct acrn_mmio_request *mmio = &io_req->reqs.mmio_request;
struct msix_table_entry *entry;
uint32_t entry_offset, table_offset, index = CONFIG_MAX_MSIX_TABLE_NUM;
uint64_t offset;
@ -83,14 +83,14 @@ uint32_t rw_vmsix_table(struct pci_vdev *vdev, struct io_request *io_req)
entry = &vdev->msix.table_entries[index];
entry_offset = table_offset % MSIX_TABLE_ENTRY_SIZE;
if (mmio->direction == REQUEST_READ) {
if (mmio->direction == ACRN_IOREQ_DIR_READ) {
(void)memcpy_s(&mmio->value, (size_t)mmio->size,
(void *)entry + entry_offset, (size_t)mmio->size);
} else {
(void)memcpy_s((void *)entry + entry_offset, (size_t)mmio->size,
&mmio->value, (size_t)mmio->size);
}
} else if (mmio->direction == REQUEST_READ) {
} else if (mmio->direction == ACRN_IOREQ_DIR_READ) {
mmio->value = 0UL;
}
} else {

View File

@ -55,7 +55,7 @@ static bool vpci_pio_cfgaddr_read(struct acrn_vcpu *vcpu, uint16_t addr, size_t
uint32_t val = ~0U;
struct acrn_vpci *vpci = &vcpu->vm->vpci;
union pci_cfg_addr_reg *cfg_addr = &vpci->addr;
struct pio_request *pio_req = &vcpu->req.reqs.pio;
struct acrn_pio_request *pio_req = &vcpu->req.reqs.pio_request;
if ((addr == (uint16_t)PCI_CONFIG_ADDR) && (bytes == 4U)) {
val = cfg_addr->value;
@ -121,7 +121,7 @@ static bool vpci_pio_cfgdata_read(struct acrn_vcpu *vcpu, uint16_t addr, size_t
union pci_bdf bdf;
uint16_t offset = addr - PCI_CONFIG_DATA;
uint32_t val = ~0U;
struct pio_request *pio_req = &vcpu->req.reqs.pio;
struct acrn_pio_request *pio_req = &vcpu->req.reqs.pio_request;
cfg_addr.value = atomic_readandclear32(&vpci->addr.value);
if (cfg_addr.bits.enable != 0U) {
@ -174,7 +174,7 @@ static bool vpci_pio_cfgdata_write(struct acrn_vcpu *vcpu, uint16_t addr, size_t
static int32_t vpci_mmio_cfg_access(struct io_request *io_req, void *private_data)
{
int32_t ret = 0;
struct mmio_request *mmio = &io_req->reqs.mmio;
struct acrn_mmio_request *mmio = &io_req->reqs.mmio_request;
struct acrn_vpci *vpci = (struct acrn_vpci *)private_data;
uint64_t pci_mmcofg_base = vpci->pci_mmcfg.address;
uint64_t address = mmio->address;
@ -192,7 +192,7 @@ static int32_t vpci_mmio_cfg_access(struct io_request *io_req, void *private_dat
*/
bdf.value = (uint16_t)((address - pci_mmcofg_base) >> 12U);
if (mmio->direction == REQUEST_READ) {
if (mmio->direction == ACRN_IOREQ_DIR_READ) {
ret = vpci_read_cfg(vpci, bdf, reg_num, (uint32_t)mmio->size, (uint32_t *)&mmio->value);
} else {
ret = vpci_write_cfg(vpci, bdf, reg_num, (uint32_t)mmio->size, (uint32_t)mmio->value);

View File

@ -813,7 +813,7 @@ static int32_t vpic_primary_handler(struct acrn_vpic *vpic, bool in, uint16_t po
*/
static bool vpic_primary_io_read(struct acrn_vcpu *vcpu, uint16_t addr, size_t width)
{
struct pio_request *pio_req = &vcpu->req.reqs.pio;
struct acrn_pio_request *pio_req = &vcpu->req.reqs.pio_request;
if (vpic_primary_handler(vm_pic(vcpu->vm), true, addr, width, &pio_req->value) < 0) {
pr_err("Primary vPIC read port 0x%x width=%d failed\n",
@ -865,7 +865,7 @@ static int32_t vpic_secondary_handler(struct acrn_vpic *vpic, bool in, uint16_t
*/
static bool vpic_secondary_io_read(struct acrn_vcpu *vcpu, uint16_t addr, size_t width)
{
struct pio_request *pio_req = &vcpu->req.reqs.pio;
struct acrn_pio_request *pio_req = &vcpu->req.reqs.pio_request;
if (vpic_secondary_handler(vm_pic(vcpu->vm), true, addr, width, &pio_req->value) < 0) {
pr_err("Secondary vPIC read port 0x%x width=%d failed\n",
@ -943,7 +943,7 @@ static int32_t vpic_elc_handler(struct acrn_vpic *vpic, bool in, uint16_t port,
*/
static bool vpic_elc_io_read(struct acrn_vcpu *vcpu, uint16_t addr, size_t width)
{
struct pio_request *pio_req = &vcpu->req.reqs.pio;
struct acrn_pio_request *pio_req = &vcpu->req.reqs.pio_request;
if (vpic_elc_handler(vm_pic(vcpu->vm), true, addr, width, &pio_req->value) < 0) {
pr_err("pic elc read port 0x%x width=%d failed", addr, width);

View File

@ -51,7 +51,7 @@ static uint8_t cmos_get_reg_val(uint8_t addr)
static bool vrtc_read(struct acrn_vcpu *vcpu, uint16_t addr, __unused size_t width)
{
uint8_t offset;
struct pio_request *pio_req = &vcpu->req.reqs.pio;
struct acrn_pio_request *pio_req = &vcpu->req.reqs.pio_request;
struct acrn_vm *vm = vcpu->vm;
offset = vm->vrtc_offset;

View File

@ -537,7 +537,7 @@ static bool vuart_read(struct acrn_vcpu *vcpu, uint16_t offset_arg, __unused siz
{
uint16_t offset = offset_arg;
struct acrn_vuart *vu = find_vuart_by_port(vcpu->vm, offset);
struct pio_request *pio_req = &vcpu->req.reqs.pio;
struct acrn_pio_request *pio_req = &vcpu->req.reqs.pio_request;
if (vu != NULL) {
offset -= vu->port_base;

View File

@ -52,7 +52,7 @@ int32_t ept_violation_vmexit_handler(struct acrn_vcpu *vcpu);
* @pre io_req->io_type == REQ_PORTIO
*
* @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
* either a previous call to emulate_io() returning 0 or the corresponding HSM
* request having transferred to the COMPLETE state.
*/
void emulate_pio_complete(struct acrn_vcpu *vcpu, const struct io_request *io_req);
@ -82,10 +82,10 @@ void allow_guest_pio_access(struct acrn_vm *vm, uint16_t port_address, uint32_
void deny_guest_pio_access(struct acrn_vm *vm, uint16_t port_address, uint32_t nbytes);
/**
* @brief Fire VHM interrupt to SOS
* @brief Fire HSM interrupt to SOS
*
* @return None
*/
void arch_fire_vhm_interrupt(void);
void arch_fire_hsm_interrupt(void);
#endif /* IO_EMUL_H */

View File

@ -40,7 +40,7 @@
*/
#define NR_STATIC_MAPPINGS (NR_STATIC_MAPPINGS_1 + CONFIG_MAX_VM_NUM)
#define HYPERVISOR_CALLBACK_VHM_VECTOR 0xF3U
#define HYPERVISOR_CALLBACK_HSM_VECTOR 0xF3U
/* vectors range for dynamic allocation, usually for devices */
#define VECTOR_DYNAMIC_START 0x20U

View File

@ -210,8 +210,7 @@ int32_t hcall_inject_msi(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint
* @param vcpu Pointer to vCPU that initiates the hypercall
* @param target_vm Pointer to target VM data structure
* @param param1 not used
* @param param2 guest physical address. This gpa points to
* struct acrn_set_ioreq_buffer
* @param param2 guest physical address. This gpa points to buffer address
*
* @pre is_sos_vm(vcpu->vm)
* @return 0 on success, non-zero on error.

View File

@ -25,14 +25,19 @@ struct io_request {
/**
* @brief Type of the request (PIO, MMIO, etc).
*
* Refer to vhm_request for detailed description of I/O request types.
* Refer to acrn_io_request for detailed description of I/O request types.
*/
uint32_t io_type;
/**
* @brief Details of this request in the same format as vhm_request.
* @brief Details of this request in the same format as acrn_io_request.
*/
union vhm_io_request reqs;
union {
struct acrn_pio_request pio_request;
struct acrn_pci_request pci_request;
struct acrn_mmio_request mmio_request;
uint64_t data[8];
} reqs;
};
/**
@ -105,7 +110,6 @@ struct vm_io_handler_desc {
};
/* Typedef for MMIO handler and range check routine */
struct mmio_request;
typedef int32_t (*hv_mem_io_handler_t)(struct io_request *io_req, void *handler_private_data);
/**
@ -187,45 +191,45 @@ int32_t acrn_insert_request(struct acrn_vcpu *vcpu, const struct io_request *io_
void reset_vm_ioreqs(struct acrn_vm *vm);
/**
* @brief Get the state of VHM request
* @brief Get the state of an IO request
*
* @param vm Target VM context
* @param vhm_req_id VHM Request ID
* @param vcpu_id VCPU ID of the IO request
*
* @return State of the IO Request.
*/
uint32_t get_vhm_req_state(struct acrn_vm *vm, uint16_t vhm_req_id);
uint32_t get_io_req_state(struct acrn_vm *vm, uint16_t vcpu_id);
/**
* @brief Set the state of VHM request
* @brief Set the state of IO request
*
* @param vm Target VM context
* @param vhm_req_id VHM Request ID
* @param vcpu_id VCPU ID of the IO request
* @param state State to be set
* @return None
*/
void set_vhm_req_state(struct acrn_vm *vm, uint16_t vhm_req_id, uint32_t state);
void set_io_req_state(struct acrn_vm *vm, uint16_t vcpu_id, uint32_t state);
/**
* @brief Set the vector for HV callback VHM
* @brief Set the vector for HV callback HSM
*
* @param vector vector for HV callback VHM
* @param vector vector for HV callback HSM
* @return None
*/
void set_vhm_notification_vector(uint32_t vector);
void set_hsm_notification_vector(uint32_t vector);
/**
* @brief Get the vector for HV callback VHM
* @brief Get the vector for HV callback HSM
*
* @return vector for HV callbakc VH
* @return vector for HV callbakc HSM
*/
uint32_t get_vhm_notification_vector(void);
uint32_t get_hsm_notification_vector(void);
/**
* @brief Emulate \p io_req for \p vcpu
*
* Handle an I/O request by either invoking a hypervisor-internal handler or
* deliver to VHM.
* deliver to HSM.
*
* @pre vcpu != NULL
* @pre vcpu->vm != NULL
@ -235,7 +239,7 @@ uint32_t get_vhm_notification_vector(void);
* @param io_req The I/O request holding the details of the MMIO access
*
* @retval 0 Successfully emulated by registered handlers.
* @retval IOREQ_PENDING The I/O request is delivered to VHM.
* @retval IOREQ_PENDING The I/O request is delivered to HSM.
* @retval -EIO The request spans multiple devices and cannot be emulated.
* @retval -EINVAL \p io_req has an invalid type.
* @retval <0 on other errors during emulation.

View File

@ -18,26 +18,29 @@
#include <types.h>
/*
* Common structures for ACRN/VHM/DM
* Common structures for ACRN/HSM/DM
*/
/*
* IO request
*/
#define VHM_REQUEST_MAX 16U
#define REQ_STATE_FREE 3U
#define REQ_STATE_PENDING 0U
#define REQ_STATE_COMPLETE 1U
#define REQ_STATE_PROCESSING 2U
#define ACRN_IO_REQUEST_MAX 16U
#define ACRN_IOREQ_STATE_PENDING 0U
#define ACRN_IOREQ_STATE_COMPLETE 1U
#define ACRN_IOREQ_STATE_PROCESSING 2U
#define ACRN_IOREQ_STATE_FREE 3U
#define ACRN_IOREQ_TYPE_PORTIO 0U
#define ACRN_IOREQ_TYPE_MMIO 1U
#define ACRN_IOREQ_TYPE_PCICFG 2U
#define ACRN_IOREQ_TYPE_WP 3U
#define ACRN_IOREQ_DIR_READ 0U
#define ACRN_IOREQ_DIR_WRITE 1U
#define REQ_PORTIO 0U
#define REQ_MMIO 1U
#define REQ_PCICFG 2U
#define REQ_WP 3U
#define REQUEST_READ 0U
#define REQUEST_WRITE 1U
/* IOAPIC device model info */
#define VIOAPIC_RTE_NUM 48U /* vioapic pins */
@ -72,11 +75,11 @@
/**
* @brief Representation of a MMIO request
*/
struct mmio_request {
struct acrn_mmio_request {
/**
* @brief Direction of the access
*
* Either \p REQUEST_READ or \p REQUEST_WRITE.
* Either \p ACRN_IOREQ_DIR_READ or \p ACRN_IOREQ_DIR_WRITE.
*/
uint32_t direction;
@ -104,11 +107,11 @@ struct mmio_request {
/**
* @brief Representation of a port I/O request
*/
struct pio_request {
struct acrn_pio_request {
/**
* @brief Direction of the access
*
* Either \p REQUEST_READ or \p REQUEST_WRITE.
* Either \p ACRN_IOREQ_DIR_READ or \p ACRN_IOREQ_DIR_WRITE.
*/
uint32_t direction;
@ -136,11 +139,11 @@ struct pio_request {
/**
* @brief Representation of a PCI configuration space access
*/
struct pci_request {
struct acrn_pci_request {
/**
* @brief Direction of the access
*
* Either \p REQUEST_READ or \p REQUEST_WRITE.
* Either \p ACRN_IOREQ_DIR_READ or \p ACRN_IOREQ_DIR_WRITE.
*/
uint32_t direction;
@ -180,28 +183,21 @@ struct pci_request {
int32_t reg;
} __aligned(8);
union vhm_io_request {
struct pio_request pio;
struct pci_request pci;
struct mmio_request mmio;
int64_t reserved1[8];
};
/**
* @brief 256-byte VHM requests
* @brief 256-byte I/O requests
*
* The state transitions of a VHM request are:
* The state transitions of a I/O request are:
*
* FREE -> PENDING -> PROCESSING -> COMPLETE -> FREE -> ...
*
* When a request is in COMPLETE or FREE state, the request is owned by the
* hypervisor. SOS (VHM or DM) shall not read or write the internals of the
* hypervisor. SOS (HSM or DM) shall not read or write the internals of the
* request except the state.
*
* When a request is in PENDING or PROCESSING state, the request is owned by
* SOS. The hypervisor shall not read or write the request other than the state.
*
* Based on the rules above, a typical VHM request lifecycle should looks like
* Based on the rules above, a typical I/O request lifecycle should looks like
* the following.
*
* @verbatim embed:rst:leading-asterisk
@ -270,9 +266,9 @@ union vhm_io_request {
* the hypervisor, as the hypervisor shall not access the request any more.
*
* 2. Due to similar reasons, setting state to COMPLETE is the last operation
* of request handling in VHM or clients in SOS.
* of request handling in HSM or clients in SOS.
*/
struct vhm_request {
struct acrn_io_request {
/**
* @brief Type of this request.
*
@ -297,13 +293,14 @@ struct vhm_request {
/**
* @brief Details about this request.
*
* For REQ_PORTIO, this has type
* pio_request. For REQ_MMIO and REQ_WP, this has type mmio_request. For
* REQ_PCICFG, this has type pci_request.
*
* Byte offset: 64.
*/
union vhm_io_request reqs;
union {
struct acrn_pio_request pio_request;
struct acrn_pci_request pci_request;
struct acrn_mmio_request mmio_request;
uint64_t data[8];
} reqs;
/**
* @brief Reserved.
@ -313,27 +310,27 @@ struct vhm_request {
uint32_t reserved1;
/**
* @brief The client which is distributed to handle this request.
*
* Accessed by VHM only.
* @brief If this request has been handled by HSM driver.
*
* Byte offset: 132.
*/
int32_t client;
int32_t kernel_handled;
/**
* @brief The status of this request.
*
* Taking REQ_STATE_xxx as values.
* Taking ACRN_IOREQ_STATE_xxx as values.
*
* Byte offset: 136.
*/
uint32_t processed;
} __aligned(256);
union vhm_request_buffer {
struct vhm_request req_queue[VHM_REQUEST_MAX];
struct acrn_io_request_buffer {
union {
struct acrn_io_request req_slot[ACRN_IO_REQUEST_MAX];
int8_t reserved[4096];
};
} __aligned(4096);
/**

View File

@ -63,4 +63,4 @@ CTASSERT(CPU_CONTEXT_OFFSET_LDTR - CPU_CONTEXT_OFFSET_EXTCTX_START
CTASSERT((sizeof(struct trusty_startup_param)
+ sizeof(struct trusty_key_info)) < 0x1000U);
CTASSERT(NR_WORLD == 2);
CTASSERT(sizeof(struct vhm_request) == (4096U/VHM_REQUEST_MAX));
CTASSERT(sizeof(struct acrn_io_request) == (4096U/ACRN_IO_REQUEST_MAX));