WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVM] Clean up CPUID handling.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 20 Dec 2006 17:15:08 -0800
Delivery-date: Wed, 20 Dec 2006 17:15:49 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [HVM] Clean up CPUID handling., Xen patchbot-unstable <=