[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [SVM] Fix virtualization of the CPUID NX bit, and clean up other CPUID bits.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID e5de45e2edaf8d7947d70666b9772315e68cebb0 # Parent ec1e371ec3208f771595da6c82baae4cd9a441f5 [SVM] Fix virtualization of the CPUID NX bit, and clean up other CPUID bits. Signed-off-by: Tom Woller <thomas.woller@xxxxxxx> Signed-off-by: Wei Huang <wei.huang2@xxxxxxx> --- xen/arch/x86/hvm/svm/svm.c | 101 ++++++++++++++++++++++++++++++++++++--------- 1 files changed, 83 insertions(+), 18 deletions(-) diff -r ec1e371ec320 -r e5de45e2edaf xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Wed May 31 07:25:59 2006 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Wed May 31 07:28:43 2006 +0100 @@ -950,8 +950,10 @@ static void svm_do_general_protection_fa svm_inject_exception(v, TRAP_gp_fault, 1, error_code); } -/* Reserved bits: [31:14], [12:1] */ -#define SVM_VCPU_CPUID_L1_RESERVED 0xffffdffe +/* Reserved bits ECX: [31:14], [12:4], [2:1]*/ +#define SVM_VCPU_CPUID_L1_ECX_RESERVED 0xffffdff6 +/* Reserved bits EDX: [31:29], [27], [22:20], [18], [10] */ +#define SVM_VCPU_CPUID_L1_EDX_RESERVED 0xe8740400 static void svm_vmexit_do_cpuid(struct vmcb_struct *vmcb, unsigned long input, struct cpu_user_regs *regs) @@ -974,20 +976,17 @@ static void svm_vmexit_do_cpuid(struct v cpuid(input, &eax, &ebx, &ecx, &edx); - if (input == 1) + if (input == 0x00000001) { if ( !hvm_apic_support(v->domain) || !vlapic_global_enabled((VLAPIC(v))) ) { - clear_bit(X86_FEATURE_APIC, &edx); - /* Since the apic is disabled, avoid any confusion about SMP cpus being available */ - clear_bit(X86_FEATURE_HT, &edx); /* clear the hyperthread bit */ - ebx &= 0xFF00FFFF; /* set the logical processor count to 1 */ - ebx |= 0x00010000; - } - + /* Since the apic is disabled, avoid any confusion + about SMP cpus being available */ + clear_bit(X86_FEATURE_APIC, &edx); + } + #if CONFIG_PAGING_LEVELS < 3 - clear_bit(X86_FEATURE_NX, &edx); clear_bit(X86_FEATURE_PAE, &edx); clear_bit(X86_FEATURE_PSE, &edx); clear_bit(X86_FEATURE_PSE36, &edx); @@ -996,24 +995,90 @@ static void svm_vmexit_do_cpuid(struct v { if ( !v->domain->arch.hvm_domain.pae_enabled ) { - clear_bit(X86_FEATURE_PAE, &edx); - clear_bit(X86_FEATURE_NX, &edx); + clear_bit(X86_FEATURE_PAE, &edx); } clear_bit(X86_FEATURE_PSE, &edx); clear_bit(X86_FEATURE_PSE36, &edx); } #endif /* Clear out reserved bits. */ - ecx &= ~SVM_VCPU_CPUID_L1_RESERVED; /* mask off reserved bits */ + ecx &= ~SVM_VCPU_CPUID_L1_ECX_RESERVED; + edx &= ~SVM_VCPU_CPUID_L1_EDX_RESERVED; + clear_bit(X86_FEATURE_MWAIT & 31, &ecx); - } + + /* Guest should only see one logical processor. + * See details on page 23 of AMD CPUID Specification. + */ + clear_bit(X86_FEATURE_HT, &edx); /* clear the hyperthread bit */ + ebx &= 0xFF00FFFF; /* clear the logical processor count when HTT=0 */ + ebx |= 0x00010000; /* set to 1 just for precaution */ + } + else if ( ( input > 0x00000005 ) && ( input < 0x80000000 ) ) + { + eax = ebx = ecx = edx = 0x0; + } + else if ( input == 0x80000001 ) + { + /* We duplicate some CPUID_00000001 code because many bits of + CPUID_80000001_EDX overlaps with CPUID_00000001_EDX. */ + + if ( !hvm_apic_support(v->domain) || + !vlapic_global_enabled((VLAPIC(v))) ) + { + /* Since the apic is disabled, avoid any confusion + about SMP cpus being available */ + clear_bit(X86_FEATURE_APIC, &edx); + } + + /* Clear the Cmp_Legacy bit + * This bit is supposed to be zero when HTT = 0. + * See details on page 23 of AMD CPUID Specification. + */ + clear_bit(X86_FEATURE_CMP_LEGACY & 31, &ecx); + #ifdef __i386__ - else if ( input == 0x80000001 ) - { /* Mask feature for Intel ia32e or AMD long mode. */ + clear_bit(X86_FEATURE_LAHF_LM & 31, &ecx); + clear_bit(X86_FEATURE_LM & 31, &edx); - } + clear_bit(X86_FEATURE_SYSCALL & 31, &edx); #endif + +#if CONFIG_PAGING_LEVELS < 3 + clear_bit(X86_FEATURE_NX & 31, &edx); + clear_bit(X86_FEATURE_PAE, &edx); + clear_bit(X86_FEATURE_PSE, &edx); + clear_bit(X86_FEATURE_PSE36, &edx); +#else + if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 ) + { + if ( !v->domain->arch.hvm_domain.pae_enabled ) + { + clear_bit(X86_FEATURE_NX & 31, &edx); + clear_bit(X86_FEATURE_PAE, &edx); + } + clear_bit(X86_FEATURE_PSE, &edx); + clear_bit(X86_FEATURE_PSE36, &edx); + } +#endif + + /* Make SVM feature invisible to the guest. */ + clear_bit(X86_FEATURE_SVME & 31, &ecx); + + /* So far, we do not support 3DNow for the guest. */ + clear_bit(X86_FEATURE_3DNOW & 31, &edx); + clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx); + } + else if ( ( input == 0x80000007 ) || ( input == 0x8000000A ) ) + { + /* Mask out features of power management and SVM extension. */ + eax = ebx = ecx = edx = 0; + } + else if ( input == 0x80000008 ) + { + ecx &= 0xFFFFFF00; /* Make sure Number of CPU core is 1 when HTT=0 */ + } regs->eax = (unsigned long)eax; regs->ebx = (unsigned long)ebx; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |