ia64/xen-unstable

changeset 10661:8e55c5c11475

[XEN] Add CPUID hypervisor-info leaves at index 0x40000000.
Currently only a signature leaf is defined ("Xen\0").
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Jul 05 18:48:41 2006 +0100 (2006-07-05)
parents 74018b65c369
children 2b815d9acdea 30cdeb686b93
files xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/traps.c xen/include/asm-x86/processor.h
line diff
     1.1 --- a/xen/arch/x86/hvm/svm/svm.c	Wed Jul 05 17:37:08 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Wed Jul 05 18:48:41 2006 +0100
     1.3 @@ -962,8 +962,8 @@ static void svm_vmexit_do_cpuid(struct v
     1.4                  !vlapic_global_enabled((VLAPIC(v))) )
     1.5          {
     1.6              /* Since the apic is disabled, avoid any confusion 
     1.7 -	       about SMP cpus being available */
     1.8 -	    clear_bit(X86_FEATURE_APIC, &edx);
     1.9 +               about SMP cpus being available */
    1.10 +            clear_bit(X86_FEATURE_APIC, &edx);
    1.11          }
    1.12  
    1.13  #if CONFIG_PAGING_LEVELS < 3
    1.14 @@ -974,52 +974,51 @@ static void svm_vmexit_do_cpuid(struct v
    1.15          if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
    1.16          {
    1.17              if ( !v->domain->arch.hvm_domain.pae_enabled )
    1.18 -            {
    1.19 -		clear_bit(X86_FEATURE_PAE, &edx);
    1.20 -            }
    1.21 +                clear_bit(X86_FEATURE_PAE, &edx);
    1.22              clear_bit(X86_FEATURE_PSE, &edx);
    1.23              clear_bit(X86_FEATURE_PSE36, &edx);
    1.24          }
    1.25 -#endif	
    1.26 +#endif
    1.27          /* Clear out reserved bits. */
    1.28          ecx &= ~SVM_VCPU_CPUID_L1_ECX_RESERVED;
    1.29          edx &= ~SVM_VCPU_CPUID_L1_EDX_RESERVED;
    1.30  
    1.31          clear_bit(X86_FEATURE_MWAIT & 31, &ecx);
    1.32  
    1.33 -	/* Guest should only see one logical processor.
    1.34 -	 * See details on page 23 of AMD CPUID Specification. 
    1.35 -	*/
    1.36 -	clear_bit(X86_FEATURE_HT, &edx);  /* clear the hyperthread bit */
    1.37 -	ebx &= 0xFF00FFFF;  /* clear the logical processor count when HTT=0 */
    1.38 -	ebx |= 0x00010000;  /* set to 1 just for precaution */
    1.39 -
    1.40 -	/* Disable machine check architecture */
    1.41 -	clear_bit(X86_FEATURE_MCA, &edx);
    1.42 -	clear_bit(X86_FEATURE_MCE, &edx);
    1.43 +        /* Guest should only see one logical processor.
    1.44 +         * See details on page 23 of AMD CPUID Specification. 
    1.45 +         */
    1.46 +        clear_bit(X86_FEATURE_HT, &edx);  /* clear the hyperthread bit */
    1.47 +        ebx &= 0xFF00FFFF;  /* clear the logical processor count when HTT=0 */
    1.48 +        ebx |= 0x00010000;  /* set to 1 just for precaution */
    1.49 +
    1.50 +        /* Disable machine check architecture */
    1.51 +        clear_bit(X86_FEATURE_MCA, &edx);
    1.52 +        clear_bit(X86_FEATURE_MCE, &edx);
    1.53      }
    1.54 -    else if ( ( input > 0x00000005 ) && ( input < 0x80000000 ) )
    1.55 +    else if ( (input > 0x00000005) && (input < 0x80000000) )
    1.56      {
    1.57 -	eax = ebx = ecx = edx = 0x0;
    1.58 +        if ( !cpuid_hypervisor_leaves(input, &eax, &ebx, &ecx, &edx) )
    1.59 +            eax = ebx = ecx = edx = 0;
    1.60      }
    1.61      else if ( input == 0x80000001 )
    1.62      {
    1.63 -	/* We duplicate some CPUID_00000001 code because many bits of 
    1.64 -	   CPUID_80000001_EDX overlaps with CPUID_00000001_EDX. */
    1.65 +        /* We duplicate some CPUID_00000001 code because many bits of 
    1.66 +           CPUID_80000001_EDX overlaps with CPUID_00000001_EDX. */
    1.67  
    1.68          if ( !hvm_apic_support(v->domain) ||
    1.69 -	     !vlapic_global_enabled((VLAPIC(v))) )
    1.70 +             !vlapic_global_enabled((VLAPIC(v))) )
    1.71          {
    1.72              /* Since the apic is disabled, avoid any confusion 
    1.73 -	       about SMP cpus being available */
    1.74 -	    clear_bit(X86_FEATURE_APIC, &edx);
    1.75 +               about SMP cpus being available */
    1.76 +            clear_bit(X86_FEATURE_APIC, &edx);
    1.77          }
    1.78  
    1.79 -	/* Clear the Cmp_Legacy bit 
    1.80 -	 * This bit is supposed to be zero when HTT = 0.
    1.81 -	 * See details on page 23 of AMD CPUID Specification. 
    1.82 -	*/
    1.83 -	clear_bit(X86_FEATURE_CMP_LEGACY & 31, &ecx);
    1.84 +        /* Clear the Cmp_Legacy bit 
    1.85 +         * This bit is supposed to be zero when HTT = 0.
    1.86 +         * See details on page 23 of AMD CPUID Specification. 
    1.87 +         */
    1.88 +        clear_bit(X86_FEATURE_CMP_LEGACY & 31, &ecx);
    1.89  
    1.90  #ifdef __i386__
    1.91          /* Mask feature for Intel ia32e or AMD long mode. */
    1.92 @@ -1030,7 +1029,7 @@ static void svm_vmexit_do_cpuid(struct v
    1.93  #endif
    1.94  
    1.95  #if CONFIG_PAGING_LEVELS < 3
    1.96 -	clear_bit(X86_FEATURE_NX & 31, &edx);
    1.97 +        clear_bit(X86_FEATURE_NX & 31, &edx);
    1.98          clear_bit(X86_FEATURE_PAE, &edx);
    1.99          clear_bit(X86_FEATURE_PSE, &edx);
   1.100          clear_bit(X86_FEATURE_PSE36, &edx);
   1.101 @@ -1039,29 +1038,29 @@ static void svm_vmexit_do_cpuid(struct v
   1.102          {
   1.103              if ( !v->domain->arch.hvm_domain.pae_enabled )
   1.104              {
   1.105 -		clear_bit(X86_FEATURE_NX & 31, &edx);
   1.106 -		clear_bit(X86_FEATURE_PAE, &edx);
   1.107 +                clear_bit(X86_FEATURE_NX & 31, &edx);
   1.108 +                clear_bit(X86_FEATURE_PAE, &edx);
   1.109              }
   1.110              clear_bit(X86_FEATURE_PSE, &edx);
   1.111              clear_bit(X86_FEATURE_PSE36, &edx);
   1.112          }
   1.113 -#endif	
   1.114 +#endif
   1.115  
   1.116          /* Make SVM feature invisible to the guest. */
   1.117          clear_bit(X86_FEATURE_SVME & 31, &ecx);
   1.118 -	
   1.119 -	/* So far, we do not support 3DNow for the guest. */
   1.120 -	clear_bit(X86_FEATURE_3DNOW & 31, &edx);
   1.121 -	clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx);
   1.122 +
   1.123 +        /* So far, we do not support 3DNow for the guest. */
   1.124 +        clear_bit(X86_FEATURE_3DNOW & 31, &edx);
   1.125 +        clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx);
   1.126      }
   1.127      else if ( ( input == 0x80000007 ) || ( input == 0x8000000A  ) )
   1.128      {
   1.129 -	/* Mask out features of power management and SVM extension. */
   1.130 -	eax = ebx = ecx = edx = 0;
   1.131 +        /* Mask out features of power management and SVM extension. */
   1.132 +        eax = ebx = ecx = edx = 0;
   1.133      }
   1.134      else if ( input == 0x80000008 )
   1.135      {
   1.136 -	ecx &= 0xFFFFFF00; /* Make sure Number of CPU core is 1 when HTT=0 */
   1.137 +        ecx &= 0xFFFFFF00; /* Make sure Number of CPU core is 1 when HTT=0 */
   1.138      }
   1.139  
   1.140      regs->eax = (unsigned long)eax;
   1.141 @@ -1214,8 +1213,9 @@ static void svm_dr_access (struct vcpu *
   1.142  }
   1.143  
   1.144  
   1.145 -static void svm_get_prefix_info(struct vmcb_struct *vmcb, 
   1.146 -		unsigned int dir, segment_selector_t **seg, unsigned int *asize)
   1.147 +static void svm_get_prefix_info(
   1.148 +    struct vmcb_struct *vmcb, 
   1.149 +    unsigned int dir, segment_selector_t **seg, unsigned int *asize)
   1.150  {
   1.151      unsigned char inst[MAX_INST_LEN];
   1.152      int i;
   1.153 @@ -1287,9 +1287,10 @@ static void svm_get_prefix_info(struct v
   1.154  
   1.155  
   1.156  /* Get the address of INS/OUTS instruction */
   1.157 -static inline int svm_get_io_address(struct vcpu *v, 
   1.158 -		struct cpu_user_regs *regs, unsigned int dir, 
   1.159 -        unsigned long *count, unsigned long *addr)
   1.160 +static inline int svm_get_io_address(
   1.161 +    struct vcpu *v, 
   1.162 +    struct cpu_user_regs *regs, unsigned int dir, 
   1.163 +    unsigned long *count, unsigned long *addr)
   1.164  {
   1.165      unsigned long        reg;
   1.166      unsigned int         asize = 0;
     2.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Wed Jul 05 17:37:08 2006 +0100
     2.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Wed Jul 05 18:48:41 2006 +0100
     2.3 @@ -868,7 +868,7 @@ static void vmx_vmexit_do_cpuid(struct c
     2.4          cpuid_count(input, count, &eax, &ebx, &ecx, &edx);
     2.5          eax &= NUM_CORES_RESET_MASK;  
     2.6      }
     2.7 -    else
     2.8 +    else if ( !cpuid_hypervisor_leaves(input, &eax, &ebx, &ecx, &edx) )
     2.9      {
    2.10          cpuid(input, &eax, &ebx, &ecx, &edx);
    2.11  
     3.1 --- a/xen/arch/x86/traps.c	Wed Jul 05 17:37:08 2006 +0100
     3.2 +++ b/xen/arch/x86/traps.c	Wed Jul 05 18:48:41 2006 +0100
     3.3 @@ -426,10 +426,32 @@ DO_ERROR_NOCODE(16, "fpu error", coproce
     3.4  DO_ERROR(17, "alignment check", alignment_check)
     3.5  DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error)
     3.6  
     3.7 +int cpuid_hypervisor_leaves(
     3.8 +    uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
     3.9 +{
    3.10 +    if ( (idx < 0x40000000) || (idx > 0x40000000) )
    3.11 +        return 0;
    3.12 +
    3.13 +    switch ( idx - 0x40000000 )
    3.14 +    {
    3.15 +    case 0:
    3.16 +        *eax = 0x40000000;
    3.17 +        *ebx = 0x006e6558; /* "Xen\0" */
    3.18 +        *ecx = *edx = 0;
    3.19 +        break;
    3.20 +
    3.21 +    default:
    3.22 +        BUG();
    3.23 +    }
    3.24 +
    3.25 +    return 1;
    3.26 +}
    3.27 +
    3.28  static int emulate_forced_invalid_op(struct cpu_user_regs *regs)
    3.29  {
    3.30      char signature[5], instr[2];
    3.31 -    unsigned long a, b, c, d, eip;
    3.32 +    uint32_t a, b, c, d;
    3.33 +    unsigned long eip;
    3.34  
    3.35      a = regs->eax;
    3.36      b = regs->ebx;
    3.37 @@ -466,6 +488,10 @@ static int emulate_forced_invalid_op(str
    3.38          if ( !IS_PRIV(current->domain) )
    3.39              clear_bit(X86_FEATURE_MTRR, &d);
    3.40      }
    3.41 +    else
    3.42 +    {
    3.43 +        (void)cpuid_hypervisor_leaves(regs->eax, &a, &b, &c, &d);
    3.44 +    }
    3.45  
    3.46      regs->eax = a;
    3.47      regs->ebx = b;
     4.1 --- a/xen/include/asm-x86/processor.h	Wed Jul 05 17:37:08 2006 +0100
     4.2 +++ b/xen/include/asm-x86/processor.h	Wed Jul 05 18:48:41 2006 +0100
     4.3 @@ -545,6 +545,9 @@ extern void mtrr_bp_init(void);
     4.4  
     4.5  extern void mcheck_init(struct cpuinfo_x86 *c);
     4.6  
     4.7 +int cpuid_hypervisor_leaves(
     4.8 +    uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
     4.9 +
    4.10  #endif /* !__ASSEMBLY__ */
    4.11  
    4.12  #endif /* __ASM_X86_PROCESSOR_H */