aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2006-07-05 18:48:41 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2006-07-05 18:48:41 +0100
commitc0142256845e6fac89ee46f00a06b3ac6144340c (patch)
treed29117c002ccda5f597aa4797aecf4126d1f7eae
parent971ec7119cc466e36bdc389f9802f509a0dbd16e (diff)
downloadxen-c0142256845e6fac89ee46f00a06b3ac6144340c.tar.gz
xen-c0142256845e6fac89ee46f00a06b3ac6144340c.tar.bz2
xen-c0142256845e6fac89ee46f00a06b3ac6144340c.zip
[XEN] Add CPUID hypervisor-info leaves at index 0x40000000.
Currently only a signature leaf is defined ("Xen\0"). Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r--xen/arch/x86/hvm/svm/svm.c87
-rw-r--r--xen/arch/x86/hvm/vmx/vmx.c2
-rw-r--r--xen/arch/x86/traps.c28
-rw-r--r--xen/include/asm-x86/processor.h3
4 files changed, 75 insertions, 45 deletions
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 29f74e8a0f..3a214c1706 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -962,8 +962,8 @@ static void svm_vmexit_do_cpuid(struct vmcb_struct *vmcb, unsigned long input,
!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 vmcb_struct *vmcb, unsigned long input,
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 */
+ /* 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);
+ /* Disable machine check architecture */
+ clear_bit(X86_FEATURE_MCA, &edx);
+ clear_bit(X86_FEATURE_MCE, &edx);
}
- else if ( ( input > 0x00000005 ) && ( input < 0x80000000 ) )
+ else if ( (input > 0x00000005) && (input < 0x80000000) )
{
- eax = ebx = ecx = edx = 0x0;
+ 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);
+ 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);
+ /* 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 vmcb_struct *vmcb, unsigned long input,
#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 vmcb_struct *vmcb, unsigned long input,
{
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 *v, unsigned int reg, unsigned int type,
}
-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 vmcb_struct *vmcb,
/* 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 --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index ed9f6815c0..f65aa009f2 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -868,7 +868,7 @@ static void vmx_vmexit_do_cpuid(struct cpu_user_regs *regs)
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 --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 30cf545625..162b96d338 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -426,10 +426,32 @@ DO_ERROR_NOCODE(16, "fpu error", coprocessor_error)
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;
@@ -466,6 +488,10 @@ static int emulate_forced_invalid_op(struct cpu_user_regs *regs)
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;
regs->ebx = b;
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index c6b3247763..38c8330446 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -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 */