# 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
|