[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [HVM] Clean up CPUID handling.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1166609382 0
# Node ID f99dd72ae205556994f3ea5ff065c6cfb02c42d0
# Parent  1818b322ede953f4fcca2d3d1239ce5111a811c5
[HVM] Clean up CPUID handling.
From: Xin B Li <xin.b.li@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c            |   41 +++++++++++
 xen/arch/x86/hvm/svm/svm.c        |  136 ++++++++++++++------------------------
 xen/arch/x86/hvm/vmx/vmx.c        |   96 +++++++-------------------
 xen/include/asm-x86/hvm/hvm.h     |    2 
 xen/include/asm-x86/hvm/vmx/cpu.h |   13 ---
 5 files changed, 124 insertions(+), 164 deletions(-)

diff -r 1818b322ede9 -r f99dd72ae205 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Wed Dec 20 10:06:33 2006 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Wed Dec 20 10:09:42 2006 +0000
@@ -400,6 +400,47 @@ void hvm_print_line(struct vcpu *v, cons
         hd->pbuf_idx = 0;
     }
     spin_unlock(&hd->pbuf_lock);
+}
+
+void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
+                                   unsigned int *ecx, unsigned int *edx)
+{
+    if ( !cpuid_hypervisor_leaves(input, eax, ebx, ecx, edx) )
+    {
+        cpuid(input, eax, ebx, ecx, edx);
+
+        if ( input == 0x00000001 )
+        {
+            struct vcpu *v = current;
+
+            clear_bit(X86_FEATURE_MWAIT & 31, ecx);
+
+            if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
+                clear_bit(X86_FEATURE_APIC & 31, edx);
+
+#if CONFIG_PAGING_LEVELS >= 3
+            if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
+#endif
+                clear_bit(X86_FEATURE_PAE & 31, edx);
+
+            clear_bit(X86_FEATURE_PSE36 & 31, edx);
+        }
+        else if ( input == 0x80000001 )
+        {
+#if CONFIG_PAGING_LEVELS >= 3
+            struct vcpu *v = current;
+            if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
+#endif
+                clear_bit(X86_FEATURE_NX & 31, edx);
+#ifdef __i386__
+            /* 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
+        }
+    }
 }
 
 typedef unsigned long hvm_hypercall_t(
diff -r 1818b322ede9 -r f99dd72ae205 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Wed Dec 20 10:06:33 2006 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Wed Dec 20 10:09:42 2006 +0000
@@ -999,91 +999,65 @@ static void svm_do_general_protection_fa
 /* 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) 
-{
+static void svm_vmexit_do_cpuid(struct vmcb_struct *vmcb,
+                                struct cpu_user_regs *regs)
+{
+    unsigned long input = regs->eax;
     unsigned int eax, ebx, ecx, edx;
-    unsigned long eip;
     struct vcpu *v = current;
     int inst_len;
 
     ASSERT(vmcb);
 
-    eip = vmcb->rip;
-
-    HVM_DBG_LOG(DBG_LEVEL_1, 
-                "do_cpuid: (eax) %lx, (ebx) %lx, (ecx) %lx, (edx) %lx,"
-                " (esi) %lx, (edi) %lx",
-                (unsigned long)regs->eax, (unsigned long)regs->ebx,
-                (unsigned long)regs->ecx, (unsigned long)regs->edx,
-                (unsigned long)regs->esi, (unsigned long)regs->edi);
-
-    if ( !cpuid_hypervisor_leaves(input, &eax, &ebx, &ecx, &edx) )
-    {
-        cpuid(input, &eax, &ebx, &ecx, &edx);       
-        if (input == 0x00000001 || input == 0x80000001 )
-        {
-            if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
-            {
-                /* Since the apic is disabled, avoid any confusion 
-                   about SMP cpus being available */
-                clear_bit(X86_FEATURE_APIC, &edx);
-            }
+    hvm_cpuid(input, &eax, &ebx, &ecx, &edx);
+
+    if ( input == 0x00000001 )
+    {
+        /* Clear out reserved bits. */
+        ecx &= ~SVM_VCPU_CPUID_L1_ECX_RESERVED;
+        edx &= ~SVM_VCPU_CPUID_L1_EDX_RESERVED;
+
+        /* Guest should only see one logical processor.
+         * See details on page 23 of AMD CPUID Specification.
+         */
+        clear_bit(X86_FEATURE_HT & 31, &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 == 0x80000001 )
+    {
+        if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
+            clear_bit(X86_FEATURE_APIC & 31, &edx);
+
 #if CONFIG_PAGING_LEVELS >= 3
-            if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
+        if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
 #endif
-            {
-                clear_bit(X86_FEATURE_PAE, &edx);
-                if (input == 0x80000001 )
-                   clear_bit(X86_FEATURE_NX & 31, &edx);
-            }
-            clear_bit(X86_FEATURE_PSE36, &edx);
-            if (input == 0x00000001 )
-            {
-                /* Clear out 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
-            {
-                /* 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);
-                /* Make SVM feature invisible to the guest. */
-                clear_bit(X86_FEATURE_SVME & 31, &ecx);
-#ifdef __i386__
-                /* 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
-                /* 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 )
-        {
-            /* Make sure Number of CPU core is 1 when HTT=0 */
-            ecx &= 0xFFFFFF00; 
-        }
+            clear_bit(X86_FEATURE_PAE & 31, &edx);
+
+        clear_bit(X86_FEATURE_PSE36 & 31, &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);
+
+        /* 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 )
+    {
+        /* Make sure Number of CPU core is 1 when HTT=0 */
+        ecx &= 0xFFFFFF00;
     }
 
     regs->eax = (unsigned long)eax;
@@ -1091,16 +1065,10 @@ static void svm_vmexit_do_cpuid(struct v
     regs->ecx = (unsigned long)ecx;
     regs->edx = (unsigned long)edx;
 
-    HVM_DBG_LOG(DBG_LEVEL_1, 
-                "svm_vmexit_do_cpuid: eip: %lx, input: %lx, out:eax=%x, "
-                "ebx=%x, ecx=%x, edx=%x",
-                eip, input, eax, ebx, ecx, edx);
-
     inst_len = __get_instruction_length(vmcb, INSTR_CPUID, NULL);
     ASSERT(inst_len > 0);
     __update_guest_eip(vmcb, inst_len);
 }
-
 
 static inline unsigned long *get_reg_p(unsigned int gpreg, 
                                        struct cpu_user_regs *regs, struct 
vmcb_struct *vmcb)
@@ -2828,7 +2796,7 @@ asmlinkage void svm_vmexit_handler(struc
         goto exit_and_crash;
 
     case VMEXIT_CPUID:
-        svm_vmexit_do_cpuid(vmcb, regs->eax, regs);
+        svm_vmexit_do_cpuid(vmcb, regs);
         break;
 
     case VMEXIT_HLT:
diff -r 1818b322ede9 -r f99dd72ae205 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Wed Dec 20 10:06:33 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Wed Dec 20 10:09:42 2006 +0000
@@ -899,24 +899,14 @@ static void vmx_do_no_device_fault(void)
     }
 }
 
-#define bitmaskof(idx) (1U << ((idx)&31))
+#define bitmaskof(idx)  (1U << ((idx) & 31))
 static void vmx_do_cpuid(struct cpu_user_regs *regs)
 {
     unsigned int input = (unsigned int)regs->eax;
     unsigned int count = (unsigned int)regs->ecx;
     unsigned int eax, ebx, ecx, edx;
-    unsigned long eip;
-    struct vcpu *v = current;
-
-    eip = __vmread(GUEST_RIP);
-
-    HVM_DBG_LOG(DBG_LEVEL_3, "(eax) 0x%08lx, (ebx) 0x%08lx, "
-                "(ecx) 0x%08lx, (edx) 0x%08lx, (esi) 0x%08lx, (edi) 0x%08lx",
-                (unsigned long)regs->eax, (unsigned long)regs->ebx,
-                (unsigned long)regs->ecx, (unsigned long)regs->edx,
-                (unsigned long)regs->esi, (unsigned long)regs->edi);
-
-    if ( input == CPUID_LEAF_0x4 )
+
+    if ( input == 0x00000004 )
     {
         cpuid_count(input, count, &eax, &ebx, &ecx, &edx);
         eax &= NUM_CORES_RESET_MASK;
@@ -929,6 +919,7 @@ static void vmx_do_cpuid(struct cpu_user
          */
         u64 value = ((u64)regs->edx << 32) | (u32)regs->ecx;
         unsigned long mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
+        struct vcpu *v = current;
         char *p;
 
         gdprintk(XENLOG_INFO, "Input address is 0x%"PRIx64".\n", value);
@@ -946,72 +937,37 @@ static void vmx_do_cpuid(struct cpu_user
         unmap_domain_page(p);
 
         gdprintk(XENLOG_INFO, "Output value is 0x%"PRIx64".\n", value);
-        ecx = (u32)(value >>  0);
+        ecx = (u32)value;
         edx = (u32)(value >> 32);
-    }
-    else if ( !cpuid_hypervisor_leaves(input, &eax, &ebx, &ecx, &edx) )
-    {
-        cpuid(input, &eax, &ebx, &ecx, &edx);
-
-        if ( input == CPUID_LEAF_0x1 )
+    } else {
+        hvm_cpuid(input, &eax, &ebx, &ecx, &edx);
+
+        if ( input == 0x00000001 )
         {
             /* Mask off reserved bits. */
             ecx &= ~VMX_VCPU_CPUID_L1_ECX_RESERVED;
 
-            if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
-                clear_bit(X86_FEATURE_APIC, &edx);
-
-#if CONFIG_PAGING_LEVELS >= 3
-            if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
-#endif
-                clear_bit(X86_FEATURE_PAE, &edx);
-            clear_bit(X86_FEATURE_PSE36, &edx);
-
             ebx &= NUM_THREADS_RESET_MASK;
 
             /* Unsupportable for virtualised CPUs. */
-            ecx &= ~(bitmaskof(X86_FEATURE_VMXE)  |
-                     bitmaskof(X86_FEATURE_EST)   |
-                     bitmaskof(X86_FEATURE_TM2)   |
-                     bitmaskof(X86_FEATURE_CID)   |
-                     bitmaskof(X86_FEATURE_MWAIT) );
-
-            edx &= ~( bitmaskof(X86_FEATURE_HT)   |
-                     bitmaskof(X86_FEATURE_ACPI)  |
-                     bitmaskof(X86_FEATURE_ACC) );
-        }
-        else if (  ( input == CPUID_LEAF_0x6 )
-                || ( input == CPUID_LEAF_0x9 )
-                || ( input == CPUID_LEAF_0xA ))
-        {
+            ecx &= ~(bitmaskof(X86_FEATURE_VMXE) |
+                     bitmaskof(X86_FEATURE_EST)  |
+                     bitmaskof(X86_FEATURE_TM2)  |
+                     bitmaskof(X86_FEATURE_CID));
+
+            edx &= ~(bitmaskof(X86_FEATURE_HT)   |
+                     bitmaskof(X86_FEATURE_ACPI) |
+                     bitmaskof(X86_FEATURE_ACC));
+        }
+
+        if ( input == 0x00000006 || input == 0x00000009 || input == 0x0000000A 
)
             eax = ebx = ecx = edx = 0x0;
-        }
-        else if ( input == CPUID_LEAF_0x80000001 )
-        {
-#if CONFIG_PAGING_LEVELS >= 3
-            if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
-#endif
-                clear_bit(X86_FEATURE_NX & 31, &edx);
-#ifdef __i386__
-            clear_bit(X86_FEATURE_LAHF_LM & 31, &ecx);
-
-            clear_bit(X86_FEATURE_LM & 31, &edx);
-            clear_bit(X86_FEATURE_SYSCALL & 31, &edx);
-#endif
-        }
-    }
-
-    regs->eax = (unsigned long) eax;
-    regs->ebx = (unsigned long) ebx;
-    regs->ecx = (unsigned long) ecx;
-    regs->edx = (unsigned long) edx;
-
-    HVM_DBG_LOG(DBG_LEVEL_3, "eip@%lx, input: 0x%lx, "
-                "output: eax = 0x%08lx, ebx = 0x%08lx, "
-                "ecx = 0x%08lx, edx = 0x%08lx",
-                (unsigned long)eip, (unsigned long)input,
-                (unsigned long)eax, (unsigned long)ebx,
-                (unsigned long)ecx, (unsigned long)edx);
+    }
+
+    regs->eax = (unsigned long)eax;
+    regs->ebx = (unsigned long)ebx;
+    regs->ecx = (unsigned long)ecx;
+    regs->edx = (unsigned long)edx;
 }
 
 #define CASE_GET_REG_P(REG, reg)    \
diff -r 1818b322ede9 -r f99dd72ae205 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Wed Dec 20 10:06:33 2006 +0000
+++ b/xen/include/asm-x86/hvm/hvm.h     Wed Dec 20 10:09:42 2006 +0000
@@ -219,6 +219,8 @@ hvm_get_segment_register(struct vcpu *v,
     hvm_funcs.get_segment_register(v, seg, reg);
 }
 
+void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
+                                   unsigned int *ecx, unsigned int *edx);
 void hvm_stts(struct vcpu *v);
 void hvm_set_guest_time(struct vcpu *v, u64 gtime);
 void hvm_freeze_time(struct vcpu *v);
diff -r 1818b322ede9 -r f99dd72ae205 xen/include/asm-x86/hvm/vmx/cpu.h
--- a/xen/include/asm-x86/hvm/vmx/cpu.h Wed Dec 20 10:06:33 2006 +0000
+++ b/xen/include/asm-x86/hvm/vmx/cpu.h Wed Dec 20 10:09:42 2006 +0000
@@ -32,21 +32,14 @@ struct arch_state_struct {
 #define VMX_MF_32       1
 #define VMX_MF_64       2
 
-#define CPUID_LEAF_0x1        0x1
-#define CPUID_LEAF_0x4        0x4
-#define CPUID_LEAF_0x6        0x6
-#define CPUID_LEAF_0x9        0x9
-#define CPUID_LEAF_0xA        0xA
-#define CPUID_LEAF_0x80000001 0x80000001
-
 #define NUM_CORES_RESET_MASK                 0x00003FFF
 #define NUM_THREADS_RESET_MASK               0xFF00FFFF
 
 #define VMX_VCPU_CPUID_L1_ECX_RESERVED_18    0x00040000
 #define VMX_VCPU_CPUID_L1_ECX_RESERVED_6     0x00000040
 
-#define VMX_VCPU_CPUID_L1_ECX_RESERVED             \
-            ( VMX_VCPU_CPUID_L1_ECX_RESERVED_18  | \
-              VMX_VCPU_CPUID_L1_ECX_RESERVED_6   )
+#define VMX_VCPU_CPUID_L1_ECX_RESERVED              \
+            ( VMX_VCPU_CPUID_L1_ECX_RESERVED_18 |   \
+              VMX_VCPU_CPUID_L1_ECX_RESERVED_6 )
 
 #endif /* __ASM_X86_HVM_VMX_CPU_H__ */

_______________________________________________
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®.