X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fapic.c;h=0761d6bb33e061a981e498008f6f4833a405af72;hb=4454a172129d12e97793c9c353339b85d3335af4;hp=b6c2416df860a9c9e2d1c160bcc837fae1987e17;hpb=acaadd79c597c8d5180fbfbec79c01fef3dff003;p=palacios.git diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index b6c2416..0761d6b 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -282,8 +282,14 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u static void set_apic_tpr(struct apic_state *apic, uint32_t val); +static int is_apic_bsp(struct apic_state * apic) { + return ((apic->base_addr_msr.value & 0x0000000000000100LL) != 0); +} + + -// No lcoking done + +// No locking done static void init_apic_state(struct apic_state * apic, uint32_t id) { apic->base_addr = DEFAULT_BASE_ADDR; @@ -360,10 +366,10 @@ static int read_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t * dst, v struct apic_dev_state * apic_dev = (struct apic_dev_state *)priv_data; struct apic_state * apic = &(apic_dev->apics[core->vcpu_id]); - PrintDebug(core->vm_info, core, "apic %u: core %u: MSR read\n", apic->lapic_id.val, core->vcpu_id); - - dst->value = apic->base_addr; - + PrintDebug(core->vm_info, core, "apic %u: core %u: MSR read getting %llx\n", apic->lapic_id.val, core->vcpu_id, apic->base_addr_msr.value); + + dst->value = apic->base_addr_msr.value; + return 0; } @@ -374,7 +380,7 @@ static int write_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t src, vo struct v3_mem_region * old_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, apic->base_addr); - PrintDebug(core->vm_info, core, "apic %u: core %u: MSR write\n", apic->lapic_id.val, core->vcpu_id); + PrintDebug(core->vm_info, core, "apic %u: core %u: MSR write of %llx\n", apic->lapic_id.val, core->vcpu_id, src.value); if (old_reg == NULL) { // uh oh... @@ -387,7 +393,9 @@ static int write_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t src, vo v3_delete_mem_region(core->vm_info, old_reg); - apic->base_addr = src.value; + apic->base_addr_msr.value = src.value; + + apic->base_addr = src.value & ~0xfffULL; if (v3_hook_full_mem(core->vm_info, core->vcpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, @@ -861,14 +869,18 @@ static int deliver_ipi(struct apic_state * src_apic, PrintDebug(VM_NONE, VCORE_NONE, " INIT delivery to core %u\n", dst_core->vcpu_id); - // TODO: any APIC reset on dest core (shouldn't be needed, but not sure...) + if (is_apic_bsp(dst_apic)) { + PrintError(VM_NONE, VCORE_NONE, "Attempted to INIT BSP CPU. Ignoring since I have no idea what the hell to do...\n"); + break; + } + - // Sanity check if (dst_apic->ipi_state != INIT_ST) { - PrintError(VM_NONE, VCORE_NONE, " Warning: core %u is not in INIT state (mode = %d), ignored (assuming this is the deassert)\n", - dst_core->vcpu_id, dst_apic->ipi_state); - // Only a warning, since INIT INIT SIPI is common - break; + v3_raise_barrier(dst_core->vm_info, src_apic->core); + dst_core->core_run_state = CORE_STOPPED; + dst_apic->ipi_state = INIT_ST; + v3_lower_barrier(dst_core->vm_info); + } // We transition the target core to SIPI state @@ -1872,12 +1884,16 @@ static int apic_free(struct apic_dev_state * apic_dev) { v3_remove_timer(core, apic->timer); } + v3_lock_deinit(&(apic->irq_queue.lock)); + // unhook memory } v3_unhook_msr(vm, BASE_ADDR_MSR); + v3_lock_deinit(&(apic_dev->state_lock)); + V3_Free(apic_dev); return 0; } @@ -2113,6 +2129,10 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { return -1; } + memset(apic_dev,0, + sizeof(struct apic_dev_state) + + sizeof(struct apic_state) * vm->num_cores); + apic_dev->num_apics = vm->num_cores; v3_lock_init(&(apic_dev->state_lock));