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

@@ -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 state State to be set
* @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];
int8_t reserved[4096];
struct acrn_io_request_buffer {
union {
struct acrn_io_request req_slot[ACRN_IO_REQUEST_MAX];
int8_t reserved[4096];
};
} __aligned(4096);
/**