X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmcs.c;h=8fb408072e92c16d53e52a9f1c800a3fc1d875db;hb=88648ddca6003a438826e7d86e28a2ba7b5bfcac;hp=04b8bf9afbc10d98a2226591f0db6279da6cc30c;hpb=7d780533980c895368aa404cbdd54f7bc2d91b40;p=palacios.git diff --git a/palacios/src/palacios/vmcs.c b/palacios/src/palacios/vmcs.c index 04b8bf9..8fb4080 100644 --- a/palacios/src/palacios/vmcs.c +++ b/palacios/src/palacios/vmcs.c @@ -204,6 +204,10 @@ int v3_update_vmcs_ctrl_fields(struct guest_info * info) { vmx_ret |= check_vmcs_write(VMCS_ENTRY_CTRLS, arch_data->entry_ctrls.value); vmx_ret |= check_vmcs_write(VMCS_EXCP_BITMAP, arch_data->excp_bmap.value); + if (info->shdw_pg_mode == NESTED_PAGING) { + vmx_ret |= check_vmcs_write(VMCS_EPT_PTR, info->direct_map_pt); + } + return vmx_ret; } @@ -227,17 +231,11 @@ int v3_vmx_save_vmcs(struct guest_info * info) { check_vmcs_read(VMCS_GUEST_DR7, &(info->dbg_regs.dr7)); check_vmcs_read(VMCS_GUEST_RFLAGS, &(info->ctrl_regs.rflags)); - if (((struct vmx_data *)info->vmm_data)->ia32e_avail) { + #ifdef __V3_64BIT__ - check_vmcs_read(VMCS_GUEST_EFER, &(info->ctrl_regs.efer)); -#else - uint32_t hi, lo; - check_vmcs_read(VMCS_GUEST_EFER, &hi); - check_vmcs_read(VMCS_GUEST_EFER_HIGH, &lo); - info->ctrl_regs.efer = ((uint64_t) hi << 32) | lo; + check_vmcs_read(VMCS_GUEST_EFER, &(info->ctrl_regs.efer)); #endif - } - + error = v3_read_vmcs_segments(&(info->segments)); return error; @@ -260,9 +258,13 @@ int v3_vmx_restore_vmcs(struct guest_info * info) { check_vmcs_write(VMCS_GUEST_RFLAGS, info->ctrl_regs.rflags); - if (((struct vmx_data *)info->vmm_data)->ia32e_avail) { - check_vmcs_write(VMCS_GUEST_EFER, info->ctrl_regs.efer); - } +#ifdef __V3_64BIT__ + check_vmcs_write(VMCS_GUEST_EFER, info->ctrl_regs.efer); + check_vmcs_write(VMCS_ENTRY_CTRLS, vmx_info->entry_ctrls.value); +#endif + + + error = v3_write_vmcs_segments(&(info->segments)); @@ -275,8 +277,12 @@ int v3_vmx_restore_vmcs(struct guest_info * info) { int v3_update_vmcs_host_state(struct guest_info * info) { int vmx_ret = 0; addr_t tmp; - struct vmx_data * arch_data = (struct vmx_data *)(info->vmm_data); struct v3_msr tmp_msr; + addr_t gdtr_base; + struct { + uint16_t selector; + addr_t base; + } __attribute__((packed)) tmp_seg; #ifdef __V3_64BIT__ __asm__ __volatile__ ( "movq %%cr0, %0; " @@ -320,22 +326,48 @@ int v3_update_vmcs_host_state(struct guest_info * info) { vmx_ret |= check_vmcs_write(VMCS_HOST_CR4, tmp); + __asm__ __volatile__( + "sgdt (%0);" + : + : "q"(&tmp_seg) + : "memory" + ); + gdtr_base = tmp_seg.base; + vmx_ret |= check_vmcs_write(VMCS_HOST_GDTR_BASE, tmp_seg.base); + + __asm__ __volatile__( + "sidt (%0);" + : + : "q"(&tmp_seg) + : "memory" + ); + vmx_ret |= check_vmcs_write(VMCS_HOST_IDTR_BASE, tmp_seg.base); + + __asm__ __volatile__( + "str (%0);" + : + : "q"(&tmp_seg) + : "memory" + ); + vmx_ret |= check_vmcs_write(VMCS_HOST_TR_SELECTOR, tmp_seg.selector); + + /* The GDTR *index* is bits 3-15 of the selector. */ + { + struct tss_descriptor * desc = NULL; + desc = (struct tss_descriptor *)(gdtr_base + (8 * (tmp_seg.selector >> 3))); + + tmp_seg.base = ((desc->base1) | + (desc->base2 << 16) | + (desc->base3 << 24) | +#ifdef __V3_64BIT__ + ((uint64_t)desc->base4 << 32) +#else + (0) +#endif + ); - vmx_ret |= check_vmcs_write(VMCS_HOST_GDTR_BASE, arch_data->host_state.gdtr.base); - vmx_ret |= check_vmcs_write(VMCS_HOST_IDTR_BASE, arch_data->host_state.idtr.base); - vmx_ret |= check_vmcs_write(VMCS_HOST_TR_BASE, arch_data->host_state.tr.base); - -#define FS_BASE_MSR 0xc0000100 -#define GS_BASE_MSR 0xc0000101 - - // FS.BASE MSR - v3_get_msr(FS_BASE_MSR, &(tmp_msr.hi), &(tmp_msr.lo)); - vmx_ret |= check_vmcs_write(VMCS_HOST_FS_BASE, tmp_msr.value); - - // GS.BASE MSR - v3_get_msr(GS_BASE_MSR, &(tmp_msr.hi), &(tmp_msr.lo)); - vmx_ret |= check_vmcs_write(VMCS_HOST_GS_BASE, tmp_msr.value); - + vmx_ret |= check_vmcs_write(VMCS_HOST_TR_BASE, tmp_seg.base); + } #ifdef __V3_64BIT__ @@ -416,12 +448,14 @@ int v3_update_vmcs_host_state(struct guest_info * info) { #endif vmx_ret |= check_vmcs_write(VMCS_HOST_GS_SELECTOR, tmp); - vmx_ret |= check_vmcs_write(VMCS_HOST_TR_SELECTOR, arch_data->host_state.tr.selector); - #define SYSENTER_CS_MSR 0x00000174 #define SYSENTER_ESP_MSR 0x00000175 #define SYSENTER_EIP_MSR 0x00000176 +#define FS_BASE_MSR 0xc0000100 +#define GS_BASE_MSR 0xc0000101 +#define EFER_MSR 0xc0000080 + // SYSENTER CS MSR v3_get_msr(SYSENTER_CS_MSR, &(tmp_msr.hi), &(tmp_msr.lo)); @@ -435,6 +469,41 @@ int v3_update_vmcs_host_state(struct guest_info * info) { v3_get_msr(SYSENTER_EIP_MSR, &(tmp_msr.hi), &(tmp_msr.lo)); vmx_ret |= check_vmcs_write(VMCS_HOST_SYSENTER_EIP, tmp_msr.value); + + // FS.BASE MSR + v3_get_msr(FS_BASE_MSR, &(tmp_msr.hi), &(tmp_msr.lo)); + vmx_ret |= check_vmcs_write(VMCS_HOST_FS_BASE, tmp_msr.value); + + // GS.BASE MSR + v3_get_msr(GS_BASE_MSR, &(tmp_msr.hi), &(tmp_msr.lo)); + vmx_ret |= check_vmcs_write(VMCS_HOST_GS_BASE, tmp_msr.value); + + + // EFER + v3_get_msr(EFER_MSR, &(tmp_msr.hi), &(tmp_msr.lo)); + vmx_ret |= check_vmcs_write(VMCS_HOST_EFER, tmp_msr.value); + + // PERF GLOBAL CONTROL + + // PAT + + + // save STAR, LSTAR, FMASK, KERNEL_GS_BASE MSRs in MSR load/store area + { + struct vmx_data * vmx_state = (struct vmx_data *)info->vmm_data; + struct vmcs_msr_save_area * msr_entries = vmx_state->msr_area; + + + v3_get_msr(IA32_STAR_MSR, &(msr_entries->host_star.hi), &(msr_entries->host_star.lo)); + v3_get_msr(IA32_LSTAR_MSR, &(msr_entries->host_lstar.hi), &(msr_entries->host_lstar.lo)); + v3_get_msr(IA32_FMASK_MSR, &(msr_entries->host_fmask.hi), &(msr_entries->host_fmask.lo)); + v3_get_msr(IA32_KERN_GS_BASE_MSR, &(msr_entries->host_kern_gs.hi), &(msr_entries->host_kern_gs.lo)); + } + + + + + return vmx_ret; }