diff options
author | cegger <none@none> | 2011-02-28 12:21:38 +0100 |
---|---|---|
committer | cegger <none@none> | 2011-02-28 12:21:38 +0100 |
commit | 567ab9ef5644ca4ed77ed6605d004527e818077e (patch) | |
tree | 32b4253587a885c62bb485ebfc631dc2cefcbec3 /tools/libxc/xc_cpuid_x86.c | |
parent | 347f5536686b04b7214488ffef2129a05848e761 (diff) | |
download | xen-567ab9ef5644ca4ed77ed6605d004527e818077e.tar.gz xen-567ab9ef5644ca4ed77ed6605d004527e818077e.tar.bz2 xen-567ab9ef5644ca4ed77ed6605d004527e818077e.zip |
tools: Add nestedhvm guest config option
Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
Acked-by: Tim Deegan <Tim.Deegan@citrix.com>
Committed-by: Tim Deegan <Tim.Deegan@citrix.com>
Diffstat (limited to 'tools/libxc/xc_cpuid_x86.c')
-rw-r--r-- | tools/libxc/xc_cpuid_x86.c | 75 |
1 files changed, 66 insertions, 9 deletions
diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c index 150ca18066..c62e98d7ea 100644 --- a/tools/libxc/xc_cpuid_x86.c +++ b/tools/libxc/xc_cpuid_x86.c @@ -30,7 +30,8 @@ #define set_bit(idx, dst) ((dst) |= (1u << ((idx) & 31))) #define DEF_MAX_BASE 0x0000000du -#define DEF_MAX_EXT 0x80000008u +#define DEF_MAX_INTELEXT 0x80000008u +#define DEF_MAX_AMDEXT 0x8000000au static int hypervisor_is_64bit(xc_interface *xch) { @@ -78,7 +79,7 @@ static void xc_cpuid_brand_get(char *str) static void amd_xc_cpuid_policy( xc_interface *xch, domid_t domid, const unsigned int *input, unsigned int *regs, - int is_pae) + int is_pae, int is_nestedhvm) { switch ( input[0] ) { @@ -87,6 +88,11 @@ static void amd_xc_cpuid_policy( regs[0] = regs[1] = regs[2] = 0; break; + case 0x80000000: + if ( regs[0] > DEF_MAX_AMDEXT ) + regs[0] = DEF_MAX_AMDEXT; + break; + case 0x80000001: { int is_64bit = hypervisor_is_64bit(xch) && is_pae; @@ -97,6 +103,7 @@ static void amd_xc_cpuid_policy( /* Filter all other features according to a whitelist. */ regs[2] &= ((is_64bit ? bitmaskof(X86_FEATURE_LAHF_LM) : 0) | bitmaskof(X86_FEATURE_CMP_LEGACY) | + (is_nestedhvm ? bitmaskof(X86_FEATURE_SVM) : 0) | bitmaskof(X86_FEATURE_CR8_LEGACY) | bitmaskof(X86_FEATURE_ABM) | bitmaskof(X86_FEATURE_SSE4A) | @@ -124,16 +131,50 @@ static void amd_xc_cpuid_policy( */ regs[2] = ((regs[2] & 0xf000u) + 1) | ((regs[2] & 0xffu) << 1) | 1u; break; + + case 0x8000000a: { + if (!is_nestedhvm) { + regs[0] = regs[1] = regs[2] = regs[3] = 0; + break; + } + +#define SVM_FEATURE_NPT 0x00000001 /* Nested page table support */ +#define SVM_FEATURE_LBRV 0x00000002 /* LBR virtualization support */ +#define SVM_FEATURE_SVML 0x00000004 /* SVM locking MSR support */ +#define SVM_FEATURE_NRIPS 0x00000008 /* Next RIP save on VMEXIT */ +#define SVM_FEATURE_TSCRATEMSR 0x00000010 /* TSC ratio MSR support */ +#define SVM_FEATURE_VMCBCLEAN 0x00000020 /* VMCB clean bits support */ +#define SVM_FEATURE_FLUSHBYASID 0x00000040 /* TLB flush by ASID support */ +#define SVM_FEATURE_DECODEASSISTS 0x00000080 /* Decode assists support */ +#define SVM_FEATURE_PAUSEFILTER 0x00000400 /* Pause intercept filter */ + + /* Pass 1: Only passthrough SVM features which are + * available in hw and which are implemented + */ + regs[3] &= (SVM_FEATURE_NPT | SVM_FEATURE_LBRV | \ + SVM_FEATURE_NRIPS | SVM_FEATURE_PAUSEFILTER); + + /* Pass 2: Always enable SVM features which are emulated */ + regs[3] |= SVM_FEATURE_VMCBCLEAN; + break; + } + } } static void intel_xc_cpuid_policy( xc_interface *xch, domid_t domid, const unsigned int *input, unsigned int *regs, - int is_pae) + int is_pae, int is_nestedhvm) { switch ( input[0] ) { + case 0x00000001: + /* ECX[5] is availability of VMX */ + if (is_nestedhvm) + set_bit(X86_FEATURE_VMXE, regs[2]); + break; + case 0x00000004: /* * EAX[31:26] is Maximum Cores Per Package (minus one). @@ -144,6 +185,11 @@ static void intel_xc_cpuid_policy( regs[3] &= 0x3ffu; break; + case 0x80000000: + if ( regs[0] > DEF_MAX_INTELEXT ) + regs[0] = DEF_MAX_INTELEXT; + break; + case 0x80000001: { int is_64bit = hypervisor_is_64bit(xch) && is_pae; @@ -225,8 +271,9 @@ static void xc_cpuid_hvm_policy( { DECLARE_DOMCTL; char brand[13]; + unsigned long nestedhvm; unsigned long pae; - int is_pae; + int is_pae, is_nestedhvm; uint64_t xfeature_mask; xc_get_hvm_param(xch, domid, HVM_PARAM_PAE_ENABLED, &pae); @@ -239,6 +286,9 @@ static void xc_cpuid_hvm_policy( do_domctl(xch, &domctl); xfeature_mask = domctl.u.vcpuextstate.xfeature_mask; + xc_get_hvm_param(xch, domid, HVM_PARAM_NESTEDHVM, &nestedhvm); + is_nestedhvm = !!nestedhvm; + switch ( input[0] ) { case 0x00000000: @@ -305,8 +355,7 @@ static void xc_cpuid_hvm_policy( break; case 0x80000000: - if ( regs[0] > DEF_MAX_EXT ) - regs[0] = DEF_MAX_EXT; + /* Passthrough to cpu vendor specific functions */ break; case 0x80000001: @@ -335,6 +384,7 @@ static void xc_cpuid_hvm_policy( case 0x80000004: /* ... continued */ case 0x80000005: /* AMD L1 cache/TLB info (dumped by Intel policy) */ case 0x80000006: /* AMD L2/3 cache/TLB info ; Intel L2 cache features */ + case 0x8000000a: /* AMD SVM feature bits */ break; default: @@ -344,9 +394,9 @@ static void xc_cpuid_hvm_policy( xc_cpuid_brand_get(brand); if ( strstr(brand, "AMD") ) - amd_xc_cpuid_policy(xch, domid, input, regs, is_pae); + amd_xc_cpuid_policy(xch, domid, input, regs, is_pae, is_nestedhvm); else - intel_xc_cpuid_policy(xch, domid, input, regs, is_pae); + intel_xc_cpuid_policy(xch, domid, input, regs, is_pae, is_nestedhvm); } @@ -507,13 +557,20 @@ int xc_cpuid_apply_policy(xc_interface *xch, domid_t domid) { unsigned int input[2] = { 0, 0 }, regs[4]; unsigned int base_max, ext_max; + char brand[13]; int rc; + cpuid(input, regs); base_max = (regs[0] <= DEF_MAX_BASE) ? regs[0] : DEF_MAX_BASE; input[0] = 0x80000000; cpuid(input, regs); - ext_max = (regs[0] <= DEF_MAX_EXT) ? regs[0] : DEF_MAX_EXT; + + xc_cpuid_brand_get(brand); + if ( strstr(brand, "AMD") ) + ext_max = (regs[0] <= DEF_MAX_AMDEXT) ? regs[0] : DEF_MAX_AMDEXT; + else + ext_max = (regs[0] <= DEF_MAX_INTELEXT) ? regs[0] : DEF_MAX_INTELEXT; input[0] = 0; input[1] = XEN_CPUID_INPUT_UNUSED; |