ia64/xen-unstable

changeset 17777:7155d82576a4

xc hvm: Fix default CPUID features according to PAE/64-bit
capabilities of the guest and of the hypervisor.

Based on a patch by Juergen Keil <jk@tools.de>

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Jun 02 16:00:45 2008 +0100 (2008-06-02)
parents b9879d710825
children fe60bf79d96f
files tools/libxc/xc_cpuid_x86.c
line diff
     1.1 --- a/tools/libxc/xc_cpuid_x86.c	Mon Jun 02 10:56:52 2008 +0100
     1.2 +++ b/tools/libxc/xc_cpuid_x86.c	Mon Jun 02 16:00:45 2008 +0100
     1.3 @@ -31,13 +31,17 @@
     1.4  #define DEF_MAX_BASE 0x00000004u
     1.5  #define DEF_MAX_EXT  0x80000008u
     1.6  
     1.7 -static void amd_xc_cpuid_policy(
     1.8 -    int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
     1.9 +static int hypervisor_is_64bit(int xc)
    1.10  {
    1.11 -    unsigned long pae = 0;
    1.12 +    xen_capabilities_info_t xen_caps = "";
    1.13 +    return ((xc_version(xc, XENVER_capabilities, &xen_caps) == 0) &&
    1.14 +            (strstr(xen_caps, "x86_64") != NULL));
    1.15 +}
    1.16  
    1.17 -    xc_get_hvm_param(xc, domid, HVM_PARAM_PAE_ENABLED, &pae);
    1.18 -
    1.19 +static void amd_xc_cpuid_policy(
    1.20 +    int xc, domid_t domid, const unsigned int *input, unsigned int *regs,
    1.21 +    int is_pae)
    1.22 +{
    1.23      switch ( input[0] )
    1.24      {
    1.25      case 0x00000001:
    1.26 @@ -52,21 +56,23 @@ static void amd_xc_cpuid_policy(
    1.27          regs[0] = regs[1] = regs[2] = 0;
    1.28          break;
    1.29  
    1.30 -    case 0x80000001:
    1.31 -        if ( !pae )
    1.32 +    case 0x80000001: {
    1.33 +        int is_64bit = hypervisor_is_64bit(xc) && is_pae;
    1.34 +
    1.35 +        if ( !is_pae )
    1.36              clear_bit(X86_FEATURE_PAE & 31, regs[3]);
    1.37          clear_bit(X86_FEATURE_PSE36 & 31, regs[3]);
    1.38  
    1.39          /* Filter all other features according to a whitelist. */
    1.40 -        regs[2] &= (bitmaskof(X86_FEATURE_LAHF_LM) |
    1.41 +        regs[2] &= ((is_64bit ? bitmaskof(X86_FEATURE_LAHF_LM) : 0) |
    1.42                      bitmaskof(X86_FEATURE_ALTMOVCR) |
    1.43                      bitmaskof(X86_FEATURE_ABM) |
    1.44                      bitmaskof(X86_FEATURE_SSE4A) |
    1.45                      bitmaskof(X86_FEATURE_MISALIGNSSE) |
    1.46                      bitmaskof(X86_FEATURE_3DNOWPF));
    1.47          regs[3] &= (0x0183f3ff | /* features shared with 0x00000001:EDX */
    1.48 -                    bitmaskof(X86_FEATURE_NX) |
    1.49 -                    bitmaskof(X86_FEATURE_LM) |
    1.50 +                    (is_pae ? bitmaskof(X86_FEATURE_NX) : 0) |
    1.51 +                    (is_64bit ? bitmaskof(X86_FEATURE_LM) : 0) |
    1.52                      bitmaskof(X86_FEATURE_SYSCALL) |
    1.53                      bitmaskof(X86_FEATURE_MP) |
    1.54                      bitmaskof(X86_FEATURE_MMXEXT) |
    1.55 @@ -75,10 +81,12 @@ static void amd_xc_cpuid_policy(
    1.56                      bitmaskof(X86_FEATURE_3DNOWEXT));
    1.57          break;
    1.58      }
    1.59 +    }
    1.60  }
    1.61  
    1.62  static void intel_xc_cpuid_policy(
    1.63 -    int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
    1.64 +    int xc, domid_t domid, const unsigned int *input, unsigned int *regs,
    1.65 +    int is_pae)
    1.66  {
    1.67      switch ( input[0] )
    1.68      {
    1.69 @@ -92,14 +100,17 @@ static void intel_xc_cpuid_policy(
    1.70          regs[3] &= 0x3FF;
    1.71          break;
    1.72  
    1.73 -    case 0x80000001:
    1.74 +    case 0x80000001: {
    1.75 +        int is_64bit = hypervisor_is_64bit(xc) && is_pae;
    1.76 +
    1.77          /* Only a few features are advertised in Intel's 0x80000001. */
    1.78 -        regs[2] &= (bitmaskof(X86_FEATURE_LAHF_LM));
    1.79 -        regs[3] &= (bitmaskof(X86_FEATURE_NX) |
    1.80 -                    bitmaskof(X86_FEATURE_LM) |
    1.81 -                    bitmaskof(X86_FEATURE_SYSCALL));
    1.82 +        regs[2] &= (is_64bit ? bitmaskof(X86_FEATURE_LAHF_LM) : 0);
    1.83 +        regs[3] &= ((is_pae ? bitmaskof(X86_FEATURE_NX) : 0) |
    1.84 +                    (is_64bit ? bitmaskof(X86_FEATURE_LM) : 0) |
    1.85 +                    (is_64bit ? bitmaskof(X86_FEATURE_SYSCALL) : 0));
    1.86          break;
    1.87      }
    1.88 +    }
    1.89  }
    1.90  
    1.91  static void cpuid(const unsigned int *input, unsigned int *regs)
    1.92 @@ -212,9 +223,9 @@ static void xc_cpuid_policy(
    1.93  
    1.94      xc_cpuid_brand_get(brand);
    1.95      if ( strstr(brand, "AMD") )
    1.96 -        amd_xc_cpuid_policy(xc, domid, input, regs);
    1.97 +        amd_xc_cpuid_policy(xc, domid, input, regs, !!pae);
    1.98      else
    1.99 -        intel_xc_cpuid_policy(xc, domid, input, regs);
   1.100 +        intel_xc_cpuid_policy(xc, domid, input, regs, !!pae);
   1.101  }
   1.102  
   1.103  static int xc_cpuid_do_domctl(