#include <palacios/vmm_rbtree.h>
-#include <palacios/vmm_profiler.h>
-
#include <palacios/vmm_direct_paging.h>
#include <palacios/vmm_ctrl_regs.h>
// This is a global pointer to the host's VMCB
-static void * host_vmcb = NULL;
+static addr_t host_vmcbs[CONFIG_MAX_CPUS] = {0};
+
+
extern void v3_stgi();
extern void v3_clgi();
ctrl_area->svm_instrs.CLGI = 1;
ctrl_area->svm_instrs.SKINIT = 1;
ctrl_area->svm_instrs.RDTSCP = 1;
+ ctrl_area->svm_instrs.CPUID = 1;
ctrl_area->svm_instrs.ICEBP = 1;
ctrl_area->svm_instrs.WBINVD = 1;
ctrl_area->svm_instrs.MONITOR = 1;
vm_info->vm_regs.rdx = 0x00000f00;
- guest_state->cr0 = 0x60000010;
+
+ guest_state->cr0 = 0x60010010; // Set the WP flag so the memory hooks work in real-mode
guest_state->cs.selector = 0xf000;
ctrl_area->instrs.IOIO_PROT = 1;
-
v3_init_svm_msr_map(vm_info);
ctrl_area->MSRPM_BASE_PA = (addr_t)V3_PAddr(vm_info->msr_map.arch_data);
ctrl_area->instrs.MSR_PROT = 1;
-
PrintDebug("Exiting on interrupts\n");
ctrl_area->guest_ctrl.V_INTR_MASKING = 1;
ctrl_area->instrs.INTR = 1;
rdtscll(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_vmcb);
+ v3_svm_launch((vmcb_t *)V3_PAddr(info->vmm_data), &(info->vm_regs), (vmcb_t *)host_vmcbs[info->cpu_id]);
rdtscll(tmp_tsc);
if ((num_exits % 5000) == 0) {
PrintDebug("SVM Exit number %d\n", num_exits);
-
-#ifdef CONFIG_PROFILE_VMM
- if (info->enable_profiler) {
- v3_print_profile(info);
- }
-#endif
}
if (v3_handle_svm_exit(info) != 0) {
PrintDebug("Host Address of rip = 0x%p\n", (void *)host_addr);
PrintDebug("Instr (15 bytes) at %p:\n", (void *)host_addr);
- PrintTraceMemDump((uchar_t *)host_addr, 15);
+ v3_dump_mem((uint8_t *)host_addr, 15);
break;
}
int v3_is_svm_capable() {
// Dinda
uint_t vm_cr_low = 0, vm_cr_high = 0;
- addr_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+ uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
v3_cpuid(CPUID_EXT_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
- PrintDebug("CPUID_EXT_FEATURE_IDS_ecx=%p\n", (void *)ecx);
+ PrintDebug("CPUID_EXT_FEATURE_IDS_ecx=0x%x\n", ecx);
if ((ecx & CPUID_EXT_FEATURE_IDS_ecx_svm_avail) == 0) {
PrintDebug("SVM Not Available\n");
v3_cpuid(CPUID_SVM_REV_AND_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
- PrintDebug("CPUID_SVM_REV_AND_FEATURE_IDS_edx=%p\n", (void *)edx);
+ PrintDebug("CPUID_SVM_REV_AND_FEATURE_IDS_edx=0x%x\n", edx);
if ((edx & CPUID_SVM_REV_AND_FEATURE_IDS_edx_svml) == 0) {
PrintDebug("SVM BIOS Disabled, not unlockable\n");
PrintDebug("SVM is available and enabled.\n");
v3_cpuid(CPUID_SVM_REV_AND_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
- PrintDebug("CPUID_SVM_REV_AND_FEATURE_IDS_eax=%p\n", (void *)eax);
- PrintDebug("CPUID_SVM_REV_AND_FEATURE_IDS_ebx=%p\n", (void *)ebx);
- PrintDebug("CPUID_SVM_REV_AND_FEATURE_IDS_ecx=%p\n", (void *)ecx);
- PrintDebug("CPUID_SVM_REV_AND_FEATURE_IDS_edx=%p\n", (void *)edx);
+ PrintDebug("CPUID_SVM_REV_AND_FEATURE_IDS_eax=0x%x\n", eax);
+ PrintDebug("CPUID_SVM_REV_AND_FEATURE_IDS_ebx=0x%x\n", ebx);
+ PrintDebug("CPUID_SVM_REV_AND_FEATURE_IDS_ecx=0x%x\n", ecx);
+ PrintDebug("CPUID_SVM_REV_AND_FEATURE_IDS_edx=0x%x\n", edx);
if ((edx & CPUID_SVM_REV_AND_FEATURE_IDS_edx_np) == 0) {
}
static int has_svm_nested_paging() {
- addr_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+ uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
v3_cpuid(CPUID_SVM_REV_AND_FEATURE_IDS, &eax, &ebx, &ecx, &edx);
}
-
-void v3_init_SVM(struct v3_ctrl_ops * vmm_ops) {
+void v3_init_svm_cpu(int cpu_id) {
reg_ex_t msr;
- extern v3_cpu_arch_t v3_cpu_type;
+ extern v3_cpu_arch_t v3_cpu_types[];
// Enable SVM on the CPU
v3_get_msr(EFER_MSR, &(msr.e_reg.high), &(msr.e_reg.low));
PrintDebug("SVM Enabled\n");
// Setup the host state save area
- host_vmcb = V3_AllocPages(4);
+ host_vmcbs[cpu_id] = (addr_t)V3_AllocPages(4);
/* 64-BIT-ISSUE */
// msr.e_reg.high = 0;
//msr.e_reg.low = (uint_t)host_vmcb;
- msr.r_reg = (addr_t)host_vmcb;
+ msr.r_reg = host_vmcbs[cpu_id];
- PrintDebug("Host State being saved at %p\n", (void *)(addr_t)host_vmcb);
+ PrintDebug("Host State being saved at %p\n", (void *)host_vmcbs[cpu_id]);
v3_set_msr(SVM_VM_HSAVE_PA_MSR, msr.e_reg.high, msr.e_reg.low);
-
-
if (has_svm_nested_paging() == 1) {
- v3_cpu_type = V3_SVM_REV3_CPU;
+ v3_cpu_types[cpu_id] = V3_SVM_REV3_CPU;
} else {
- v3_cpu_type = V3_SVM_CPU;
+ v3_cpu_types[cpu_id] = V3_SVM_CPU;
}
+}
+
+
+void v3_init_svm_hooks(struct v3_ctrl_ops * vmm_ops) {
// Setup the SVM specific vmm operations
vmm_ops->init_guest = &init_svm_guest;
vmsave
"rdtsc ; "
: "=D"(start_hi), "=S"(start_lo), "=a"(end_lo),"=d"(end_hi)
- : "c"(host_vmcb), "0"(0), "1"(0), "2"(0), "3"(0)
+ : "c"(host_vmcb[cpu_id]), "0"(0), "1"(0), "2"(0), "3"(0)
);
start = start_hi;
"movq %%rcx, %%rax ; "
vmload
"rdtsc ; "
- : "=D"(start_hi), "=S"(start_lo), "=a"(end_lo),d"(end_hi)
- : "c"(host_vmcb), "0"(0), "1"(0), "2"(0), "3"(0)
+ : "=D"(start_hi), "=S"(start_lo), "=a"(end_lo),"=d"(end_hi)
+ : "c"(host_vmcb[cpu_id]), "0"(0), "1"(0), "2"(0), "3"(0)
);
start = start_hi;