#include <palacios/vmm_barrier.h>
#include <palacios/vmm_debug.h>
+#include <palacios/vmm_perftune.h>
#ifdef V3_CONFIG_CHECKPOINT
#include <palacios/vmm_sprintf.h>
+#ifdef V3_CONFIG_MEM_TRACK
+#include <palacios/vmm_mem_track.h>
+#endif
+
+#ifdef V3_CONFIG_TM_FUNC
+#include <extensions/trans_mem.h>
+#endif
#ifndef V3_CONFIG_DEBUG_SVM
#undef PrintDebug
#endif
+
uint32_t v3_last_exit;
// This is a global pointer to the host's VMCB
ctrl_area->exceptions.nmi = 1;
*/
+
+#ifdef V3_CONFIG_TM_FUNC
+ v3_tm_set_excp_intercepts(ctrl_area);
+#endif
ctrl_area->instrs.NMI = 1;
PrintDebug(core->vm_info, core, "Created\n");
core->ctrl_regs.cr0 |= 0x80000000;
- core->ctrl_regs.cr3 = core->direct_map_pt;
+
+ v3_activate_passthrough_pt(core);
ctrl_area->cr_reads.cr0 = 1;
ctrl_area->cr_writes.cr0 = 1;
- //ctrl_area->cr_reads.cr4 = 1;
+ //intercept cr4 read so shadow pager can use PAE independently of guest
+ ctrl_area->cr_reads.cr4 = 1;
ctrl_area->cr_writes.cr4 = 1;
ctrl_area->cr_reads.cr3 = 1;
ctrl_area->cr_writes.cr3 = 1;
// Conditionally yield the CPU if the timeslice has expired
v3_schedule(info);
+#ifdef V3_CONFIG_MEM_TRACK
+ v3_mem_track_entry(info);
+#endif
+
// Update timer devices after being in the VM before doing
// IRQ updates, so that any interrupts they raise get seen
// immediately.
v3_advance_time(info, NULL);
v3_update_timers(info);
+
// disable global interrupts for vm state transition
v3_clgi();
guest_state->rip = info->rip;
guest_state->rsp = info->vm_regs.rsp;
+ V3_FP_ENTRY_RESTORE(info);
+
#ifdef V3_CONFIG_SYMCALL
if (info->sym_core_state.symcall_state.sym_call_active == 0) {
update_irq_entry_state(info);
update_irq_entry_state(info);
#endif
+#ifdef V3_CONFIG_TM_FUNC
+ v3_tm_check_intr_state(info, guest_ctrl, guest_state);
+#endif
+
/* ** */
info->num_exits++;
+ V3_FP_EXIT_SAVE(info);
+
// Save Guest state from VMCB
info->rip = guest_state->rip;
info->vm_regs.rsp = guest_state->rsp;
// reenable global interrupts after vm exit
v3_stgi();
+
// Conditionally yield the CPU if the timeslice has expired
v3_schedule(info);
v3_advance_time(info, NULL);
v3_update_timers(info);
+
{
int ret = v3_handle_svm_exit(info, exit_code, exit_info1, exit_info2);
v3_handle_timeouts(info, guest_cycles);
}
+#ifdef V3_CONFIG_MEM_TRACK
+ v3_mem_track_exit(info);
+#endif
+
return 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);
-
+
+ V3_NO_WORK(info);
+
while (info->core_run_state == CORE_STOPPED) {
if (info->vm_info->run_state == VM_STOPPED) {
return 0;
}
- v3_yield(info,-1);
+ V3_STILL_NO_WORK(info);
+
//PrintDebug(info->vm_info, info, "SVM core %u: still waiting for INIT\n", info->vcpu_id);
}
+
+ V3_HAVE_WORK_AGAIN(info);
PrintDebug(info->vm_info, info, "SVM core %u(on %u) initialized\n", info->vcpu_id, info->pcpu_id);