Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:FrontRunner
xen.16553
5d89d8d9-libxc-x86-avoid-overflow-in-CPUID-APIC...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5d89d8d9-libxc-x86-avoid-overflow-in-CPUID-APIC-ID.patch of Package xen.16553
References: bsc#1137717 # Commit df29d03f1d97bdde1bc0cea8ef8538d4f524b3ec # Date 2019-09-24 10:50:33 +0200 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> libxc/x86: avoid certain overflows in CPUID APIC ID adjustments Recent AMD processors may report up to 128 logical processors in CPUID leaf 1. Doubling this value produces 0 (which OSes sincerely dislike), as the respective field is only 8 bits wide. Suppress doubling the value (and its leaf 0x80000008 counterpart) in such a case. Note that while there's a similar overflow in intel_xc_cpuid_policy(), that one is being left alone for now. Note further that while it was considered to suppress the multiplication by 2 altogether if the host topology already provides at least one bit of thread ID within APIC IDs, it was decided to avoid more change here than really needed at this point. Also zap leaf 4 (and at the same time leaf 2) EDX output for AMD, as it should have been from the beginning. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> # Commit c9c7ac508b3f65f7d5f9685893096a1b22d8b176 # Date 2019-09-25 15:50:58 +0200 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> libxc/x86: correct overflow avoidance check in AMD CPUID handling Commit df29d03f1d ("libxc/x86: avoid certain overflows in CPUID APIC ID adjustments" introduced a one bit too narrow mask when checking whether multiplying by 1 (in particular in leaf 1) would result in overflow. Reported-by: Andrew Cooper <andrew.cooper3@citrix.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> # Commit 8c79c129a6db2220c1089e0ce5fa49e7298b1d3e # Date 2019-11-26 10:33:52 +0000 # Author George Dunlap <george.dunlap@citrix.com> # Committer George Dunlap <george.dunlap@citrix.com> x86: Don't increase ApicIdCoreSize past 7 Changeset ca2eee92df44 ("x86, hvm: Expose host core/HT topology to HVM guests") attempted to "fake up" a topology which would induce guest operating systems to not treat vcpus as sibling hyperthreads. This involved actually reporting hyperthreading as available, but giving vcpus every other ApicId; which in turn led to doubling the ApicIds per core by bumping the ApicIdCoreSize by one. In particular, Ryzen 3xxx series processors, and reportedly EPYC "Rome" cpus -- have an ApicIdCoreSize of 7; the "fake" topology increases this to 8. Unfortunately, Windows running on modern AMD hardware -- including Ryzen 3xxx series processors, and reportedly EPYC "Rome" cpus -- doesn't seem to cope with this value being higher than 7. (Linux guests have so far continued to cope.) A "proper" fix is complicated and it's too late to fix it either for 4.13, or to backport to supported branches. As a short-term fix, limit this value to 7. This does mean that a Linux guest, booted on such a system without this change, and then migrating to a system with this change, with more than 64 vcpus, would see an apparent topology change. This is a low enough risk in practice that enabling this limit unilaterally, to allow other guests to boot without manual intervention, is worth it. Reported-by: Steven Haigh <netwiz@crc.id.au> Reported-by: Andreas Kinzler <hfp@posteo.de> Signed-off-by: George Dunlap <george.dunlap@citrix.com> Acked-by: Jan Beulich <jbeulich@suse.com> --- a/tools/libxc/xc_cpuid_x86.c +++ b/tools/libxc/xc_cpuid_x86.c @@ -335,7 +335,7 @@ static void amd_xc_cpuid_policy(xc_inter { case 0x00000002: case 0x00000004: - regs[0] = regs[1] = regs[2] = 0; + regs[0] = regs[1] = regs[2] = regs[3] = 0; break; case 0x80000000: @@ -345,11 +345,24 @@ static void amd_xc_cpuid_policy(xc_inter case 0x80000008: /* - * ECX[15:12] is ApicIdCoreSize: ECX[7:0] is NumberOfCores (minus one). - * Update to reflect vLAPIC_ID = vCPU_ID * 2. + * ECX[15:12] is ApicIdCoreSize. + * ECX[7:0] is NumberOfCores (minus one). + * Update to reflect vLAPIC_ID = vCPU_ID * 2. But make sure to avoid + * - overflow, + * - going out of sync with leaf 1 EBX[23:16], + * - incrementing ApicIdCoreSize when it's zero (which changes the + * meaning of bits 7:0). + * + * UPDATE: I addition to avoiding overflow, some proprietary operating + * systems have trouble with apic_id_size values greater than 7. + * Limit the value to 7 for now. */ - regs[2] = ((regs[2] + (1u << 12)) & 0xf000u) | - ((regs[2] & 0xffu) << 1) | 1u; + if ( (regs[2] & 0xffu) < 0x7fu ) + { + if ( (regs[2] & 0xf000u) && (regs[2] & 0xf000u) < 0x7000u ) + regs[2] = (regs[2] + 0x1000u) | (regs[2] & 0xffu); + regs[2] = (regs[2] & 0xf000u) | ((regs[2] & 0x7fu) << 1) | 1u; + } break; case 0x8000000a: { @@ -430,9 +443,13 @@ static void xc_cpuid_hvm_policy(xc_inter case 0x00000001: /* * EBX[23:16] is Maximum Logical Processors Per Package. - * Update to reflect vLAPIC_ID = vCPU_ID * 2. + * Update to reflect vLAPIC_ID = vCPU_ID * 2, but make sure to avoid + * overflow. */ - regs[1] = (regs[1] & 0x0000ffffu) | ((regs[1] & 0x007f0000u) << 1); + if ( !(regs[1] & 0x00800000u) ) + regs[1] = (regs[1] & 0x0000ffffu) | ((regs[1] & 0x007f0000u) << 1); + else + regs[1] &= 0x00ffffffu; regs[2] = info->featureset[featureword_of(X86_FEATURE_SSE3)]; regs[3] = (info->featureset[featureword_of(X86_FEATURE_FPU)] |
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor