[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86: correct CPUID output for out of bounds input
commit b0c0e695e05dc52212b8fdbf8d973be353af7b6a Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Tue Sep 6 10:19:18 2016 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Sep 6 10:19:18 2016 +0200 x86: correct CPUID output for out of bounds input Another place where we should try to behave sufficiently close to how real hardware does; see the code comments. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- xen/arch/x86/hvm/hvm.c | 21 +++++++++++++++++++++ xen/arch/x86/traps.c | 23 +++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index c0c270a..58a40b6 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3368,6 +3368,27 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx, if ( cpuid_hypervisor_leaves(input, count, eax, ebx, ecx, edx) ) return; + if ( input & 0x7fffffff ) + { + /* + * Requests outside the supported leaf ranges return zero on AMD + * and the highest basic leaf output on Intel. Uniformly follow + * the AMD model as the more sane one. + */ + unsigned int limit; + + domain_cpuid(d, (input >> 16) != 0x8000 ? 0 : 0x80000000, 0, + &limit, &dummy, &dummy, &dummy); + if ( input > limit ) + { + *eax = 0; + *ebx = 0; + *ecx = 0; + *edx = 0; + return; + } + } + domain_cpuid(d, input, count, eax, ebx, ecx, edx); switch ( input ) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 90b0741..b24ca74 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -952,6 +952,29 @@ void pv_cpuid(struct cpu_user_regs *regs) if ( cpuid_hypervisor_leaves(leaf, subleaf, &a, &b, &c, &d) ) goto out; + if ( leaf & 0x7fffffff ) + { + /* + * Requests outside the supported leaf ranges return zero on AMD + * and the highest basic leaf output on Intel. Uniformly follow + * the AMD model as the more sane one. + */ + unsigned int limit = (leaf >> 16) != 0x8000 ? 0 : 0x80000000, dummy; + + if ( !is_control_domain(currd) && !is_hardware_domain(currd) ) + domain_cpuid(currd, limit, 0, &limit, &dummy, &dummy, &dummy); + else + limit = cpuid_eax(limit); + if ( leaf > limit ) + { + regs->eax = 0; + regs->ebx = 0; + regs->ecx = 0; + regs->edx = 0; + return; + } + } + if ( !is_control_domain(currd) && !is_hardware_domain(currd) ) domain_cpuid(currd, leaf, subleaf, &a, &b, &c, &d); else -- 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 |