[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/cpuid: Handle leaf 0x80000001 in guest_cpuid()
commit 07929c99852694208ab5844f1382482ef4ecc5fc Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> AuthorDate: Fri Jan 20 14:47:34 2017 +0000 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Wed Jan 25 10:24:39 2017 +0000 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> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- 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); }; -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |