HV: Clean vpic and vioapic logic when lapic is pt

When the lapic is passthru, vpic and vioapic cannot be used anymore. In
current code, user can still inject vpic interrupt to Guest OS, this is
not allowed.
This patch remove the vpic and vioapic initiate functions during
creating VM with lapic passthru. But the APIs in vpic and vioapic are
called in many places, for these APIs, follow the below principles:

1. For the APIs which will access uninitiated variables, and may case
hypervisor hang, add @pre to make sure user should call them after vpic or
vioapic is initiated.

2. For the APIs which only return some static value, do noting with them.

3. For the APIs which user will called to inject interrupt, such as
vioapic_set_irqline_lock or vpic_set_irqline, add condition in these
APIs to make sure it only inject interrupt when vpic or vioapic is
initiated. This change is to make sure the vuart or hypercall need not
to care whether lapic is passthru or the vpic and vioapic is initiated
or not.

Tracked-On: #3227
Signed-off-by: Conghui Chen <conghui.chen@intel.com>
This commit is contained in:
Conghui Chen 2019-05-22 03:01:23 +08:00 committed by Eddie Dong
parent f83ddd393f
commit ac6c5dce81
4 changed files with 27 additions and 6 deletions

View File

@ -477,7 +477,9 @@ int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_
register_pm1ab_handler(vm);
}
}
if (!is_lapic_pt_configured(vm)) {
vpic_init(vm);
}
/* Create virtual uart;*/
vuart_init(vm, vm_config->vuart);
@ -495,7 +497,9 @@ int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_
vm->wire_mode = VPIC_WIRE_INTR;
/* Init full emulated vIOAPIC instance */
if (!is_lapic_pt_configured(vm)) {
vioapic_init(vm);
}
/* Intercept the virtual pm port for RTVM */
if (is_rt_vm(vm)) {

View File

@ -124,6 +124,8 @@ vioapic_set_pinstate(struct acrn_vioapic *vioapic, uint32_t pin, uint32_t level)
* GSI_RAISING_PULSE/GSI_FALLING_PULSE
*
* @pre irqline < vioapic_pincount(vm)
* @pre vm != NULL
* @pre vioapic->ready == true
* @return None
*/
void
@ -166,6 +168,7 @@ vioapic_set_irqline_nolock(const struct acrn_vm *vm, uint32_t irqline, uint32_t
* GSI_RAISING_PULSE/GSI_FALLING_PULSE
*
* @pre irqline < vioapic_pincount(vm)
* @pre vm != NULL
*
* @return None
*/
@ -173,11 +176,12 @@ void
vioapic_set_irqline_lock(const struct acrn_vm *vm, uint32_t irqline, uint32_t operation)
{
struct acrn_vioapic *vioapic = vm_ioapic(vm);
if (vioapic->ready) {
spinlock_obtain(&(vioapic->mtx));
vioapic_set_irqline_nolock(vm, irqline, operation);
spinlock_release(&(vioapic->mtx));
}
}
static uint32_t
vioapic_indirect_read(const struct acrn_vioapic *vioapic, uint32_t addr)
@ -385,6 +389,10 @@ vioapic_mmio_rw(struct acrn_vioapic *vioapic, uint64_t gpa,
spinlock_release(&(vioapic->mtx));
}
/*
* @pre vm != NULL
* @pre vioapic->ready == true
*/
void
vioapic_process_eoi(struct acrn_vm *vm, uint32_t vector)
{
@ -460,6 +468,7 @@ vioapic_init(struct acrn_vm *vm)
(uint64_t)VIOAPIC_BASE,
(uint64_t)VIOAPIC_BASE + VIOAPIC_SIZE,
vm);
vm->arch_vm.vioapic.ready = true;
}
uint32_t
@ -476,6 +485,10 @@ vioapic_pincount(const struct acrn_vm *vm)
return ret;
}
/*
* @pre handler_private_data != NULL
* @pre vioapic->ready == true
*/
int32_t vioapic_mmio_access_handler(struct io_request *io_req, void *handler_private_data)
{
struct acrn_vm *vm = (struct acrn_vm *)handler_private_data;

View File

@ -509,6 +509,7 @@ vpic_pincount(void)
/**
* @pre vm->vpic != NULL
* @pre irqline < NR_VPIC_PINS_TOTAL
* @pre this function should be called after vpic_init()
*/
void vpic_get_irqline_trigger_mode(const struct acrn_vm *vm, uint32_t irqline,
enum vpic_trigger *trigger)
@ -531,6 +532,7 @@ void vpic_get_irqline_trigger_mode(const struct acrn_vm *vm, uint32_t irqline,
* @param[inout] vecptr Pointer to vector buffer and will be filled
* with eligible vector if any.
*
* @pre this function should be called after vpic_init()
* @return None
*/
void vpic_pending_intr(struct acrn_vm *vm, uint32_t *vecptr)
@ -593,6 +595,7 @@ static void vpic_pin_accepted(struct i8259_reg_state *i8259, uint32_t pin)
* @return None
*
* @pre vm != NULL
* @pre this function should be called after vpic_init()
*/
void vpic_intr_accepted(struct acrn_vm *vm, uint32_t vector)
{

View File

@ -53,6 +53,7 @@ struct acrn_vioapic {
struct acrn_vm *vm;
spinlock_t mtx;
uint32_t id;
bool ready;
uint32_t ioregsel;
union ioapic_rte rtbl[REDIR_ENTRIES_HW];
/* pin_state status bitmap: 1 - high, 0 - low */