HV: io: separate I/O emulation interface declarations

Currently the I/O emulation structures and interfaces are scattered among mmu.h,
io.h and guest.h, and tangled with other interfaces there. This patch moves the
former to a separate header ioreq.h.

Signed-off-by: Junjie Mao <junjie.mao@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Junjie Mao 2018-07-24 17:00:10 +08:00 committed by lijinxia
parent 3cab92655d
commit 1915eec632
5 changed files with 136 additions and 125 deletions

View File

@ -32,10 +32,6 @@
#define IDX_PAT (IDX_TSC + 1U)
#define IDX_MAX_MSR (IDX_PAT + 1U)
struct vhm_request;
int32_t acrn_insert_request_wait(struct vcpu *vcpu, struct vhm_request *req);
/*
* VCPU related APIs
*/

View File

@ -15,6 +15,7 @@
#include <lapic.h>
#include <msr.h>
#include <io.h>
#include <ioreq.h>
#include <mtrr.h>
#include <vcpu.h>
#include <trusty.h>

View File

@ -9,13 +9,6 @@
#include <types.h>
/* Definition of a IO port range */
struct vm_io_range {
uint16_t base; /* IO port base */
uint16_t len; /* IO port range */
uint32_t flags; /* IO port attributes */
};
/* Write 1 byte to specified I/O port */
static inline void io_write_byte(uint8_t value, uint16_t port)
{
@ -83,80 +76,6 @@ static inline uint32_t io_read(uint16_t addr, size_t sz)
return io_read_long(addr);
}
struct vm_io_handler;
struct vm;
struct vcpu;
typedef
uint32_t (*io_read_fn_t)(struct vm_io_handler *, struct vm *,
uint16_t, size_t);
typedef
void (*io_write_fn_t)(struct vm_io_handler *, struct vm *,
uint16_t, size_t, uint32_t);
/* Describes a single IO handler description entry. */
struct vm_io_handler_desc {
/** The base address of the IO range for this description. */
uint16_t addr;
/** The number of bytes covered by this description. */
size_t len;
/** A pointer to the "read" function.
*
* The read function is called from the hypervisor whenever
* a read access to a range described in "ranges" occur.
* The arguments to the callback are:
*
* - The address of the port to read from.
* - The width of the read operation (1,2 or 4).
*
* The implementation must return the ports content as
* byte, word or doubleword (depending on the width).
*
* If the pointer is null, a read of 1's is assumed.
*/
io_read_fn_t io_read;
/** A pointer to the "write" function.
*
* The write function is called from the hypervisor code
* whenever a write access to a range described in "ranges"
* occur. The arguments to the callback are:
*
* - The address of the port to write to.
* - The width of the write operation (1,2 or 4).
* - The value to write as byte, word or doubleword
* (depending on the width)
*
* The implementation must write the value to the port.
*
* If the pointer is null, the write access is ignored.
*/
io_write_fn_t io_write;
};
struct vm_io_handler {
struct vm_io_handler *next;
struct vm_io_handler_desc desc;
};
#define IO_ATTR_R 0U
#define IO_ATTR_RW 1U
#define IO_ATTR_NO_ACCESS 2U
/* External Interfaces */
int io_instr_vmexit_handler(struct vcpu *vcpu);
void setup_io_bitmap(struct vm *vm);
void free_io_emulation_resource(struct vm *vm);
void allow_guest_io_access(struct vm *vm, uint32_t address, uint32_t nbytes);
void register_io_emulation_handler(struct vm *vm, struct vm_io_range *range,
io_read_fn_t io_read_fn_ptr,
io_write_fn_t io_write_fn_ptr);
int dm_emulate_pio_post(struct vcpu *vcpu);
/** Writes a 32 bit value to a memory mapped IO device.
*
* @param value The 32 bit value to write.
@ -327,24 +246,4 @@ static inline void setb(void *addr, uint8_t mask, uint8_t value)
mmio_write_byte((mmio_read_byte(addr) & ~mask) | value, addr);
}
/* MMIO memory access types */
enum mem_io_type {
HV_MEM_IO_READ = 0,
HV_MEM_IO_WRITE,
};
/* MMIO emulation related structures */
#define MMIO_TRANS_VALID 1U
#define MMIO_TRANS_INVALID 0U
struct mem_io {
uint64_t paddr; /* Physical address being accessed */
enum mem_io_type read_write; /* 0 = read / 1 = write operation */
uint8_t access_size; /* Access size being emulated */
uint8_t sign_extend_read; /* 1 if sign extension required for read */
uint64_t value; /* Value read or value to write */
uint8_t mmio_status; /* Indicates if this MMIO transaction is valid */
/* Used to store emulation context for this mmio transaction */
void *private_data;
};
#endif /* _IO_H defined */

View File

