From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andre Przywara Subject: Re: [PATCH 2/2] kvm/x86: move and fix substitue search for missing CPUID entries Date: Thu, 31 Mar 2011 16:50:54 +0200 Message-ID: <4D9494CE.3040606@amd.com> References: <4D94584F.1020409@redhat.com> <1301577181-10767-1-git-send-email-andre.przywara@amd.com> <4D947ED4.50407@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: 7bit Cc: "kvm@vger.kernel.org" To: Avi Kivity Return-path: Received: from va3ehsobe002.messaging.microsoft.com ([216.32.180.12]:10738 "EHLO VA3EHSOBE002.bigfish.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753216Ab1CaOvc (ORCPT ); Thu, 31 Mar 2011 10:51:32 -0400 In-Reply-To: <4D947ED4.50407@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: Avi Kivity wrote: > On 03/31/2011 03:13 PM, Andre Przywara wrote: >> If KVM cannot find an exact match for a requested CPUID leaf, the >> code will try to find the closest match instead of simply confessing >> it's failure. >> The implementation was meant to satisfy the CPUID specification, but >> did not properly check for extended and standard leaves and also >> didn't account for the index subleaf. >> Beside that this rule only applies to CPUID intercepts, which is not >> the only user of the kvm_find_cpuid_entry() function. >> >> So fix this algorithm and move it into kvm_emulate_cpuid(). >> This fixes a crash of newer Linux kernels as KVM guests on >> AMD Bulldozer CPUs, where bogus values were returned in response to >> a CPUID intercept. >> >> @@ -4996,6 +4990,19 @@ void kvm_emulate_cpuid(struct kvm_vcpu *vcpu) >> kvm_register_write(vcpu, VCPU_REGS_RCX, 0); >> kvm_register_write(vcpu, VCPU_REGS_RDX, 0); >> best = kvm_find_cpuid_entry(vcpu, function, index); >> + >> + /* if no match is found, check whether we exceed the vCPU's limit >> + * and return the content of the highest valid standard leaf instead. >> + * This is to satisfy the CPUID specification. >> + */ >> + if (!best) { >> + best = kvm_find_cpuid_entry(vcpu, function& 0x80000000, 0); > > "highest valid standard leaf" means the second argument should be zero, no? Weird, but somehow true. I fixed this is in a another version (following). Thanks for spotting this. Andre. > >> + if (best&& best->eax< function) >> + best = kvm_find_cpuid_entry(vcpu, best->eax, index); >> + else >> + best = NULL; >> + } >> + >> if (best) { >> kvm_register_write(vcpu, VCPU_REGS_RAX, best->eax); >> kvm_register_write(vcpu, VCPU_REGS_RBX, best->ebx); > > -- Andre Przywara AMD-Operating System Research Center (OSRC), Dresden, Germany