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) {
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
PrintDebug(info->vm_info, info, "Starting SVM core %u (on logical core %u)\n", info->vcpu_id, info->pcpu_id);
- if (info->vcpu_id == 0) {
- info->core_run_state = CORE_RUNNING;
- } else {
- PrintDebug(info->vm_info, info, "SVM core %u (on %u): Waiting for core initialization\n", info->vcpu_id, info->pcpu_id);
+ while (1) {
- while (info->core_run_state == CORE_STOPPED) {
-
- if (info->vm_info->run_state == VM_STOPPED) {
- // The VM was stopped before this core was initialized.
- return 0;
- }
+ if (info->core_run_state == CORE_STOPPED) {
- v3_yield(info,-1);
- //PrintDebug(info->vm_info, info, "SVM core %u: still waiting for INIT\n", info->vcpu_id);
+ if (info->vcpu_id == 0) {
+ info->core_run_state = CORE_RUNNING;
+ } else {
+ PrintDebug(info->vm_info, info, "SVM core %u (on %u): Waiting for core initialization\n", info->vcpu_id, info->pcpu_id);
+
+ while (info->core_run_state == CORE_STOPPED) {
+
+ if (info->vm_info->run_state == VM_STOPPED) {
+ // The VM was stopped before this core was initialized.
+ return 0;
+ }
+
+ v3_yield(info,-1);
+ //PrintDebug(info->vm_info, info, "SVM core %u: still waiting for INIT\n", info->vcpu_id);
+ }
+
+ PrintDebug(info->vm_info, info, "SVM core %u(on %u) initialized\n", info->vcpu_id, info->pcpu_id);
+
+ // We'll be paranoid about race conditions here
+ v3_wait_at_barrier(info);
+ }
+
+ PrintDebug(info->vm_info, info, "SVM core %u(on %u): I am starting at CS=0x%x (base=0x%p, limit=0x%x), RIP=0x%p\n",
+ info->vcpu_id, info->pcpu_id,
+ info->segments.cs.selector, (void *)(info->segments.cs.base),
+ info->segments.cs.limit, (void *)(info->rip));
+
+
+
+ PrintDebug(info->vm_info, info, "SVM core %u: Launching SVM VM (vmcb=%p) (on cpu %u)\n",
+ info->vcpu_id, (void *)info->vmm_data, info->pcpu_id);
+ //PrintDebugVMCB((vmcb_t*)(info->vmm_data));
+
+ v3_start_time(info);
}
-
- PrintDebug(info->vm_info, info, "SVM core %u(on %u) initialized\n", info->vcpu_id, info->pcpu_id);
-
- // We'll be paranoid about race conditions here
- v3_wait_at_barrier(info);
- }
-
- PrintDebug(info->vm_info, info, "SVM core %u(on %u): I am starting at CS=0x%x (base=0x%p, limit=0x%x), RIP=0x%p\n",
- info->vcpu_id, info->pcpu_id,
- info->segments.cs.selector, (void *)(info->segments.cs.base),
- info->segments.cs.limit, (void *)(info->rip));
-
-
-
- PrintDebug(info->vm_info, info, "SVM core %u: Launching SVM VM (vmcb=%p) (on cpu %u)\n",
- info->vcpu_id, (void *)info->vmm_data, info->pcpu_id);
- //PrintDebugVMCB((vmcb_t*)(info->vmm_data));
-
- v3_start_time(info);
+
+ if (info->vm_info->run_state == VM_STOPPED) {
+ info->core_run_state = CORE_STOPPED;
+ break;
+ }
+
#ifdef V3_CONFIG_PMU_TELEMETRY
- v3_pmu_telemetry_start(info);
+ v3_pmu_telemetry_start(info);
#endif
-
+
#ifdef V3_CONFIG_PWRSTAT_TELEMETRY
- v3_pwrstat_telemetry_start(info);
+ v3_pwrstat_telemetry_start(info);
#endif
-
- while (1) {
-
- if (info->vm_info->run_state == VM_STOPPED) {
- info->core_run_state = CORE_STOPPED;
- break;
- }
if (v3_svm_enter(info) == -1) {
vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
v3_dump_mem((uint8_t *)host_addr, 15);
v3_print_stack(info);
-
+
break;
}
-
+
v3_wait_at_barrier(info);
-
+
if (info->vm_info->run_state == VM_STOPPED) {
info->core_run_state = CORE_STOPPED;
PrintDebug(info->vm_info, info, "Starting VMX core %u\n", info->vcpu_id);
- if (info->vcpu_id == 0) {
- info->core_run_state = CORE_RUNNING;
- } else {
-
- PrintDebug(info->vm_info, info, "VMX core %u: Waiting for core initialization\n", info->vcpu_id);
-
- while (info->core_run_state == CORE_STOPPED) {
-
+ while (1) {
+ if (info->core_run_state == CORE_STOPPED) {
+ if (info->vcpu_id == 0) {
+ info->core_run_state = CORE_RUNNING;
+ } else {
+
+ PrintDebug(info->vm_info, info, "VMX core %u: Waiting for core initialization\n", info->vcpu_id);
+
+ while (info->core_run_state == CORE_STOPPED) {
+
+ if (info->vm_info->run_state == VM_STOPPED) {
+ // The VM was stopped before this core was initialized.
+ return 0;
+ }
+
+ v3_yield(info,-1);
+ //PrintDebug(info->vm_info, info, "VMX core %u: still waiting for INIT\n",info->vcpu_id);
+ }
+
+ PrintDebug(info->vm_info, info, "VMX core %u initialized\n", info->vcpu_id);
+
+ // We'll be paranoid about race conditions here
+ v3_wait_at_barrier(info);
+ }
+
+
+ PrintDebug(info->vm_info, info, "VMX core %u: I am starting at CS=0x%x (base=0x%p, limit=0x%x), RIP=0x%p\n",
+ info->vcpu_id, info->segments.cs.selector, (void *)(info->segments.cs.base),
+ info->segments.cs.limit, (void *)(info->rip));
+
+
+ PrintDebug(info->vm_info, info, "VMX core %u: Launching VMX VM on logical core %u\n", info->vcpu_id, info->pcpu_id);
+
+ v3_start_time(info);
+
+
if (info->vm_info->run_state == VM_STOPPED) {
- // The VM was stopped before this core was initialized.
- return 0;
+ info->core_run_state = CORE_STOPPED;
+ break;
}
-
- v3_yield(info,-1);
- //PrintDebug(info->vm_info, info, "VMX core %u: still waiting for INIT\n",info->vcpu_id);
- }
+ }
+
- PrintDebug(info->vm_info, info, "VMX core %u initialized\n", info->vcpu_id);
-
- // We'll be paranoid about race conditions here
- v3_wait_at_barrier(info);
- }
-
-
- PrintDebug(info->vm_info, info, "VMX core %u: I am starting at CS=0x%x (base=0x%p, limit=0x%x), RIP=0x%p\n",
- info->vcpu_id, info->segments.cs.selector, (void *)(info->segments.cs.base),
- info->segments.cs.limit, (void *)(info->rip));
-
-
- PrintDebug(info->vm_info, info, "VMX core %u: Launching VMX VM on logical core %u\n", info->vcpu_id, info->pcpu_id);
-
- v3_start_time(info);
-
#ifdef V3_CONFIG_PMU_TELEMETRY
- v3_pmu_telemetry_start(info);
+ v3_pmu_telemetry_start(info);
#endif
-
+
#ifdef V3_CONFIG_PWRSTAT_TELEMETRY
- v3_pwrstat_telemetry_start(info);
+ v3_pwrstat_telemetry_start(info);
#endif
-
- while (1) {
-
- if (info->vm_info->run_state == VM_STOPPED) {
- info->core_run_state = CORE_STOPPED;
- break;
- }
-
+
+
if (v3_vmx_enter(info) == -1) {
-
+
addr_t host_addr;
addr_t linear_addr = 0;