@ -0,0 +1,135 @@
/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef IOREQ_H
#define IOREQ_H
#include <types.h>
/* Definition of a IO port range */
struct vm_io_range {
uint16_t base; /* IO port base */
uint16_t len; /* IO port range */
uint32_t flags; /* IO port attributes */
};
struct vm_io_handler;
struct vm;
struct vcpu;
typedef
uint32_t (*io_read_fn_t)(struct vm_io_handler *, struct vm *,
uint16_t, size_t);
typedef
void (*io_write_fn_t)(struct vm_io_handler *, struct vm *,
uint16_t, size_t, uint32_t);
/* Describes a single IO handler description entry. */
struct vm_io_handler_desc {
/** The base address of the IO range for this description. */
uint16_t addr;
/** The number of bytes covered by this description. */
size_t len;
/** A pointer to the "read" function.
*
* The read function is called from the hypervisor whenever
* a read access to a range described in "ranges" occur.
* The arguments to the callback are:
*
* - The address of the port to read from.
* - The width of the read operation (1,2 or 4).
*
* The implementation must return the ports content as
* byte, word or doubleword (depending on the width).
*
* If the pointer is null, a read of 1's is assumed.
*/
io_read_fn_t io_read;
/** A pointer to the "write" function.
*
* The write function is called from the hypervisor code
* whenever a write access to a range described in "ranges"
* occur. The arguments to the callback are:
*
* - The address of the port to write to.
* - The width of the write operation (1,2 or 4).
* - The value to write as byte, word or doubleword
* (depending on the width)
*
* The implementation must write the value to the port.
*
* If the pointer is null, the write access is ignored.
*/
io_write_fn_t io_write;
};
struct vm_io_handler {
struct vm_io_handler *next;
struct vm_io_handler_desc desc;
};
#define IO_ATTR_R 0U
#define IO_ATTR_RW 1U
#define IO_ATTR_NO_ACCESS 2U
/* MMIO memory access types */
enum mem_io_type {
HV_MEM_IO_READ = 0,
HV_MEM_IO_WRITE,
};
/* MMIO emulation related structures */
#define MMIO_TRANS_VALID 1U
#define MMIO_TRANS_INVALID 0U
struct mem_io {
uint64_t paddr; /* Physical address being accessed */
enum mem_io_type read_write; /* 0 = read / 1 = write operation */
uint8_t access_size; /* Access size being emulated */
uint8_t sign_extend_read; /* 1 if sign extension required for read */
uint64_t value; /* Value read or value to write */
uint8_t mmio_status; /* Indicates if this MMIO transaction is valid */
/* Used to store emulation context for this mmio transaction */
void *private_data;
};
/* Typedef for MMIO handler and range check routine */
struct mmio_request;
typedef int (*hv_mem_io_handler_t)(struct vcpu *, struct mem_io *, void *);
/* Structure for MMIO handler node */
struct mem_io_node {
hv_mem_io_handler_t read_write;
void *handler_private_data;
struct list_head list;
uint64_t range_start;
uint64_t range_end;
};
/* External Interfaces */
int io_instr_vmexit_handler(struct vcpu *vcpu);
void setup_io_bitmap(struct vm *vm);
void free_io_emulation_resource(struct vm *vm);
void allow_guest_io_access(struct vm *vm, uint32_t address, uint32_t nbytes);
void register_io_emulation_handler(struct vm *vm, struct vm_io_range *range,
io_read_fn_t io_read_fn_ptr,
io_write_fn_t io_write_fn_ptr);
int dm_emulate_pio_post(struct vcpu *vcpu);
int register_mmio_emulation_handler(struct vm *vm,
hv_mem_io_handler_t read_write, uint64_t start,
uint64_t end, void *handler_private_data);
void unregister_mmio_emulation_handler(struct vm *vm, uint64_t start,
uint64_t end);
int dm_emulate_mmio_post(struct vcpu *vcpu);
int32_t acrn_insert_request_wait(struct vcpu *vcpu, struct vhm_request *req);
#endif /* IOREQ_H */

View File

@ -303,18 +303,6 @@ static inline void mem_write64(void *addr, uint64_t data)
*addr64 = data;
}
/* Typedef for MMIO handler and range check routine */
typedef int(*hv_mem_io_handler_t)(struct vcpu *, struct mem_io *, void *);
/* Structure for MMIO handler node */
struct mem_io_node {
hv_mem_io_handler_t read_write;
void *handler_private_data;
struct list_head list;
uint64_t range_start;
uint64_t range_end;
};
uint64_t get_paging_pml4(void);
bool check_mmu_1gb_support(enum _page_table_type page_table_type);
void *alloc_paging_struct(void);
@ -342,13 +330,6 @@ int obtain_last_page_table_entry(struct map_params *map_params,
uint64_t *lookup_address(uint64_t *pml4_page, uint64_t addr,
uint64_t *pg_size, enum _page_table_type ptt);
int register_mmio_emulation_handler(struct vm *vm,
hv_mem_io_handler_t read_write, uint64_t start,
uint64_t end, void *handler_private_data);
void unregister_mmio_emulation_handler(struct vm *vm, uint64_t start,
uint64_t end);
#pragma pack(1)
/** Defines a single entry in an E820 memory map. */
@ -411,7 +392,6 @@ int ept_mr_del(struct vm *vm, uint64_t *pml4_page,
int ept_violation_vmexit_handler(struct vcpu *vcpu);
int ept_misconfig_vmexit_handler(struct vcpu *vcpu);
int dm_emulate_mmio_post(struct vcpu *vcpu);
#endif /* ASSEMBLER not defined */