diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2016-07-20 21:32:56 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2016-07-20 21:32:56 +0100 |
| commit | e66b05e9ca471715388182613217503160ed7a4d (patch) | |
| tree | 42d50d35e80d75e3d6494c1fef25b793c2afc6bd /target-i386/kvm.c | |
| parent | 3b55fbdcb048bf82e82c29b555d0918b83fc40a5 (diff) | |
| parent | 8fe6374e8e0c8dacb85e9e97897291541dd61be6 (diff) | |
| download | focaccia-qemu-e66b05e9ca471715388182613217503160ed7a4d.tar.gz focaccia-qemu-e66b05e9ca471715388182613217503160ed7a4d.zip | |
Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging
x86 queue, 2016-07-20 # gpg: Signature made Wed 20 Jul 2016 16:07:38 BST # gpg: using RSA key 0x2807936F984DC5A6 # gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>" # Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF D1AA 2807 936F 984D C5A6 * remotes/ehabkost/tags/x86-pull-request: (28 commits) pc: Make device_del CPU work for x86 CPUs target-i386: Add x86_cpu_unrealizefn() apic: Use apic_id as apic's migration instance_id (kvm)apic: Add unrealize callbacks apic: kvm-apic: Fix crash due to access to freed memory region apic: Drop APICCommonState.idx and use APIC ID as index in local_apics[] apic: move MAX_APICS check to 'apic' class pc: Implement query-hotpluggable-cpus callback pc: cpu: Allow device_add to be used with x86 cpu pc: Enforce adding CPUs contiguously and removing them in opposite order pc: Forbid BSP removal pc: Register created initial and hotpluged CPUs in one place pc_cpu_plug() pc: Delay setting number of boot CPUs to machine_done time pc: Set APIC ID based on socket/core/thread ids if it's not been set yet target-i386: Fix apic object leak when CPU is deleted target-i386: cpu: Do not ignore error and fix apic parent target-i386: Add support for UMIP and RDPID CPUID bits target-i386: Add socket/core/thread properties to X86CPU target-i386: Replace custom apic-id setter/getter with static property pc: cpu: Consolidate apic-id validity checks in pc_cpu_pre_plug() ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-i386/kvm.c')
| -rw-r--r-- | target-i386/kvm.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 93275231ec..df28dd254a 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); } } @@ -1970,6 +1977,7 @@ static int kvm_get_msrs(X86CPU *cpu) CPUX86State *env = &cpu->env; struct kvm_msr_entry *msrs = cpu->kvm_msr_buf->entries; int ret, i; + uint64_t mtrr_top_bits; kvm_msr_buf_reset(cpu); @@ -2122,6 +2130,30 @@ static int kvm_get_msrs(X86CPU *cpu) } assert(ret == cpu->kvm_msr_buf->nmsrs); + /* + * MTRR masks: Each mask consists of 5 parts + * a 10..0: must be zero + * b 11 : valid bit + * c n-1.12: actual mask bits + * d 51..n: reserved must be zero + * e 63.52: reserved must be zero + * + * 'n' is the number of physical bits supported by the CPU and is + * apparently always <= 52. We know our 'n' but don't know what + * the destinations 'n' is; it might be smaller, in which case + * it masks (c) on loading. It might be larger, in which case + * we fill 'd' so that d..c is consistent irrespetive of the 'n' + * we're migrating to. + */ + + if (cpu->fill_mtrr_mask) { + QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > 52); + assert(cpu->phys_bits <= TARGET_PHYS_ADDR_SPACE_BITS); + mtrr_top_bits = MAKE_64BIT_MASK(cpu->phys_bits, 52 - cpu->phys_bits); + } else { + mtrr_top_bits = 0; + } + for (i = 0; i < ret; i++) { uint32_t index = msrs[i].index; switch (index) { @@ -2320,7 +2352,8 @@ static int kvm_get_msrs(X86CPU *cpu) break; case MSR_MTRRphysBase(0) ... MSR_MTRRphysMask(MSR_MTRRcap_VCNT - 1): if (index & 1) { - env->mtrr_var[MSR_MTRRphysIndex(index)].mask = msrs[i].data; + env->mtrr_var[MSR_MTRRphysIndex(index)].mask = msrs[i].data | + mtrr_top_bits; } else { env->mtrr_var[MSR_MTRRphysIndex(index)].base = msrs[i].data; } |