ia64/xen-unstable

changeset 16123:723b9837db1b

x86/hvm: miscellaneous CPUID handling changes
- use __clear_bit() rather than clear_bit()
- use switch statements instead of long series of if-s
- eliminate pointless casts

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir@xensource.com>
date Fri Oct 12 11:42:56 2007 +0100 (2007-10-12)
parents e66147d054cf
children ef4119637f52
files xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/cpufeature.h
line diff
     1.1 --- a/xen/arch/x86/hvm/hvm.c	Fri Oct 12 11:20:28 2007 +0100
     1.2 +++ b/xen/arch/x86/hvm/hvm.c	Fri Oct 12 11:42:56 2007 +0100
     1.3 @@ -1259,40 +1259,40 @@ void hvm_print_line(struct vcpu *v, cons
     1.4  void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
     1.5                                     unsigned int *ecx, unsigned int *edx)
     1.6  {
     1.7 -    if ( !cpuid_hypervisor_leaves(input, eax, ebx, ecx, edx) )
     1.8 -    {
     1.9 -        cpuid(input, eax, ebx, ecx, edx);
    1.10 +    struct vcpu *v = current;
    1.11  
    1.12 -        if ( input == 0x00000001 )
    1.13 -        {
    1.14 -            struct vcpu *v = current;
    1.15 +    if ( cpuid_hypervisor_leaves(input, eax, ebx, ecx, edx) )
    1.16 +        return;
    1.17  
    1.18 -            clear_bit(X86_FEATURE_MWAIT & 31, ecx);
    1.19 +    cpuid(input, eax, ebx, ecx, edx);
    1.20  
    1.21 -            if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
    1.22 -                clear_bit(X86_FEATURE_APIC & 31, edx);
    1.23 +    switch ( input )
    1.24 +    {
    1.25 +    case 0x00000001:
    1.26 +        __clear_bit(X86_FEATURE_MWAIT & 31, ecx);
    1.27 +
    1.28 +        if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
    1.29 +            __clear_bit(X86_FEATURE_APIC & 31, edx);
    1.30  
    1.31  #if CONFIG_PAGING_LEVELS >= 3
    1.32 -            if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
    1.33 +        if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
    1.34  #endif
    1.35 -                clear_bit(X86_FEATURE_PAE & 31, edx);
    1.36 -            clear_bit(X86_FEATURE_PSE36 & 31, edx);
    1.37 -        }
    1.38 -        else if ( input == 0x80000001 )
    1.39 -        {
    1.40 +            __clear_bit(X86_FEATURE_PAE & 31, edx);
    1.41 +        __clear_bit(X86_FEATURE_PSE36 & 31, edx);
    1.42 +        break;
    1.43 +
    1.44 +    case 0x80000001:
    1.45  #if CONFIG_PAGING_LEVELS >= 3
    1.46 -            struct vcpu *v = current;
    1.47 -            if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
    1.48 +        if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
    1.49  #endif
    1.50 -                clear_bit(X86_FEATURE_NX & 31, edx);
    1.51 +            __clear_bit(X86_FEATURE_NX & 31, edx);
    1.52  #ifdef __i386__
    1.53 -            /* Mask feature for Intel ia32e or AMD long mode. */
    1.54 -            clear_bit(X86_FEATURE_LAHF_LM & 31, ecx);
    1.55 -
    1.56 -            clear_bit(X86_FEATURE_LM & 31, edx);
    1.57 -            clear_bit(X86_FEATURE_SYSCALL & 31, edx);
    1.58 +        /* Mask feature for Intel ia32e or AMD long mode. */
    1.59 +        __clear_bit(X86_FEATURE_LAHF_LM & 31, ecx);
    1.60 +        __clear_bit(X86_FEATURE_LM & 31, edx);
    1.61 +        __clear_bit(X86_FEATURE_SYSCALL & 31, edx);
    1.62  #endif
    1.63 -        }
    1.64 +        break;
    1.65      }
    1.66  }
    1.67  
     2.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Oct 12 11:20:28 2007 +0100
     2.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Oct 12 11:42:56 2007 +0100
     2.3 @@ -999,8 +999,9 @@ static void svm_vmexit_do_cpuid(struct v
     2.4  
     2.5      hvm_cpuid(input, &eax, &ebx, &ecx, &edx);
     2.6  
     2.7 -    if ( input == 0x00000001 )
     2.8 +    switch ( input )
     2.9      {
    2.10 +    case 0x00000001:
    2.11          /* Clear out reserved bits. */
    2.12          ecx &= ~SVM_VCPU_CPUID_L1_ECX_RESERVED;
    2.13          edx &= ~SVM_VCPU_CPUID_L1_EDX_RESERVED;
    2.14 @@ -1008,50 +1009,56 @@ static void svm_vmexit_do_cpuid(struct v
    2.15          /* Guest should only see one logical processor.
    2.16           * See details on page 23 of AMD CPUID Specification.
    2.17           */
    2.18 -        clear_bit(X86_FEATURE_HT & 31, &edx);  /* clear the hyperthread bit */
    2.19 +        __clear_bit(X86_FEATURE_HT & 31, &edx);
    2.20          ebx &= 0xFF00FFFF;  /* clear the logical processor count when HTT=0 */
    2.21          ebx |= 0x00010000;  /* set to 1 just for precaution */
    2.22 -    }
    2.23 -    else if ( input == 0x80000001 )
    2.24 -    {
    2.25 +        break;
    2.26 +
    2.27 +    case 0x80000001:
    2.28          if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
    2.29 -            clear_bit(X86_FEATURE_APIC & 31, &edx);
    2.30 +            __clear_bit(X86_FEATURE_APIC & 31, &edx);
    2.31  
    2.32  #if CONFIG_PAGING_LEVELS >= 3
    2.33          if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
    2.34  #endif
    2.35 -            clear_bit(X86_FEATURE_PAE & 31, &edx);
    2.36 +            __clear_bit(X86_FEATURE_PAE & 31, &edx);
    2.37  
    2.38 -        clear_bit(X86_FEATURE_PSE36 & 31, &edx);
    2.39 +        __clear_bit(X86_FEATURE_PSE36 & 31, &edx);
    2.40  
    2.41          /* Clear the Cmp_Legacy bit
    2.42           * This bit is supposed to be zero when HTT = 0.
    2.43           * See details on page 23 of AMD CPUID Specification.
    2.44           */
    2.45 -        clear_bit(X86_FEATURE_CMP_LEGACY & 31, &ecx);
    2.46 +        __clear_bit(X86_FEATURE_CMP_LEGACY & 31, &ecx);
    2.47  
    2.48          /* Make SVM feature invisible to the guest. */
    2.49 -        clear_bit(X86_FEATURE_SVME & 31, &ecx);
    2.50 +        __clear_bit(X86_FEATURE_SVME & 31, &ecx);
    2.51 +        __clear_bit(X86_FEATURE_SKINIT & 31, &ecx);
    2.52 +
    2.53 +        __clear_bit(X86_FEATURE_OSVW & 31, &ecx);
    2.54 +        __clear_bit(X86_FEATURE_WDT & 31, &ecx);
    2.55  
    2.56          /* So far, we do not support 3DNow for the guest. */
    2.57 -        clear_bit(X86_FEATURE_3DNOW & 31, &edx);
    2.58 -        clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx);
    2.59 -    }
    2.60 -    else if ( input == 0x80000007 || input == 0x8000000A )
    2.61 -    {
    2.62 +        __clear_bit(X86_FEATURE_3DNOW & 31, &edx);
    2.63 +        __clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx);
    2.64 +        break;
    2.65 +
    2.66 +    case 0x80000007:
    2.67 +    case 0x8000000A:
    2.68          /* Mask out features of power management and SVM extension. */
    2.69          eax = ebx = ecx = edx = 0;
    2.70 -    }
    2.71 -    else if ( input == 0x80000008 )
    2.72 -    {
    2.73 +        break;
    2.74 +
    2.75 +    case 0x80000008:
    2.76          /* Make sure Number of CPU core is 1 when HTT=0 */
    2.77          ecx &= 0xFFFFFF00;
    2.78 +        break;
    2.79      }
    2.80  
    2.81 -    regs->eax = (unsigned long)eax;
    2.82 -    regs->ebx = (unsigned long)ebx;
    2.83 -    regs->ecx = (unsigned long)ecx;
    2.84 -    regs->edx = (unsigned long)edx;
    2.85 +    regs->eax = eax;
    2.86 +    regs->ebx = ebx;
    2.87 +    regs->ecx = ecx;
    2.88 +    regs->edx = edx;
    2.89  
    2.90      HVMTRACE_3D(CPUID, v, input,
    2.91                  ((uint64_t)eax << 32) | ebx, ((uint64_t)ecx << 32) | edx);
     3.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Oct 12 11:20:28 2007 +0100
     3.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Oct 12 11:42:56 2007 +0100
     3.3 @@ -1253,16 +1253,10 @@ static void vmx_do_no_device_fault(void)
     3.4  #define bitmaskof(idx)  (1U << ((idx) & 31))
     3.5  static void vmx_do_cpuid(struct cpu_user_regs *regs)
     3.6  {
     3.7 -    unsigned int input = (unsigned int)regs->eax;
     3.8 -    unsigned int count = (unsigned int)regs->ecx;
     3.9 +    unsigned int input = regs->eax;
    3.10      unsigned int eax, ebx, ecx, edx;
    3.11  
    3.12 -    if ( input == 0x00000004 )
    3.13 -    {
    3.14 -        cpuid_count(input, count, &eax, &ebx, &ecx, &edx);
    3.15 -        eax &= NUM_CORES_RESET_MASK;
    3.16 -    }
    3.17 -    else if ( input == 0x40000003 )
    3.18 +    if ( input == 0x40000003 )
    3.19      {
    3.20          /*
    3.21           * NB. Unsupported interface for private use of VMXASSIST only.
    3.22 @@ -1292,37 +1286,44 @@ static void vmx_do_cpuid(struct cpu_user
    3.23          unmap_domain_page(p);
    3.24  
    3.25          gdprintk(XENLOG_INFO, "Output value is 0x%"PRIx64".\n", value);
    3.26 -        ecx = (u32)value;
    3.27 -        edx = (u32)(value >> 32);
    3.28 -    } else {
    3.29 -        hvm_cpuid(input, &eax, &ebx, &ecx, &edx);
    3.30 -
    3.31 -        if ( input == 0x00000001 )
    3.32 -        {
    3.33 -            /* Mask off reserved bits. */
    3.34 -            ecx &= ~VMX_VCPU_CPUID_L1_ECX_RESERVED;
    3.35 -
    3.36 -            ebx &= NUM_THREADS_RESET_MASK;
    3.37 -
    3.38 -            /* Unsupportable for virtualised CPUs. */
    3.39 -            ecx &= ~(bitmaskof(X86_FEATURE_VMXE) |
    3.40 -                     bitmaskof(X86_FEATURE_EST)  |
    3.41 -                     bitmaskof(X86_FEATURE_TM2)  |
    3.42 -                     bitmaskof(X86_FEATURE_CID));
    3.43 -
    3.44 -            edx &= ~(bitmaskof(X86_FEATURE_HT)   |
    3.45 -                     bitmaskof(X86_FEATURE_ACPI) |
    3.46 -                     bitmaskof(X86_FEATURE_ACC));
    3.47 -        }
    3.48 -
    3.49 -        if ( input == 0x00000006 || input == 0x00000009 || input == 0x0000000A )
    3.50 -            eax = ebx = ecx = edx = 0x0;
    3.51 +        regs->ecx = (u32)value;
    3.52 +        regs->edx = (u32)(value >> 32);
    3.53 +        return;
    3.54      }
    3.55  
    3.56 -    regs->eax = (unsigned long)eax;
    3.57 -    regs->ebx = (unsigned long)ebx;
    3.58 -    regs->ecx = (unsigned long)ecx;
    3.59 -    regs->edx = (unsigned long)edx;
    3.60 +    hvm_cpuid(input, &eax, &ebx, &ecx, &edx);
    3.61 +
    3.62 +    switch ( input )
    3.63 +    {
    3.64 +    case 0x00000001:
    3.65 +        ecx &= ~VMX_VCPU_CPUID_L1_ECX_RESERVED;
    3.66 +        ebx &= NUM_THREADS_RESET_MASK;
    3.67 +        ecx &= ~(bitmaskof(X86_FEATURE_VMXE) |
    3.68 +                 bitmaskof(X86_FEATURE_EST)  |
    3.69 +                 bitmaskof(X86_FEATURE_TM2)  |
    3.70 +                 bitmaskof(X86_FEATURE_CID)  |
    3.71 +                 bitmaskof(X86_FEATURE_PDCM));
    3.72 +        edx &= ~(bitmaskof(X86_FEATURE_HT)   |
    3.73 +                 bitmaskof(X86_FEATURE_ACPI) |
    3.74 +                 bitmaskof(X86_FEATURE_ACC));
    3.75 +        break;
    3.76 +
    3.77 +    case 0x00000004:
    3.78 +        cpuid_count(input, regs->ecx, &eax, &ebx, &ecx, &edx);
    3.79 +        eax &= NUM_CORES_RESET_MASK;
    3.80 +        break;
    3.81 +
    3.82 +    case 0x00000006:
    3.83 +    case 0x00000009:
    3.84 +    case 0x0000000A:
    3.85 +        eax = ebx = ecx = edx = 0;
    3.86 +        break;
    3.87 +    }
    3.88 +
    3.89 +    regs->eax = eax;
    3.90 +    regs->ebx = ebx;
    3.91 +    regs->ecx = ecx;
    3.92 +    regs->edx = edx;
    3.93  
    3.94      HVMTRACE_3D(CPUID, current, input,
    3.95                  ((uint64_t)eax << 32) | ebx, ((uint64_t)ecx << 32) | edx);
     4.1 --- a/xen/include/asm-x86/cpufeature.h	Fri Oct 12 11:20:28 2007 +0100
     4.2 +++ b/xen/include/asm-x86/cpufeature.h	Fri Oct 12 11:42:56 2007 +0100
     4.3 @@ -81,9 +81,15 @@
     4.4  #define X86_FEATURE_SMXE	(4*32+ 6) /* Safer Mode Extensions */
     4.5  #define X86_FEATURE_EST		(4*32+ 7) /* Enhanced SpeedStep */
     4.6  #define X86_FEATURE_TM2		(4*32+ 8) /* Thermal Monitor 2 */
     4.7 +#define X86_FEATURE_SSSE3	(4*32+ 9) /* Supplemental Streaming SIMD Extensions-3 */
     4.8  #define X86_FEATURE_CID		(4*32+10) /* Context ID */
     4.9  #define X86_FEATURE_CX16        (4*32+13) /* CMPXCHG16B */
    4.10  #define X86_FEATURE_XTPR	(4*32+14) /* Send Task Priority Messages */
    4.11 +#define X86_FEATURE_PDCM	(4*32+15) /* Perf/Debug Capability MSR */
    4.12 +#define X86_FEATURE_DCA		(4*32+18) /* Direct Cache Access */
    4.13 +#define X86_FEATURE_SSE4_1	(4*32+19) /* Streaming SIMD Extensions 4.1 */
    4.14 +#define X86_FEATURE_SSE4_2	(4*32+20) /* Streaming SIMD Extensions 4.2 */
    4.15 +#define X86_FEATURE_POPCNT	(4*32+23) /* POPCNT instruction */
    4.16  
    4.17  /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
    4.18  #define X86_FEATURE_XSTORE	(5*32+ 2) /* on-CPU RNG present (xstore insn) */
    4.19 @@ -101,6 +107,15 @@
    4.20  #define X86_FEATURE_LAHF_LM	(6*32+ 0) /* LAHF/SAHF in long mode */
    4.21  #define X86_FEATURE_CMP_LEGACY	(6*32+ 1) /* If yes HyperThreading not valid */
    4.22  #define X86_FEATURE_SVME        (6*32+ 2) /* Secure Virtual Machine */
    4.23 +#define X86_FEATURE_EXTAPICSPACE (6*32+ 3) /* Extended APIC space */
    4.24 +#define X86_FEATURE_ALTMOVCR	(6*32+ 4) /* LOCK MOV CR accesses CR+8 */
    4.25 +#define X86_FEATURE_ABM		(6*32+ 5) /* Advanced Bit Manipulation */
    4.26 +#define X86_FEATURE_SSE4A	(6*32+ 6) /* AMD Streaming SIMD Extensions-4a */
    4.27 +#define X86_FEATURE_MISALIGNSSE	(6*32+ 7) /* Misaligned SSE Access */
    4.28 +#define X86_FEATURE_3DNOWPF	(6*32+ 8) /* 3DNow! Prefetch */
    4.29 +#define X86_FEATURE_OSVW	(6*32+ 9) /* OS Visible Workaround */
    4.30 +#define X86_FEATURE_SKINIT	(6*32+ 12) /* SKINIT, STGI/CLGI, DEV */
    4.31 +#define X86_FEATURE_WDT		(6*32+ 13) /* Watchdog Timer */
    4.32  
    4.33  #define cpu_has(c, bit)		test_bit(bit, (c)->x86_capability)
    4.34  #define boot_cpu_has(bit)	test_bit(bit, boot_cpu_data.x86_capability)