target-i386: Mask mtrr mask based on CPU physical address limits
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 <dgilbert@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
parent
af45907a13
commit
112dad69d7
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user