#include <palacios/vmm_direct_paging.h>
#include <palacios/vmm_ctrl_regs.h>
-#include <palacios/vmm_config.h>
#include <palacios/svm_io.h>
#include <palacios/vmm_sprintf.h>
+uint32_t v3_last_exit;
+
// This is a global pointer to the host's VMCB
static addr_t host_vmcbs[CONFIG_MAX_CPUS] = { [0 ... CONFIG_MAX_CPUS - 1] = 0};
}
-static int init_svm_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
-
-
- v3_pre_config_guest(info, config_ptr);
+int v3_init_svm_vmcb(struct guest_info * info, v3_vm_class_t vm_class) {
PrintDebug("Allocating VMCB\n");
info->vmm_data = (void*)Allocate_VMCB();
-
- PrintDebug("Initializing VMCB (addr=%p)\n", (void *)info->vmm_data);
- Init_VMCB_BIOS((vmcb_t*)(info->vmm_data), info);
-
- v3_post_config_guest(info, config_ptr);
+
+ if (vm_class == V3_PC_VM) {
+ PrintDebug("Initializing VMCB (addr=%p)\n", (void *)info->vmm_data);
+ Init_VMCB_BIOS((vmcb_t*)(info->vmm_data), info);
+ } else {
+ PrintError("Invalid VM class\n");
+ return -1;
+ }
return 0;
}
-static int update_irq_state_atomic(struct guest_info * info) {
+static int update_irq_exit_state(struct guest_info * info) {
vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
if ((info->intr_state.irq_pending == 1) && (guest_ctrl->guest_ctrl.V_IRQ == 0)) {
// Interrupt was taken fully vectored
info->intr_state.irq_started = 0;
- } else {
+ } else if ((info->intr_state.irq_started == 1) && (guest_ctrl->exit_int_info.valid == 1)) {
#ifdef CONFIG_DEBUG_INTERRUPTS
PrintDebug("EXIT INT INFO is set (vec=%d)\n", guest_ctrl->exit_int_info.vector);
#endif
}
-static int update_irq_state(struct guest_info * info) {
+static int update_irq_entry_state(struct guest_info * info) {
vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
+
+ if (info->intr_state.irq_pending == 0) {
+ guest_ctrl->guest_ctrl.V_IRQ = 0;
+ guest_ctrl->guest_ctrl.V_INTR_VECTOR = 0;
+ }
+
if (v3_excp_pending(info)) {
uint_t excp = v3_get_excp_number(info);
guest_ctrl->EVENTINJ.valid = 1;
-
-
#ifdef CONFIG_DEBUG_INTERRUPTS
PrintDebug("<%d> Injecting Exception %d (CR2=%p) (EIP=%p)\n",
(int)info->num_exits,
#endif
v3_injecting_excp(info, excp);
-
-
} else if (info->intr_state.irq_started == 1) {
#ifdef CONFIG_DEBUG_INTERRUPTS
PrintDebug("IRQ pending from previous injection\n");
guest_state->rax = info->vm_regs.rax;
guest_state->rip = info->rip;
guest_state->rsp = info->vm_regs.rsp;
+
+#ifdef CONFIG_SYMBIOTIC
+ if (info->sym_state.sym_call_active == 0) {
+ update_irq_entry_state(info);
+ }
+#else
+ update_irq_entry_state(info);
+#endif
+
+
/* ** */
/*
rdtscll(info->time_state.cached_host_tsc);
- // guest_ctrl->TSC_OFFSET = info->time_state.guest_tsc - info->time_state.cached_host_tsc;
+ guest_ctrl->TSC_OFFSET = info->time_state.guest_tsc - info->time_state.cached_host_tsc;
v3_svm_launch((vmcb_t *)V3_PAddr(info->vmm_data), &(info->vm_regs), (vmcb_t *)host_vmcbs[info->cpu_id]);
+
+ v3_last_exit = (uint32_t)(guest_ctrl->exit_code);
+
+ // v3_print_cond("SVM Returned: Exit Code: %x\n", (uint32_t)(guest_ctrl->exit_code));
+
rdtscll(tmp_tsc);
//PrintDebug("SVM Returned\n");
v3_update_time(info, tmp_tsc - info->time_state.cached_host_tsc);
-#ifdef CONFIG_SYMBIOTIC
- if (info->sym_state.sym_call_active == 0) {
- update_irq_state_atomic(info);
- }
-#else
- update_irq_state_atomic(info);
-#endif
// Save Guest state from VMCB
info->rip = guest_state->rip;
exit_info2 = guest_ctrl->exit_info2;
+#ifdef CONFIG_SYMBIOTIC
+ if (info->sym_state.sym_call_active == 0) {
+ update_irq_exit_state(info);
+ }
+#else
+ update_irq_exit_state(info);
+#endif
+
+
// reenable global interrupts after vm exit
v3_stgi();
return -1;
}
-#ifdef CONFIG_SYMBIOTIC
- if (info->sym_state.sym_call_active == 0) {
- update_irq_state(info);
- }
-#else
- update_irq_state(info);
-#endif
return 0;
}
-static int start_svm_guest(struct guest_info *info) {
+int v3_start_svm_guest(struct guest_info *info) {
// vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
// vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
break;
}
+/*
if ((info->num_exits % 5000) == 0) {
V3_Print("SVM Exit number %d\n", (uint32_t)info->num_exits);
}
-
-
+*/
-
}
return 0;
}
}
-void v3_init_svm_hooks(struct v3_ctrl_ops * vmm_ops) {
-
- // Setup the SVM specific vmm operations
- vmm_ops->init_guest = &init_svm_guest;
- vmm_ops->start_guest = &start_svm_guest;
- vmm_ops->has_nested_paging = &has_svm_nested_paging;
-
- return;
-}