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 locking done
static void init_apic_state(struct apic_state * apic, uint32_t id) {
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;
}
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...
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,
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
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));