[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.