ia64/xen-unstable

changeset 19665:bf37a89269bf

x86 vmx: Unrestricted guest (realmode) support

It allows fully virtualized guests to run real mode and unpaged mode
code natively in the VMX mode when EPT is turned on. With the
unrestricted guest there is no need to emulate the guest real mode
code in the vm86 container or in the emulator. Also the guest big real
mode code works like native.

This patch enhances Xen to use the unrestricted guest feature if
available on the processor. It also adds a new xen parameter to
disable the unrestricted guest feature at the boot time.

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 28 09:51:43 2009 +0100 (2009-05-28)
parents 878e4c128991
children 8bf58f09e45a
files xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/vmx/vmcs.h
line diff
     1.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Thu May 28 09:41:59 2009 +0100
     1.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Thu May 28 09:51:43 2009 +0100
     1.3 @@ -41,6 +41,9 @@
     1.4  static int opt_vpid_enabled = 1;
     1.5  boolean_param("vpid", opt_vpid_enabled);
     1.6  
     1.7 +static int opt_unrestricted_guest_enabled = 1;
     1.8 +boolean_param("unrestricted_guest", opt_unrestricted_guest_enabled);
     1.9 +
    1.10  /* Dynamic (run-time adjusted) execution control flags. */
    1.11  u32 vmx_pin_based_exec_control __read_mostly;
    1.12  u32 vmx_cpu_based_exec_control __read_mostly;
    1.13 @@ -68,6 +71,7 @@ static void __init vmx_display_features(
    1.14      P(cpu_has_vmx_vpid, "Virtual-Processor Identifiers (VPID)");
    1.15      P(cpu_has_vmx_vnmi, "Virtual NMI");
    1.16      P(cpu_has_vmx_msr_bitmap, "MSR direct-access bitmap");
    1.17 +    P(cpu_has_vmx_unrestricted_guest, "Unrestricted Guest");
    1.18  #undef P
    1.19  
    1.20      if ( !printed )
    1.21 @@ -139,6 +143,9 @@ static void vmx_init_vmcs_config(void)
    1.22                 SECONDARY_EXEC_ENABLE_EPT);
    1.23          if ( opt_vpid_enabled )
    1.24              opt |= SECONDARY_EXEC_ENABLE_VPID;
    1.25 +        if ( opt_unrestricted_guest_enabled )
    1.26 +            opt |= SECONDARY_EXEC_UNRESTRICTED_GUEST;
    1.27 +
    1.28          _vmx_secondary_exec_control = adjust_vmx_controls(
    1.29              min, opt, MSR_IA32_VMX_PROCBASED_CTLS2);
    1.30      }
    1.31 @@ -156,7 +163,9 @@ static void vmx_init_vmcs_config(void)
    1.32          if ( must_be_one & (CPU_BASED_INVLPG_EXITING |
    1.33                              CPU_BASED_CR3_LOAD_EXITING |
    1.34                              CPU_BASED_CR3_STORE_EXITING) )
    1.35 -            _vmx_secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
    1.36 +            _vmx_secondary_exec_control &=
    1.37 +                ~(SECONDARY_EXEC_ENABLE_EPT |
    1.38 +                  SECONDARY_EXEC_UNRESTRICTED_GUEST);
    1.39      }
    1.40  
    1.41  #if defined(__i386__)
    1.42 @@ -532,7 +541,9 @@ static int construct_vmcs(struct vcpu *v
    1.43      }
    1.44      else
    1.45      {
    1.46 -        v->arch.hvm_vmx.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
    1.47 +        v->arch.hvm_vmx.secondary_exec_control &= 
    1.48 +            ~(SECONDARY_EXEC_ENABLE_EPT | 
    1.49 +              SECONDARY_EXEC_UNRESTRICTED_GUEST);
    1.50          vmx_vmexit_control &= ~(VM_EXIT_SAVE_GUEST_PAT |
    1.51                                  VM_EXIT_LOAD_HOST_PAT);
    1.52          vmx_vmentry_control &= ~VM_ENTRY_LOAD_GUEST_PAT;
     2.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu May 28 09:41:59 2009 +0100
     2.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu May 28 09:51:43 2009 +0100
     2.3 @@ -1062,8 +1062,10 @@ static void vmx_update_guest_cr(struct v
     2.4      {
     2.5      case 0: {
     2.6          int realmode;
     2.7 -        unsigned long hw_cr0_mask =
     2.8 -            X86_CR0_NE | X86_CR0_PG | X86_CR0_PE;
     2.9 +        unsigned long hw_cr0_mask = X86_CR0_NE;
    2.10 +
    2.11 +        if ( !vmx_unrestricted_guest(v) )
    2.12 +            hw_cr0_mask |= X86_CR0_PG | X86_CR0_PE;
    2.13  
    2.14          if ( paging_mode_shadow(v->domain) )
    2.15             hw_cr0_mask |= X86_CR0_WP;
    2.16 @@ -1091,7 +1093,9 @@ static void vmx_update_guest_cr(struct v
    2.17          }
    2.18  
    2.19          realmode = !(v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE); 
    2.20 -        if ( realmode != v->arch.hvm_vmx.vmx_realmode )
    2.21 +
    2.22 +        if ( (!vmx_unrestricted_guest(v)) &&
    2.23 +             (realmode != v->arch.hvm_vmx.vmx_realmode) )
    2.24          {
    2.25              enum x86_segment s; 
    2.26              struct segment_register reg[x86_seg_tr + 1];
    2.27 @@ -1431,15 +1435,10 @@ void start_vmx(void)
    2.28      }
    2.29  
    2.30      if ( cpu_has_vmx_ept )
    2.31 -    {
    2.32 -        printk("VMX: EPT is available.\n");
    2.33          vmx_function_table.hap_supported = 1;
    2.34 -    }
    2.35  
    2.36      if ( cpu_has_vmx_vpid )
    2.37      {
    2.38 -        printk("VMX: VPID is available.\n");
    2.39 -
    2.40          vpid_bitmap = xmalloc_array(
    2.41              unsigned long, BITS_TO_LONGS(VPID_BITMAP_SIZE));
    2.42          BUG_ON(vpid_bitmap == NULL);
     3.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Thu May 28 09:41:59 2009 +0100
     3.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Thu May 28 09:51:43 2009 +0100
     3.3 @@ -170,6 +170,7 @@ extern u32 vmx_vmentry_control;
     3.4  #define SECONDARY_EXEC_ENABLE_EPT               0x00000002
     3.5  #define SECONDARY_EXEC_ENABLE_VPID              0x00000020
     3.6  #define SECONDARY_EXEC_WBINVD_EXITING           0x00000040
     3.7 +#define SECONDARY_EXEC_UNRESTRICTED_GUEST       0x00000080
     3.8  extern u32 vmx_secondary_exec_control;
     3.9  
    3.10  extern bool_t cpu_has_vmx_ins_outs_instr_info;
    3.11 @@ -194,6 +195,11 @@ extern bool_t cpu_has_vmx_ins_outs_instr
    3.12      (vmx_cpu_based_exec_control & CPU_BASED_MONITOR_TRAP_FLAG)
    3.13  #define cpu_has_vmx_pat \
    3.14      (vmx_vmentry_control & VM_ENTRY_LOAD_GUEST_PAT)
    3.15 +#define cpu_has_vmx_unrestricted_guest \
    3.16 +    (vmx_secondary_exec_control & SECONDARY_EXEC_UNRESTRICTED_GUEST)
    3.17 +#define vmx_unrestricted_guest(v)               \
    3.18 +    ((v)->arch.hvm_vmx.secondary_exec_control & \
    3.19 +     SECONDARY_EXEC_UNRESTRICTED_GUEST)
    3.20  
    3.21  /* GUEST_INTERRUPTIBILITY_INFO flags. */
    3.22  #define VMX_INTR_SHADOW_STI             0x00000001