From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54670) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bPYjg-0000bY-Oe for qemu-devel@nongnu.org; Tue, 19 Jul 2016 13:23:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bPYjf-0002Mx-Cr for qemu-devel@nongnu.org; Tue, 19 Jul 2016 13:23:12 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56713) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bPYjf-0002Ms-6i for qemu-devel@nongnu.org; Tue, 19 Jul 2016 13:23:11 -0400 From: Eduardo Habkost Date: Tue, 19 Jul 2016 14:22:31 -0300 Message-Id: <1468948976-30660-4-git-send-email-ehabkost@redhat.com> In-Reply-To: <1468948976-30660-1-git-send-email-ehabkost@redhat.com> References: <1468948976-30660-1-git-send-email-ehabkost@redhat.com> Subject: [Qemu-devel] [PULL 03/28] target-i386: Mask mtrr mask based on CPU physical address limits List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Peter Maydell Cc: Paolo Bonzini , Richard Henderson , qemu-devel@nongnu.org, "Dr. David Alan Gilbert" From: "Dr. David Alan Gilbert" The CPU GPs if we try and set a bit in a variable MTRR mask above the limit of physical address bits on the host. We hit this when loading a migration from a host with a larger physical address limit than our destination (e.g. a Xeon->i7 of same generation) but previously used to get away with it until 48e1a45 started checking that msr writes actually worked. It seems in our case the GP probably comes from KVM emulating that GP. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Eduardo Habkost Signed-off-by: Eduardo Habkost --- target-i386/kvm.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 9327523..2f1cc62 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1716,6 +1716,8 @@ static int kvm_put_msrs(X86CPU *cpu, int level) } } if (has_msr_mtrr) { + uint64_t phys_mask = MAKE_64BIT_MASK(0, cpu->phys_bits); + kvm_msr_entry_add(cpu, MSR_MTRRdefType, env->mtrr_deftype); kvm_msr_entry_add(cpu, MSR_MTRRfix64K_00000, env->mtrr_fixed[0]); kvm_msr_entry_add(cpu, MSR_MTRRfix16K_80000, env->mtrr_fixed[1]); @@ -1729,10 +1731,15 @@ static int kvm_put_msrs(X86CPU *cpu, int level) kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F0000, env->mtrr_fixed[9]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F8000, env->mtrr_fixed[10]); for (i = 0; i < MSR_MTRRcap_VCNT; i++) { + /* The CPU GPs if we write to a bit above the physical limit of + * the host CPU (and KVM emulates that) + */ + uint64_t mask = env->mtrr_var[i].mask; + mask &= phys_mask; + kvm_msr_entry_add(cpu, MSR_MTRRphysBase(i), env->mtrr_var[i].base); - kvm_msr_entry_add(cpu, MSR_MTRRphysMask(i), - env->mtrr_var[i].mask); + kvm_msr_entry_add(cpu, MSR_MTRRphysMask(i), mask); } } -- 2.5.5