hv: vioapic init for SOS VM on platforms with multiple IO-APICs

For SOS VM, when the target platform has multiple IO-APICs, there
should be equal number of virtual IO-APICs.

This patch adds support for emulating multiple vIOAPICs per VM.

Tracked-On: #4151
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Acked-by: Eddie Dong <eddie.dong@Intel.com>
This commit is contained in:
Sainath Grandhi
2020-02-16 19:22:26 -08:00
committed by wenlingz
parent f67ac09141
commit fe5a108c7b
9 changed files with 206 additions and 73 deletions

View File

@@ -107,7 +107,7 @@ struct vm_arch {
void *sworld_eptp;
struct memory_ops ept_mem_ops;
struct acrn_vioapic vioapic; /* Virtual IOAPIC base address */
struct acrn_vioapics vioapics; /* Virtual IOAPIC/s */
struct acrn_vpic vpic; /* Virtual PIC */
#ifdef CONFIG_HYPERV_ENABLED
struct acrn_hyperv hyperv;

View File

@@ -26,6 +26,8 @@ uint32_t gsi_to_ioapic_pin(uint32_t gsi);
int32_t init_ioapic_id_info(void);
uint8_t ioapic_irq_to_ioapic_id(uint32_t irq);
uint8_t get_platform_ioapic_info (struct ioapic_info **plat_ioapic_info);
/**
* @defgroup ioapic_ext_apis IOAPIC External Interfaces
*
@@ -108,6 +110,7 @@ struct gsi_table {
void *gsi_to_ioapic_base(uint32_t gsi);
uint32_t get_max_nr_gsi(void);
uint8_t get_gsi_to_ioapic_index(uint32_t gsi);
uint32_t get_pic_pin_from_ioapic_pin(uint32_t pin_index);
bool is_gsi_valid(uint32_t gsi);
#endif /* IOAPIC_H */

View File

@@ -48,11 +48,16 @@
#define IOAPIC_RTE_LOW_INTVEC ((uint32_t)IOAPIC_RTE_INTVEC)
struct acrn_vioapic {
struct acrn_vm *vm;
/*
* id field is used to emulate the IOAPIC_ID register of vIOAPIC
*/
struct acrn_single_vioapic {
spinlock_t mtx;
struct acrn_vm *vm;
uint32_t base_addr;
uint32_t nr_pins;
uint32_t gsi_base;
uint32_t id;
bool ready;
uint32_t ioregsel;
@@ -61,8 +66,19 @@ struct acrn_vioapic {
uint64_t pin_state[STATE_BITMAP_SIZE];
};
void vioapic_init(struct acrn_vm *vm);
void vioapic_reset(struct acrn_vm *vm);
/*
* ioapic_num represents the number of IO-APICs emulated for the VM.
* nr_gsi represents the maximum number of GSI emulated for the VM.
*/
struct acrn_vioapics {
uint8_t ioapic_num;
uint32_t nr_gsi;
struct acrn_single_vioapic vioapic_array[CONFIG_MAX_IOAPIC_NUM];
};
void dump_vioapic(struct acrn_vm *vm);
void vioapic_init(struct acrn_vm *vm);
void reset_vioapics(const struct acrn_vm *vm);
/**
@@ -102,8 +118,8 @@ void vioapic_set_irqline_lock(const struct acrn_vm *vm, uint32_t vgsi, uint32_t
*/
void vioapic_set_irqline_nolock(const struct acrn_vm *vm, uint32_t vgsi, uint32_t operation);
uint32_t vioapic_pincount(const struct acrn_vm *vm);
void vioapic_process_eoi(struct acrn_vm *vm, uint32_t vector);
uint32_t get_vm_gsicount(const struct acrn_vm *vm);
void vioapic_broadcast_eoi(const struct acrn_vm *vm, uint32_t vector);
void vioapic_get_rte(const struct acrn_vm *vm, uint32_t vgsi, union ioapic_rte *rte);
int32_t vioapic_mmio_access_handler(struct io_request *io_req, void *handler_private_data);