ia64/xen-unstable

changeset 16440:0814fb0f8a4d

x86, hvm: Config option to allow vmxassist to be disabled.
hvmloader is modified to dynamically detect this, allowing possibility
of optional full vmxassist replacement in 3.2 stable branch in future.
Currently 'vmxassist=y' is not much use since no replacement is
implemented.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir@xensource.com>
date Sat Nov 24 13:23:22 2007 +0000 (2007-11-24)
parents dc9246357cdb
children 9e88db95ddc7
files tools/firmware/hvmloader/hvmloader.c xen/arch/x86/Rules.mk xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/hvm/vpic.c xen/include/asm-x86/hvm/vmx/vmcs.h
line diff
     1.1 --- a/tools/firmware/hvmloader/hvmloader.c	Fri Nov 23 16:42:44 2007 +0000
     1.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Sat Nov 24 13:23:22 2007 +0000
     1.3 @@ -40,6 +40,7 @@ asm(
     1.4      "    cli                         \n"
     1.5      "    movl $stack_top,%esp        \n"
     1.6      "    movl %esp,%ebp              \n"
     1.7 +    "    movl %eax,initial_eax       \n"
     1.8      "    call main                   \n"
     1.9      /* Relocate real-mode trampoline to 0x0. */
    1.10      "    mov  $trampoline_start,%esi \n"
    1.11 @@ -97,6 +98,8 @@ asm(
    1.12      "stack_top:                      \n"
    1.13      );
    1.14  
    1.15 +static unsigned int initial_eax;
    1.16 +
    1.17  void create_mp_tables(void);
    1.18  int hvm_write_smbios_tables(void);
    1.19  
    1.20 @@ -121,6 +124,12 @@ check_amd(void)
    1.21      return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
    1.22  }
    1.23  
    1.24 +static int
    1.25 +use_vmxassist(void)
    1.26 +{
    1.27 +    return !check_amd() && !initial_eax;
    1.28 +}
    1.29 +
    1.30  static void
    1.31  wrmsr(uint32_t idx, uint64_t v)
    1.32  {
    1.33 @@ -407,7 +416,7 @@ int main(void)
    1.34          printf(" %05x-%05x: Etherboot ROM\n",
    1.35                 ETHERBOOT_PHYSICAL_ADDRESS,
    1.36                 ETHERBOOT_PHYSICAL_ADDRESS + etherboot_sz - 1);
    1.37 -    if ( !check_amd() )
    1.38 +    if ( use_vmxassist() )
    1.39          printf(" %05x-%05x: VMXAssist\n",
    1.40                 VMXASSIST_PHYSICAL_ADDRESS,
    1.41                 VMXASSIST_PHYSICAL_ADDRESS + sizeof(vmxassist) - 1);
    1.42 @@ -424,7 +433,7 @@ int main(void)
    1.43                 ROMBIOS_PHYSICAL_ADDRESS,
    1.44                 ROMBIOS_PHYSICAL_ADDRESS + rombios_sz - 1);
    1.45  
    1.46 -    if ( !check_amd() )
    1.47 +    if ( use_vmxassist() )
    1.48      {
    1.49          printf("Loading VMXAssist ...\n");
    1.50          memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
     2.1 --- a/xen/arch/x86/Rules.mk	Fri Nov 23 16:42:44 2007 +0000
     2.2 +++ b/xen/arch/x86/Rules.mk	Sat Nov 24 13:23:22 2007 +0000
     2.3 @@ -11,6 +11,11 @@ xenoprof := y
     2.4  #
     2.5  pae ?= n
     2.6  supervisor_mode_kernel ?= n
     2.7 +vmxassist ?= y
     2.8 +
     2.9 +ifeq ($(vmxassist),y)
    2.10 +CFLAGS += -DVMXASSIST
    2.11 +endif
    2.12  
    2.13  # Solaris grabs stdarg.h and friends from the system include directory.
    2.14  ifneq ($(XEN_OS),SunOS)
     3.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Nov 23 16:42:44 2007 +0000
     3.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Sat Nov 24 13:23:22 2007 +0000
     3.3 @@ -92,6 +92,11 @@ static int vmx_vcpu_initialise(struct vc
     3.4  
     3.5      vmx_install_vlapic_mapping(v);
     3.6  
     3.7 +#ifndef VMXASSIST
     3.8 +    if ( v->vcpu_id == 0 )
     3.9 +        v->arch.guest_context.user_regs.eax = 1;
    3.10 +#endif
    3.11 +
    3.12      return 0;
    3.13  }
    3.14  
    3.15 @@ -701,7 +706,9 @@ static void vmx_load_cpu_state(struct vc
    3.16      v->arch.hvm_vmx.shadow_gs = data->shadow_gs;
    3.17  #endif
    3.18  
    3.19 +#ifdef VMXASSIST
    3.20      v->arch.hvm_vmx.vmxassist_enabled = !(data->cr0 & X86_CR0_PE);
    3.21 +#endif
    3.22  
    3.23      hvm_set_guest_time(v, data->tsc);
    3.24  
    3.25 @@ -961,9 +968,11 @@ static void vmx_init_ap_context(
    3.26      struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector)
    3.27  {
    3.28      memset(ctxt, 0, sizeof(*ctxt));
    3.29 +#ifdef VMXASSIST
    3.30      ctxt->user_regs.eip = VMXASSIST_BASE;
    3.31      ctxt->user_regs.edx = vcpuid;
    3.32      ctxt->user_regs.ebx = trampoline_vector;
    3.33 +#endif
    3.34  }
    3.35  
    3.36  void do_nmi(struct cpu_user_regs *);
    3.37 @@ -1045,7 +1054,10 @@ static void vmx_update_guest_cr(struct v
    3.38  
    3.39          v->arch.hvm_vcpu.hw_cr[0] =
    3.40              v->arch.hvm_vcpu.guest_cr[0] |
    3.41 -            X86_CR0_PE | X86_CR0_NE | X86_CR0_PG | X86_CR0_WP;
    3.42 +            X86_CR0_NE | X86_CR0_PG | X86_CR0_WP;
    3.43 +#ifdef VMXASSIST
    3.44 +        v->arch.hvm_vcpu.hw_cr[0] |= X86_CR0_PE;
    3.45 +#endif
    3.46          __vmwrite(GUEST_CR0, v->arch.hvm_vcpu.hw_cr[0]);
    3.47          __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vcpu.guest_cr[0]);
    3.48          break;
    3.49 @@ -1246,6 +1258,7 @@ static void vmx_do_cpuid(struct cpu_user
    3.50      unsigned int input = regs->eax;
    3.51      unsigned int eax, ebx, ecx, edx;
    3.52  
    3.53 +#ifdef VMXASSIST
    3.54      if ( input == 0x40000003 )
    3.55      {
    3.56          /*
    3.57 @@ -1280,6 +1293,7 @@ static void vmx_do_cpuid(struct cpu_user
    3.58          regs->edx = (u32)(value >> 32);
    3.59          return;
    3.60      }
    3.61 +#endif
    3.62  
    3.63      hvm_cpuid(input, &eax, &ebx, &ecx, &edx);
    3.64  
    3.65 @@ -1816,6 +1830,8 @@ static void vmx_io_instruction(unsigned 
    3.66      }
    3.67  }
    3.68  
    3.69 +#ifdef VMXASSIST
    3.70 +
    3.71  static void vmx_world_save(struct vcpu *v, struct vmx_assist_context *c)
    3.72  {
    3.73      struct cpu_user_regs *regs = guest_cpu_user_regs();
    3.74 @@ -2058,6 +2074,19 @@ static int vmx_set_cr0(unsigned long val
    3.75      return 1;
    3.76  }
    3.77  
    3.78 +#else /* !defined(VMXASSIST) */
    3.79 +
    3.80 +#define vmx_set_cr0(v) hvm_set_cr0(v)
    3.81 +
    3.82 +static int vmx_realmode(struct cpu_user_regs *regs)
    3.83 +{
    3.84 +    gdprintk(XENLOG_ERR, "Attempt to enter real mode on VCPU %d\n",
    3.85 +             current->vcpu_id);
    3.86 +    return -EINVAL;
    3.87 +}
    3.88 +
    3.89 +#endif
    3.90 +
    3.91  #define CASE_SET_REG(REG, reg)      \
    3.92      case REG_ ## REG: regs->reg = value; break
    3.93  #define CASE_GET_REG(REG, reg)      \
    3.94 @@ -2677,9 +2706,16 @@ static void vmx_failed_vmentry(unsigned 
    3.95                                 struct cpu_user_regs *regs)
    3.96  {
    3.97      unsigned int failed_vmentry_reason = (uint16_t)exit_reason;
    3.98 -    unsigned long exit_qualification;
    3.99 -
   3.100 -    exit_qualification = __vmread(EXIT_QUALIFICATION);
   3.101 +    unsigned long exit_qualification = __vmread(EXIT_QUALIFICATION);
   3.102 +
   3.103 +#ifndef VMXASSIST
   3.104 +    if ( (failed_vmentry_reason == EXIT_REASON_INVALID_GUEST_STATE) &&
   3.105 +         (exit_qualification == 0) &&
   3.106 +         !(current->arch.hvm_vcpu.hw_cr[0] & X86_CR0_PE) &&
   3.107 +         (vmx_realmode(regs) == 0) )
   3.108 +        return;
   3.109 +#endif
   3.110 +
   3.111      printk("Failed vm entry (exit reason 0x%x) ", exit_reason);
   3.112      switch ( failed_vmentry_reason )
   3.113      {
     4.1 --- a/xen/arch/x86/hvm/vpic.c	Fri Nov 23 16:42:44 2007 +0000
     4.2 +++ b/xen/arch/x86/hvm/vpic.c	Sat Nov 24 13:23:22 2007 +0000
     4.3 @@ -271,7 +271,7 @@ static void vpic_ioport_write(
     4.4              vpic->imr = val;
     4.5              break;
     4.6          case 1:
     4.7 -#if 1 /* Delete me when vmxassist is retired. */
     4.8 +#ifdef VMXASSIST
     4.9              /* Which mode is irqbase programmed in? */
    4.10              current->arch.hvm_vmx.irqbase_mode =
    4.11                  current->arch.hvm_vmx.vmxassist_enabled;
     5.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Fri Nov 23 16:42:44 2007 +0000
     5.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Sat Nov 24 13:23:22 2007 +0000
     5.3 @@ -22,7 +22,10 @@
     5.4  #include <asm/config.h>
     5.5  #include <asm/hvm/io.h>
     5.6  #include <asm/hvm/vmx/cpu.h>
     5.7 +
     5.8 +#ifdef VMXASSIST
     5.9  #include <public/hvm/vmx_assist.h>
    5.10 +#endif
    5.11  
    5.12  extern void start_vmx(void);
    5.13  extern void vmcs_dump_vcpu(void);
    5.14 @@ -85,10 +88,11 @@ struct arch_vmx_struct {
    5.15      unsigned int         host_msr_count;
    5.16      struct vmx_msr_entry *host_msr_area;
    5.17  
    5.18 -    /* Following fields are all specific to vmxassist. */
    5.19 +#ifdef VMXASSIST
    5.20      unsigned long        vmxassist_enabled:1;
    5.21      unsigned long        irqbase_mode:1;
    5.22      unsigned char        pm_irqbase[2];
    5.23 +#endif
    5.24  };
    5.25  
    5.26  int vmx_create_vmcs(struct vcpu *v);