diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 0604f2da7..06d426b42 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -477,7 +477,9 @@ int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_ register_pm1ab_handler(vm); } } - vpic_init(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 */ - vioapic_init(vm); + if (!is_lapic_pt_configured(vm)) { + vioapic_init(vm); + } /* Intercept the virtual pm port for RTVM */ if (is_rt_vm(vm)) { diff --git a/hypervisor/dm/vioapic.c b/hypervisor/dm/vioapic.c index b8893f566..2ddf34e09 100644 --- a/hypervisor/dm/vioapic.c +++ b/hypervisor/dm/vioapic.c @@ -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,10 +176,11 @@ void vioapic_set_irqline_lock(const struct acrn_vm *vm, uint32_t irqline, uint32_t operation) { struct acrn_vioapic *vioapic = vm_ioapic(vm); - - spinlock_obtain(&(vioapic->mtx)); - vioapic_set_irqline_nolock(vm, irqline, operation); - spinlock_release(&(vioapic->mtx)); + if (vioapic->ready) { + spinlock_obtain(&(vioapic->mtx)); + vioapic_set_irqline_nolock(vm, irqline, operation); + spinlock_release(&(vioapic->mtx)); + } } static uint32_t @@ -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; diff --git a/hypervisor/dm/vpic.c b/hypervisor/dm/vpic.c index f06cccffc..8dacb45ff 100644 --- a/hypervisor/dm/vpic.c +++ b/hypervisor/dm/vpic.c @@ -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) { diff --git a/hypervisor/include/dm/vioapic.h b/hypervisor/include/dm/vioapic.h index 22633a16c..45bfea5d4 100644 --- a/hypervisor/include/dm/vioapic.h +++ b/hypervisor/include/dm/vioapic.h @@ -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 */