[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 08/14] x86/cpuid: Handle leaf 0x80000008 in guest_cpuid()
The entirety of edx is reserved. Intel only defines the lower 16 bits of eax, although ebx is covered by the featureset ABI, so left unclobbered. AMD uses 24 bits in eax, although nothing thus far has ever exposed a non-zero guest maxphysaddr to HVM guests. Its semantics are not clearly expressed, so it is explicitly clobbered. ecx contains some reserved bits, and several pieces of static topology information, which are left as the toolstack chooses. A side effect of the common recalculation of maxlinaddr is that 32bit PV guests see a maximum linear address of 32, which is consistent with the hiding of other long mode information from them. Finally, the call to guest_cpuid() in mtrr_var_range_msr_set() (introduced in c/s fff8160a) can be dropped, now that maxphysaddr can be read straight out of the cpuid_policy block. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> v2: * New v3: * Clobber GuestMaxPhysAddr until its semantics are understood. --- xen/arch/x86/cpuid.c | 45 ++++++++++++++++++++------------------------- xen/arch/x86/hvm/mtrr.c | 7 +------ xen/include/asm-x86/cpuid.h | 2 +- 3 files changed, 22 insertions(+), 32 deletions(-) diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c index 3338045..b806cc5 100644 --- a/xen/arch/x86/cpuid.c +++ b/xen/arch/x86/cpuid.c @@ -170,6 +170,8 @@ static void recalculate_misc(struct cpuid_policy *p) /* Most of Power/RAS hidden from guests. */ p->extd.raw[0x7].a = p->extd.raw[0x7].b = p->extd.raw[0x7].c = 0; + p->extd.raw[0x8].d = 0; + switch ( p->x86_vendor ) { case X86_VENDOR_INTEL: @@ -185,6 +187,9 @@ static void recalculate_misc(struct cpuid_policy *p) p->extd.raw[0x5] = EMPTY_LEAF; p->extd.raw[0x6].a = p->extd.raw[0x6].b = p->extd.raw[0x6].d = 0; + + p->extd.raw[0x8].a &= 0x0000ffff; + p->extd.raw[0x8].c = 0; break; case X86_VENDOR_AMD: @@ -198,6 +203,9 @@ static void recalculate_misc(struct cpuid_policy *p) p->extd.raw_fms = p->basic.raw_fms; p->extd.raw[0x1].b &= 0xff00ffff; p->extd.e1d |= p->basic._1d & CPUID_COMMON_1D_FEATURES; + + p->extd.raw[0x8].a &= 0x0000ffff; /* GuestMaxPhysAddr hidden. */ + p->extd.raw[0x8].c &= 0x0003f0ff; break; } } @@ -469,6 +477,15 @@ void recalculate_cpuid_policy(struct domain *d) special_features[FEATURESET_7b0]); cpuid_featureset_to_policy(fs, p); + + p->extd.maxphysaddr = min(p->extd.maxphysaddr, max->extd.maxphysaddr); + p->extd.maxphysaddr = min_t(uint8_t, p->extd.maxphysaddr, + d->arch.paging.gfn_bits + PAGE_SHIFT); + p->extd.maxphysaddr = max_t(uint8_t, p->extd.maxphysaddr, + (p->basic.pae || p->basic.pse36) ? 36 : 32); + + p->extd.maxlinaddr = p->extd.lm ? 48 : 32; + recalculate_xstate(p); recalculate_misc(p); } @@ -682,11 +699,6 @@ static void pv_cpuid(uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *res) res->a = (res->a & ~0xff) | 3; break; - case 0x80000008: - res->a = paddr_bits | (vaddr_bits << 8); - res->b = p->extd.e8b; - break; - case 0x00000005: /* MONITOR/MWAIT */ case 0x0000000b: /* Extended Topology Enumeration */ case 0x8000000a: /* SVM revision and features */ @@ -700,7 +712,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 ... 0x80000007: + case 0x80000000 ... 0x80000008: ASSERT_UNREACHABLE(); /* Now handled in guest_cpuid(). */ } @@ -716,8 +728,6 @@ static void hvm_cpuid(uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *res) switch ( leaf ) { - unsigned int tmp; - case 0x1: /* Fix up VLAPIC details. */ res->b &= 0x00FFFFFFu; @@ -780,21 +790,6 @@ static void hvm_cpuid(uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *res) res->a = (res->a & ~0xff) | 3; break; - case 0x80000008: - res->a &= 0xff; - tmp = d->arch.paging.gfn_bits + PAGE_SHIFT; - if ( res->a > tmp ) - res->a = tmp; - - tmp = (p->basic.pae || p->basic.pse36) ? 36 : 32; - if ( res->a < tmp ) - res->a = tmp; - - res->a |= (p->extd.lm ? vaddr_bits : 32) << 8; - - res->b = p->extd.e8b; - break; - case 0x8000001c: if ( !cpu_has_svm ) { @@ -813,7 +808,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 ... 0x80000007: + case 0x80000000 ... 0x80000008: ASSERT_UNREACHABLE(); /* Now handled in guest_cpuid(). */ } @@ -896,7 +891,7 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf, default: goto legacy; - case 0x80000000 ... 0x80000007: + case 0x80000000 ... 0x80000008: *res = p->extd.raw[leaf & 0xffff]; break; } diff --git a/xen/arch/x86/hvm/mtrr.c b/xen/arch/x86/hvm/mtrr.c index 709759c..9ea1fdc 100644 --- a/xen/arch/x86/hvm/mtrr.c +++ b/xen/arch/x86/hvm/mtrr.c @@ -452,12 +452,7 @@ bool_t mtrr_var_range_msr_set( return 0; if ( d == current->domain ) - { - struct cpuid_leaf res; - - guest_cpuid(current, 0x80000008, 0, &res); - phys_addr = (uint8_t)res.a ?: 36; - } + phys_addr = d->arch.cpuid->extd.maxphysaddr; else phys_addr = paddr_bits; msr_mask = ~((((uint64_t)1) << phys_addr) - 1); diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h index be76ed4..6cc23aa 100644 --- a/xen/include/asm-x86/cpuid.h +++ b/xen/include/asm-x86/cpuid.h @@ -198,7 +198,7 @@ struct cpuid_policy }; /* Leaf 0x80000008 - Misc addr/feature info. */ - uint32_t /* a */:32; + uint8_t maxphysaddr, maxlinaddr, :8, :8; union { uint32_t e8b; struct { DECL_BITFIELD(e8b); }; -- 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 |