[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN] Add CPUID hypervisor-info leaves at index 0x40000000.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 8e55c5c1147589b7a6a1875384d4317aec7ccf84 # Parent 74018b65c369ea23815a4b2c7285c3268af1d7d4 [XEN] Add CPUID hypervisor-info leaves at index 0x40000000. Currently only a signature leaf is defined ("Xen\0"). Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/hvm/svm/svm.c | 97 ++++++++++++++++++++-------------------- xen/arch/x86/hvm/vmx/vmx.c | 2 xen/arch/x86/traps.c | 28 +++++++++++ xen/include/asm-x86/processor.h | 3 + 4 files changed, 80 insertions(+), 50 deletions(-) diff -r 74018b65c369 -r 8e55c5c11475 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Wed Jul 05 17:37:08 2006 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Wed Jul 05 18:48:41 2006 +0100 @@ -962,8 +962,8 @@ static void svm_vmexit_do_cpuid(struct v !vlapic_global_enabled((VLAPIC(v))) ) { /* Since the apic is disabled, avoid any confusion - about SMP cpus being available */ - clear_bit(X86_FEATURE_APIC, &edx); + about SMP cpus being available */ + clear_bit(X86_FEATURE_APIC, &edx); } #if CONFIG_PAGING_LEVELS < 3 @@ -974,52 +974,51 @@ static void svm_vmexit_do_cpuid(struct v if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 ) { if ( !v->domain->arch.hvm_domain.pae_enabled ) - { - clear_bit(X86_FEATURE_PAE, &edx); - } + clear_bit(X86_FEATURE_PAE, &edx); clear_bit(X86_FEATURE_PSE, &edx); clear_bit(X86_FEATURE_PSE36, &edx); } -#endif +#endif /* 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 */ - - /* Disable machine check architecture */ - clear_bit(X86_FEATURE_MCA, &edx); - clear_bit(X86_FEATURE_MCE, &edx); - } - else if ( ( input > 0x00000005 ) && ( input < 0x80000000 ) ) - { - eax = ebx = ecx = edx = 0x0; + /* 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 */ + + /* Disable machine check architecture */ + clear_bit(X86_FEATURE_MCA, &edx); + clear_bit(X86_FEATURE_MCE, &edx); + } + else if ( (input > 0x00000005) && (input < 0x80000000) ) + { + if ( !cpuid_hypervisor_leaves(input, &eax, &ebx, &ecx, &edx) ) + eax = ebx = ecx = edx = 0; } else if ( input == 0x80000001 ) { - /* We duplicate some CPUID_00000001 code because many bits of - CPUID_80000001_EDX overlaps with CPUID_00000001_EDX. */ + /* 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))) ) + !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); + 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__ /* Mask feature for Intel ia32e or AMD long mode. */ @@ -1030,7 +1029,7 @@ static void svm_vmexit_do_cpuid(struct v #endif #if CONFIG_PAGING_LEVELS < 3 - clear_bit(X86_FEATURE_NX & 31, &edx); + 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); @@ -1039,29 +1038,29 @@ static void svm_vmexit_do_cpuid(struct v { 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_NX & 31, &edx); + clear_bit(X86_FEATURE_PAE, &edx); } clear_bit(X86_FEATURE_PSE, &edx); clear_bit(X86_FEATURE_PSE36, &edx); } -#endif +#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); + + /* 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; + /* 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 */ + ecx &= 0xFFFFFF00; /* Make sure Number of CPU core is 1 when HTT=0 */ } regs->eax = (unsigned long)eax; @@ -1214,8 +1213,9 @@ static void svm_dr_access (struct vcpu * } -static void svm_get_prefix_info(struct vmcb_struct *vmcb, - unsigned int dir, segment_selector_t **seg, unsigned int *asize) +static void svm_get_prefix_info( + struct vmcb_struct *vmcb, + unsigned int dir, segment_selector_t **seg, unsigned int *asize) { unsigned char inst[MAX_INST_LEN]; int i; @@ -1287,9 +1287,10 @@ static void svm_get_prefix_info(struct v /* Get the address of INS/OUTS instruction */ -static inline int svm_get_io_address(struct vcpu *v, - struct cpu_user_regs *regs, unsigned int dir, - unsigned long *count, unsigned long *addr) +static inline int svm_get_io_address( + struct vcpu *v, + struct cpu_user_regs *regs, unsigned int dir, + unsigned long *count, unsigned long *addr) { unsigned long reg; unsigned int asize = 0; diff -r 74018b65c369 -r 8e55c5c11475 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Wed Jul 05 17:37:08 2006 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Jul 05 18:48:41 2006 +0100 @@ -868,7 +868,7 @@ static void vmx_vmexit_do_cpuid(struct c cpuid_count(input, count, &eax, &ebx, &ecx, &edx); eax &= NUM_CORES_RESET_MASK; } - else + else if ( !cpuid_hypervisor_leaves(input, &eax, &ebx, &ecx, &edx) ) { cpuid(input, &eax, &ebx, &ecx, &edx); diff -r 74018b65c369 -r 8e55c5c11475 xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Wed Jul 05 17:37:08 2006 +0100 +++ b/xen/arch/x86/traps.c Wed Jul 05 18:48:41 2006 +0100 @@ -426,10 +426,32 @@ DO_ERROR(17, "alignment check", alignmen DO_ERROR(17, "alignment check", alignment_check) DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error) +int cpuid_hypervisor_leaves( + uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) +{ + if ( (idx < 0x40000000) || (idx > 0x40000000) ) + return 0; + + switch ( idx - 0x40000000 ) + { + case 0: + *eax = 0x40000000; + *ebx = 0x006e6558; /* "Xen\0" */ + *ecx = *edx = 0; + break; + + default: + BUG(); + } + + return 1; +} + static int emulate_forced_invalid_op(struct cpu_user_regs *regs) { char signature[5], instr[2]; - unsigned long a, b, c, d, eip; + uint32_t a, b, c, d; + unsigned long eip; a = regs->eax; b = regs->ebx; @@ -465,6 +487,10 @@ static int emulate_forced_invalid_op(str clear_bit(X86_FEATURE_SEP, &d); if ( !IS_PRIV(current->domain) ) clear_bit(X86_FEATURE_MTRR, &d); + } + else + { + (void)cpuid_hypervisor_leaves(regs->eax, &a, &b, &c, &d); } regs->eax = a; diff -r 74018b65c369 -r 8e55c5c11475 xen/include/asm-x86/processor.h --- a/xen/include/asm-x86/processor.h Wed Jul 05 17:37:08 2006 +0100 +++ b/xen/include/asm-x86/processor.h Wed Jul 05 18:48:41 2006 +0100 @@ -545,6 +545,9 @@ extern void mtrr_bp_init(void); extern void mcheck_init(struct cpuinfo_x86 *c); +int cpuid_hypervisor_leaves( + uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); + #endif /* !__ASSEMBLY__ */ #endif /* __ASM_X86_PROCESSOR_H */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |