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…
Reference in New Issue
Block a user