[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] x86/HVM: correct CPUID leaf 80000008 handling
At 11:48 +0000 on 26 Mar (1395830898), Jan Beulich wrote: > CPUID[80000001].EAX[23:16] have been given the meaning of the guest s/80000001/80000008/? > physical address restriction (in case it needs to be smaller than the > host's), hence we need to mirror that into vCPUID[80000008].EAX[7:0]. > > Enforce a lower limit at the same time, as well as a fixed value for > the virtual address bits, and zero for the guest physical address ones. > > In order for the vMTRR code to see these overrides we need to make it > call hvm_cpuid() instead of domain_cpuid(), which in turn requires > special casing (and relaxing) the controlling domain. > > This additionally should hide an ordering problem in the tools: Both > xend and xl appear to be restoring a guest from its image before > setting up the CPUID policy in the hypervisor, resulting in > domain_cpuid() returning all zeros and hence the check in > mtrr_var_range_msr_set() failing if the guest previously had more than > the minimum 36 physical address bits. > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > > --- a/xen/arch/x86/hvm/hvm.c > +++ b/xen/arch/x86/hvm/hvm.c > @@ -3012,6 +3012,8 @@ void hvm_cpuid(unsigned int input, unsig > > switch ( input ) > { > + unsigned int sub_leaf, _eax, _ebx, _ecx, _edx; > + > case 0x1: > /* Fix up VLAPIC details. */ > *ebx &= 0x00FFFFFFu; > @@ -3051,8 +3053,6 @@ void hvm_cpuid(unsigned int input, unsig > *edx = v->vcpu_id * 2; > break; > case 0xd: > - { > - unsigned int sub_leaf, _eax, _ebx, _ecx, _edx; > /* EBX value of main leaf 0 depends on enabled xsave features */ > if ( count == 0 && v->arch.xcr0 ) > { > @@ -3069,7 +3069,7 @@ void hvm_cpuid(unsigned int input, unsig > } > } > break; > - } > + > case 0x80000001: > /* We expose RDTSCP feature to guest only when > tsc_mode == TSC_MODE_DEFAULT and host_tsc_is_safe() returns 1 */ > @@ -3083,6 +3083,23 @@ void hvm_cpuid(unsigned int input, unsig > if ( !(hvm_pae_enabled(v) || hvm_long_mode_enabled(v)) ) > *edx &= ~cpufeat_mask(X86_FEATURE_PSE36); > break; > + > + case 0x80000008: > + count = cpuid_eax(0x80000008); > + count = (count >> 16) & 0xff ?: count & 0xff; > + if ( (*eax & 0xff) > count ) > + *eax = (*eax & ~0xff) | count; > + > + hvm_cpuid(1, NULL, NULL, NULL, &_edx); > + count = _edx & (cpufeat_mask(X86_FEATURE_PAE) | > + cpufeat_mask(X86_FEATURE_PSE36)) ? 36 : 32; > + if ( (*eax & 0xff) < count ) > + *eax = (*eax & ~0xff) | count; What is this for? Surely if the CPU really claims to have a paddr limit lower than 32 then (a) it's buggy and (b) we can't just pretend it doesn't say that. And architecturally, the presence of PSE/PAE doesn't guarantee that the CPU will support a given paddr width. (My reading of the AMD docs says you get up-to-40/up-to-52 but gives no lower bound). > + hvm_cpuid(0x80000001, NULL, NULL, NULL, &_edx); > + *eax = (*eax & ~0xffff00) | (_edx & cpufeat_mask(X86_FEATURE_LM) > + ? 0x3000 : 0x2000); But we don't support 64-bit linear addresses in long mode -- shouldn't we be capping this at what the hardware actually allows? Tim. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |