diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 400d31de74..881a9a832b 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -41,6 +41,9 @@ static int opt_vpid_enabled = 1; boolean_param("vpid", opt_vpid_enabled); +static int opt_unrestricted_guest_enabled = 1; +boolean_param("unrestricted_guest", opt_unrestricted_guest_enabled); + /* Dynamic (run-time adjusted) execution control flags. */ u32 vmx_pin_based_exec_control __read_mostly; u32 vmx_cpu_based_exec_control __read_mostly; @@ -68,6 +71,7 @@ static void __init vmx_display_features(void) P(cpu_has_vmx_vpid, "Virtual-Processor Identifiers (VPID)"); P(cpu_has_vmx_vnmi, "Virtual NMI"); P(cpu_has_vmx_msr_bitmap, "MSR direct-access bitmap"); + P(cpu_has_vmx_unrestricted_guest, "Unrestricted Guest"); #undef P if ( !printed ) @@ -139,6 +143,9 @@ static void vmx_init_vmcs_config(void) SECONDARY_EXEC_ENABLE_EPT); if ( opt_vpid_enabled ) opt |= SECONDARY_EXEC_ENABLE_VPID; + if ( opt_unrestricted_guest_enabled ) + opt |= SECONDARY_EXEC_UNRESTRICTED_GUEST; + _vmx_secondary_exec_control = adjust_vmx_controls( min, opt, MSR_IA32_VMX_PROCBASED_CTLS2); } @@ -156,7 +163,9 @@ static void vmx_init_vmcs_config(void) if ( must_be_one & (CPU_BASED_INVLPG_EXITING | CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING) ) - _vmx_secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT; + _vmx_secondary_exec_control &= + ~(SECONDARY_EXEC_ENABLE_EPT | + SECONDARY_EXEC_UNRESTRICTED_GUEST); } #if defined(__i386__) @@ -532,7 +541,9 @@ static int construct_vmcs(struct vcpu *v) } else { - v->arch.hvm_vmx.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT; + v->arch.hvm_vmx.secondary_exec_control &= + ~(SECONDARY_EXEC_ENABLE_EPT | + SECONDARY_EXEC_UNRESTRICTED_GUEST); vmx_vmexit_control &= ~(VM_EXIT_SAVE_GUEST_PAT | VM_EXIT_LOAD_HOST_PAT); vmx_vmentry_control &= ~VM_ENTRY_LOAD_GUEST_PAT; diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index dddd9ec108..e256f51de6 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -1062,8 +1062,10 @@ static void vmx_update_guest_cr(struct vcpu *v, unsigned int cr) { case 0: { int realmode; - unsigned long hw_cr0_mask = - X86_CR0_NE | X86_CR0_PG | X86_CR0_PE; + unsigned long hw_cr0_mask = X86_CR0_NE; + + if ( !vmx_unrestricted_guest(v) ) + hw_cr0_mask |= X86_CR0_PG | X86_CR0_PE; if ( paging_mode_shadow(v->domain) ) hw_cr0_mask |= X86_CR0_WP; @@ -1091,7 +1093,9 @@ static void vmx_update_guest_cr(struct vcpu *v, unsigned int cr) } realmode = !(v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE); - if ( realmode != v->arch.hvm_vmx.vmx_realmode ) + + if ( (!vmx_unrestricted_guest(v)) && + (realmode != v->arch.hvm_vmx.vmx_realmode) ) { enum x86_segment s; struct segment_register reg[x86_seg_tr + 1]; @@ -1431,15 +1435,10 @@ void start_vmx(void) } if ( cpu_has_vmx_ept ) - { - printk("VMX: EPT is available.\n"); vmx_function_table.hap_supported = 1; - } if ( cpu_has_vmx_vpid ) { - printk("VMX: VPID is available.\n"); - vpid_bitmap = xmalloc_array( unsigned long, BITS_TO_LONGS(VPID_BITMAP_SIZE)); BUG_ON(vpid_bitmap == NULL); diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h index 80640e0d5a..c2b468e664 100644 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -170,6 +170,7 @@ extern u32 vmx_vmentry_control; #define SECONDARY_EXEC_ENABLE_EPT 0x00000002 #define SECONDARY_EXEC_ENABLE_VPID 0x00000020 #define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 +#define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080 extern u32 vmx_secondary_exec_control; extern bool_t cpu_has_vmx_ins_outs_instr_info; @@ -194,6 +195,11 @@ extern bool_t cpu_has_vmx_ins_outs_instr_info; (vmx_cpu_based_exec_control & CPU_BASED_MONITOR_TRAP_FLAG) #define cpu_has_vmx_pat \ (vmx_vmentry_control & VM_ENTRY_LOAD_GUEST_PAT) +#define cpu_has_vmx_unrestricted_guest \ + (vmx_secondary_exec_control & SECONDARY_EXEC_UNRESTRICTED_GUEST) +#define vmx_unrestricted_guest(v) \ + ((v)->arch.hvm_vmx.secondary_exec_control & \ + SECONDARY_EXEC_UNRESTRICTED_GUEST) /* GUEST_INTERRUPTIBILITY_INFO flags. */ #define VMX_INTR_SHADOW_STI 0x00000001