|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 05/14] x86/cpuid: Handle leaf 0x80000001 in guest_cpuid()
Intel reserve eax and ebx, while AMD duplicates eax from the low
family/model/stepping leaf. For AMD, ebx contains further brand/package
information which is left as the toolstack chooses (other than bits 27:16
which are reserved).
While moving the dynamic adjustments from the legacy path, simplify the shadow
PSE36 adjustment. PAE paging is a prerequisite for enabling long mode, making
the long mode check redundant; the case where it doesn't get short circuited
is the case where it is architecturally 0. Make the same adjustment to the
leaf 1 legacy path.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
v2:
* New
---
xen/arch/x86/cpuid.c | 107 ++++++++++++++++++++++----------------------
xen/include/asm-x86/cpuid.h | 2 +-
2 files changed, 55 insertions(+), 54 deletions(-)
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 7af5900..c06b5a6 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -177,6 +177,8 @@ static void recalculate_misc(struct cpuid_policy *p)
p->extd.vendor_ebx = 0;
p->extd.vendor_ecx = 0;
p->extd.vendor_edx = 0;
+
+ p->extd.raw[0x1].a = p->extd.raw[0x1].b = 0;
break;
case X86_VENDOR_AMD:
@@ -187,6 +189,8 @@ static void recalculate_misc(struct cpuid_policy *p)
p->extd.vendor_ecx = p->basic.vendor_ecx;
p->extd.vendor_edx = p->basic.vendor_edx;
+ p->extd.raw_fms = p->basic.raw_fms;
+ p->extd.raw[0x1].b &= 0xff00ffff;
p->extd.e1d |= p->basic._1d & CPUID_COMMON_1D_FEATURES;
break;
}
@@ -672,24 +676,6 @@ static void pv_cpuid(uint32_t leaf, uint32_t subleaf,
struct cpuid_leaf *res)
res->a = (res->a & ~0xff) | 3;
break;
- case 0x80000001:
- res->c = p->extd.e1c;
- res->d = p->extd.e1d;
-
- /*
- * MTRR used to unconditionally leak into PV guests. They cannot MTRR
- * infrastructure at all, and shouldn't be able to see the feature.
- *
- * Modern PVOPS Linux self-clobbers the MTRR feature, to avoid trying
- * to use the associated MSRs. Xenolinux-based PV dom0's however use
- * the MTRR feature as an indication of the presence of the
- * XENPF_{add,del,read}_memtype hypercalls.
- */
- if ( is_hardware_domain(currd) && cpu_has_mtrr &&
- guest_kernel_mode(curr, guest_cpu_user_regs()) )
- res->d |= cpufeat_mask(X86_FEATURE_MTRR);
- break;
-
case 0x80000007:
res->d = p->extd.e7d;
break;
@@ -712,7 +698,7 @@ static void pv_cpuid(uint32_t leaf, uint32_t subleaf,
struct cpuid_leaf *res)
case 0x2 ... 0x3:
case 0x7 ... 0x9:
case 0xc ... XSTATE_CPUID:
- case 0x80000000:
+ case 0x80000000 ... 0x80000001:
ASSERT_UNREACHABLE();
/* Now handled in guest_cpuid(). */
}
@@ -760,7 +746,7 @@ static void hvm_cpuid(uint32_t leaf, uint32_t subleaf,
struct cpuid_leaf *res)
* a 32bit guest doesn't get the impression that it could try to use
* PSE36 paging.
*/
- if ( !hap_enabled(d) && !(hvm_pae_enabled(v) ||
hvm_long_mode_enabled(v)) )
+ if ( !hap_enabled(d) && !hvm_pae_enabled(v) )
res->d &= ~cpufeat_mask(X86_FEATURE_PSE36);
if ( vpmu_enabled(v) &&
@@ -792,37 +778,6 @@ static void hvm_cpuid(uint32_t leaf, uint32_t subleaf,
struct cpuid_leaf *res)
res->a = (res->a & ~0xff) | 3;
break;
- case 0x80000001:
- res->c = p->extd.e1c;
- res->d = p->extd.e1d;
-
- /* fast-forward MSR_APIC_BASE.EN if it hasn't already been clobbered.
*/
- if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
- res->d &= ~cpufeat_bit(X86_FEATURE_APIC);
-
- /*
- * PSE36 is not supported in shadow mode. This bit should be
- * unilaterally cleared.
- *
- * However, an unspecified version of Hyper-V from 2011 refuses
- * to start as the "cpu does not provide required hw features" if
- * it can't see PSE36.
- *
- * As a workaround, leak the toolstack-provided PSE36 value into a
- * shadow guest if the guest is already using PAE paging (and won't
- * care about reverting back to PSE paging). Otherwise, knoble it, so
- * a 32bit guest doesn't get the impression that it could try to use
- * PSE36 paging.
- */
- if ( !hap_enabled(d) && !(hvm_pae_enabled(v) ||
hvm_long_mode_enabled(v)) )
- res->d &= ~cpufeat_mask(X86_FEATURE_PSE36);
-
- /* SYSCALL is hidden outside of long mode on Intel. */
- if ( p->x86_vendor == X86_VENDOR_INTEL && !hvm_long_mode_enabled(v) )
- res->d &= ~cpufeat_mask(X86_FEATURE_SYSCALL);
-
- break;
-
case 0x80000007:
res->d = p->extd.e7d;
break;
@@ -860,7 +815,7 @@ static void hvm_cpuid(uint32_t leaf, uint32_t subleaf,
struct cpuid_leaf *res)
case 0x2 ... 0x3:
case 0x7 ... 0x9:
case 0xc ... XSTATE_CPUID:
- case 0x80000000:
+ case 0x80000000 ... 0x80000001:
ASSERT_UNREACHABLE();
/* Now handled in guest_cpuid(). */
}
@@ -943,7 +898,7 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
default:
goto legacy;
- case 0x80000000:
+ case 0x80000000 ... 0x80000001:
*res = p->extd.raw[leaf & 0xffff];
break;
}
@@ -1007,6 +962,52 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
break;
}
break;
+
+ case 0x80000001:
+ if ( has_hvm_container_domain(d) )
+ {
+ /* Fast-forward MSR_APIC_BASE.EN. */
+ if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
+ res->d &= ~cpufeat_bit(X86_FEATURE_APIC);
+
+ /*
+ * PSE36 is not supported in shadow mode. This bit should be
+ * clear in hvm_shadow_featuremask[].
+ *
+ * However, an unspecified version of Hyper-V from 2011 refuses to
+ * start as the "cpu does not provide required hw features" if it
+ * can't see PSE36.
+ *
+ * As a workaround, leak the toolstack-provided PSE36 value into a
+ * shadow guest if the guest is already using PAE paging (and
+ * won't care about reverting back to PSE paging). Otherwise,
+ * knoble it, so a 32bit guest doesn't get the impression that it
+ * could try to use PSE36 paging.
+ */
+ if ( !hap_enabled(d) && !hvm_pae_enabled(v) )
+ res->d &= ~cpufeat_mask(X86_FEATURE_PSE36);
+
+ /* SYSCALL is hidden outside of long mode on Intel. */
+ if ( p->x86_vendor == X86_VENDOR_INTEL &&
!hvm_long_mode_enabled(v) )
+ res->d &= ~cpufeat_mask(X86_FEATURE_SYSCALL);
+ }
+ else /* PV domain */
+ {
+ /*
+ * MTRR used to unconditionally leak into PV guests. They cannot
+ * MTRR infrastructure at all, and shouldn't be able to see the
+ * feature.
+ *
+ * Modern PVOPS Linux self-clobbers the MTRR feature, to avoid
+ * trying to use the associated MSRs. Xenolinux-based PV dom0's
+ * however use the MTRR feature as an indication of the presence
+ * of the XENPF_{add,del,read}_memtype hypercalls.
+ */
+ if ( is_hardware_domain(d) && cpu_has_mtrr &&
+ guest_kernel_mode(v, guest_cpu_user_regs()) )
+ res->d |= cpufeat_mask(X86_FEATURE_MTRR);
+ }
+ break;
}
/* Done. */
diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h
index a15270a..be76ed4 100644
--- a/xen/include/asm-x86/cpuid.h
+++ b/xen/include/asm-x86/cpuid.h
@@ -174,7 +174,7 @@ struct cpuid_policy
uint32_t max_leaf, vendor_ebx, vendor_ecx, vendor_edx;
/* Leaf 0x80000001 - Family/model/stepping and features. */
- uint32_t /* a */:32, /* b */:32;
+ uint32_t raw_fms, /* b */:32;
union {
uint32_t e1c;
struct { DECL_BITFIELD(e1c); };
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |