ia64/xen-unstable

changeset 10222:e5de45e2edaf

[SVM] Fix virtualization of the CPUID NX bit, and clean up other CPUID bits.
Signed-off-by: Tom Woller <thomas.woller@amd.com>
Signed-off-by: Wei Huang <wei.huang2@amd.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed May 31 07:28:43 2006 +0100 (2006-05-31)
parents ec1e371ec320
children 2c0cd4075d1c
files xen/arch/x86/hvm/svm/svm.c
line diff
     1.1 --- a/xen/arch/x86/hvm/svm/svm.c	Wed May 31 07:25:59 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Wed May 31 07:28:43 2006 +0100
     1.3 @@ -950,8 +950,10 @@ static void svm_do_general_protection_fa
     1.4      svm_inject_exception(v, TRAP_gp_fault, 1, error_code);
     1.5  }
     1.6  
     1.7 -/* Reserved bits: [31:14], [12:1] */
     1.8 -#define SVM_VCPU_CPUID_L1_RESERVED 0xffffdffe
     1.9 +/* Reserved bits ECX: [31:14], [12:4], [2:1]*/
    1.10 +#define SVM_VCPU_CPUID_L1_ECX_RESERVED 0xffffdff6
    1.11 +/* Reserved bits EDX: [31:29], [27], [22:20], [18], [10] */
    1.12 +#define SVM_VCPU_CPUID_L1_EDX_RESERVED 0xe8740400
    1.13  
    1.14  static void svm_vmexit_do_cpuid(struct vmcb_struct *vmcb, unsigned long input, 
    1.15          struct cpu_user_regs *regs) 
    1.16 @@ -974,20 +976,17 @@ static void svm_vmexit_do_cpuid(struct v
    1.17  
    1.18      cpuid(input, &eax, &ebx, &ecx, &edx);
    1.19  
    1.20 -    if (input == 1)
    1.21 +    if (input == 0x00000001)
    1.22      {
    1.23          if ( !hvm_apic_support(v->domain) ||
    1.24                  !vlapic_global_enabled((VLAPIC(v))) )
    1.25          {
    1.26 -            clear_bit(X86_FEATURE_APIC, &edx);
    1.27 -            /* Since the apic is disabled, avoid any confusion about SMP cpus being available */
    1.28 -            clear_bit(X86_FEATURE_HT, &edx);  /* clear the hyperthread bit */
    1.29 -            ebx &= 0xFF00FFFF;  /* set the logical processor count to 1 */
    1.30 -            ebx |= 0x00010000;
    1.31 +            /* Since the apic is disabled, avoid any confusion 
    1.32 +	       about SMP cpus being available */
    1.33 +	    clear_bit(X86_FEATURE_APIC, &edx);
    1.34          }
    1.35 -	    
    1.36 +
    1.37  #if CONFIG_PAGING_LEVELS < 3
    1.38 -        clear_bit(X86_FEATURE_NX, &edx);
    1.39          clear_bit(X86_FEATURE_PAE, &edx);
    1.40          clear_bit(X86_FEATURE_PSE, &edx);
    1.41          clear_bit(X86_FEATURE_PSE36, &edx);
    1.42 @@ -996,24 +995,90 @@ static void svm_vmexit_do_cpuid(struct v
    1.43          {
    1.44              if ( !v->domain->arch.hvm_domain.pae_enabled )
    1.45              {
    1.46 -               clear_bit(X86_FEATURE_PAE, &edx);
    1.47 -               clear_bit(X86_FEATURE_NX, &edx);
    1.48 +		clear_bit(X86_FEATURE_PAE, &edx);
    1.49              }
    1.50              clear_bit(X86_FEATURE_PSE, &edx);
    1.51              clear_bit(X86_FEATURE_PSE36, &edx);
    1.52          }
    1.53  #endif	
    1.54          /* Clear out reserved bits. */
    1.55 -        ecx &= ~SVM_VCPU_CPUID_L1_RESERVED; /* mask off reserved bits */
    1.56 +        ecx &= ~SVM_VCPU_CPUID_L1_ECX_RESERVED;
    1.57 +        edx &= ~SVM_VCPU_CPUID_L1_EDX_RESERVED;
    1.58 +
    1.59          clear_bit(X86_FEATURE_MWAIT & 31, &ecx);
    1.60 +
    1.61 +	/* Guest should only see one logical processor.
    1.62 +	 * See details on page 23 of AMD CPUID Specification. 
    1.63 +	*/
    1.64 +	clear_bit(X86_FEATURE_HT, &edx);  /* clear the hyperthread bit */
    1.65 +	ebx &= 0xFF00FFFF;  /* clear the logical processor count when HTT=0 */
    1.66 +	ebx |= 0x00010000;  /* set to 1 just for precaution */
    1.67      }
    1.68 -#ifdef __i386__
    1.69 +    else if ( ( input > 0x00000005 ) && ( input < 0x80000000 ) )
    1.70 +    {
    1.71 +	eax = ebx = ecx = edx = 0x0;
    1.72 +    }
    1.73      else if ( input == 0x80000001 )
    1.74      {
    1.75 +	/* We duplicate some CPUID_00000001 code because many bits of 
    1.76 +	   CPUID_80000001_EDX overlaps with CPUID_00000001_EDX. */
    1.77 +
    1.78 +        if ( !hvm_apic_support(v->domain) ||
    1.79 +	     !vlapic_global_enabled((VLAPIC(v))) )
    1.80 +        {
    1.81 +            /* Since the apic is disabled, avoid any confusion 
    1.82 +	       about SMP cpus being available */
    1.83 +	    clear_bit(X86_FEATURE_APIC, &edx);
    1.84 +        }
    1.85 +
    1.86 +	/* Clear the Cmp_Legacy bit 
    1.87 +	 * This bit is supposed to be zero when HTT = 0.
    1.88 +	 * See details on page 23 of AMD CPUID Specification. 
    1.89 +	*/
    1.90 +	clear_bit(X86_FEATURE_CMP_LEGACY & 31, &ecx);
    1.91 +
    1.92 +#ifdef __i386__
    1.93          /* Mask feature for Intel ia32e or AMD long mode. */
    1.94 +        clear_bit(X86_FEATURE_LAHF_LM & 31, &ecx);
    1.95 +
    1.96          clear_bit(X86_FEATURE_LM & 31, &edx);
    1.97 +        clear_bit(X86_FEATURE_SYSCALL & 31, &edx);
    1.98 +#endif
    1.99 +
   1.100 +#if CONFIG_PAGING_LEVELS < 3
   1.101 +	clear_bit(X86_FEATURE_NX & 31, &edx);
   1.102 +        clear_bit(X86_FEATURE_PAE, &edx);
   1.103 +        clear_bit(X86_FEATURE_PSE, &edx);
   1.104 +        clear_bit(X86_FEATURE_PSE36, &edx);
   1.105 +#else
   1.106 +        if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
   1.107 +        {
   1.108 +            if ( !v->domain->arch.hvm_domain.pae_enabled )
   1.109 +            {
   1.110 +		clear_bit(X86_FEATURE_NX & 31, &edx);
   1.111 +		clear_bit(X86_FEATURE_PAE, &edx);
   1.112 +            }
   1.113 +            clear_bit(X86_FEATURE_PSE, &edx);
   1.114 +            clear_bit(X86_FEATURE_PSE36, &edx);
   1.115 +        }
   1.116 +#endif	
   1.117 +
   1.118 +        /* Make SVM feature invisible to the guest. */
   1.119 +        clear_bit(X86_FEATURE_SVME & 31, &ecx);
   1.120 +	
   1.121 +	/* So far, we do not support 3DNow for the guest. */
   1.122 +	clear_bit(X86_FEATURE_3DNOW & 31, &edx);
   1.123 +	clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx);
   1.124      }
   1.125 -#endif
   1.126 +    else if ( ( input == 0x80000007 ) || ( input == 0x8000000A  ) )
   1.127 +    {
   1.128 +	/* Mask out features of power management and SVM extension. */
   1.129 +	eax = ebx = ecx = edx = 0;
   1.130 +    }
   1.131 +    else if ( input == 0x80000008 )
   1.132 +    {
   1.133 +	ecx &= 0xFFFFFF00; /* Make sure Number of CPU core is 1 when HTT=0 */
   1.134 +    }
   1.135  
   1.136      regs->eax = (unsigned long)eax;
   1.137      regs->ebx = (unsigned long)ebx;