diff options
author | Peter Maydell | 2016-06-14 10:30:05 +0200 |
---|---|---|
committer | Peter Maydell | 2016-06-14 10:30:05 +0200 |
commit | a28aae041aa76a779df6467a7fe68b9e8a8b2c0a (patch) | |
tree | 4b5ff0e7a997bae3b58ef16f52c57faf49bdf50c /target-ppc | |
parent | Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-20160613-1' into s... (diff) | |
parent | spapr: Ensure all LMBs are represented in ibm,dynamic-memory (diff) | |
download | qemu-a28aae041aa76a779df6467a7fe68b9e8a8b2c0a.tar.gz qemu-a28aae041aa76a779df6467a7fe68b9e8a8b2c0a.tar.xz qemu-a28aae041aa76a779df6467a7fe68b9e8a8b2c0a.zip |
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.7-20160614' into staging
ppc patch queue for 2016-06-14
Latest patch queue for ppc.
* Allow qemu to support a generic architecture 2.07 (POWER8-era)
compatibility mode. This is useful for guests which are POWER8
aware, but don't know about the specific POWER8 variant that
qemu (and/or KVM) is emulating. (Thomas Huth)
* Fix a bug where macio wasn't removing DMA mappings (Mark Cave-Ayland)
* Add a workaround for Linux guest's miscalculation of maximum
memory address (including hotplugged memory), which could break
when hotplug memory was combined with VFIO. The previous
approach was technically correct by spec, but differed from
PowerVM's behaviour enough to trip a guest kernel bug. This
works around the bug, while remaining correct-to-spec. (Bharata Rao)
# gpg: Signature made Tue 14 Jun 2016 06:53:58 BST
# gpg: using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg: It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392
* remotes/dgibson/tags/ppc-for-2.7-20160614:
spapr: Ensure all LMBs are represented in ibm,dynamic-memory
macio: call dma_memory_unmap() at the end of each DMA transfer
Add PowerPC AT_HWCAP2 definitions
ppc: Add PowerISA 2.07 compatibility mode
ppc: Improve PCR bit selection in ppc_set_compat()
ppc: Provide function to get CPU class of the host CPU
ppc: Split pcr_mask settings into supported bits and the register mask
ppc/spapr: Refactor h_client_architecture_support() CPU parsing code
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-ppc')
-rw-r--r-- | target-ppc/cpu-qom.h | 3 | ||||
-rw-r--r-- | target-ppc/cpu.h | 3 | ||||
-rw-r--r-- | target-ppc/kvm.c | 19 | ||||
-rw-r--r-- | target-ppc/kvm_ppc.h | 7 | ||||
-rw-r--r-- | target-ppc/translate_init.c | 24 |
5 files changed, 44 insertions, 12 deletions
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h index 07358aadf3..969ecdfbd4 100644 --- a/target-ppc/cpu-qom.h +++ b/target-ppc/cpu-qom.h @@ -165,7 +165,8 @@ typedef struct PowerPCCPUClass { uint32_t pvr; bool (*pvr_match)(struct PowerPCCPUClass *pcc, uint32_t pvr); - uint64_t pcr_mask; + uint64_t pcr_mask; /* Available bits in PCR register */ + uint64_t pcr_supported; /* Bits for supported PowerISA versions */ uint32_t svr; uint64_t insns_flags; uint64_t insns_flags2; diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index cb8b9122f3..93c2dd5a65 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1187,7 +1187,9 @@ void ppc_store_msr (CPUPPCState *env, target_ulong value); void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf); int ppc_get_compat_smt_threads(PowerPCCPU *cpu); +#if defined(TARGET_PPC64) void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp); +#endif /* Time-base and decrementer management */ #ifndef NO_CPU_IO_DEFS @@ -2200,6 +2202,7 @@ enum { enum { PCR_COMPAT_2_05 = 1ull << (63-62), PCR_COMPAT_2_06 = 1ull << (63-61), + PCR_COMPAT_2_07 = 1ull << (63-60), PCR_VEC_DIS = 1ull << (63-0), /* Vec. disable (bit NA since POWER8) */ PCR_VSX_DIS = 1ull << (63-1), /* VSX disable (bit NA since POWER8) */ PCR_TM_DIS = 1ull << (63-2), /* Trans. memory disable (POWER8) */ diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 24d6032007..6c153611c0 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -2329,6 +2329,19 @@ static PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc) return POWERPC_CPU_CLASS(oc); } +PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void) +{ + uint32_t host_pvr = mfpvr(); + PowerPCCPUClass *pvr_pcc; + + pvr_pcc = ppc_cpu_class_by_pvr(host_pvr); + if (pvr_pcc == NULL) { + pvr_pcc = ppc_cpu_class_by_pvr_mask(host_pvr); + } + + return pvr_pcc; +} + static int kvm_ppc_register_host_cpu_type(void) { TypeInfo type_info = { @@ -2336,14 +2349,10 @@ static int kvm_ppc_register_host_cpu_type(void) .instance_init = kvmppc_host_cpu_initfn, .class_init = kvmppc_host_cpu_class_init, }; - uint32_t host_pvr = mfpvr(); PowerPCCPUClass *pvr_pcc; DeviceClass *dc; - pvr_pcc = ppc_cpu_class_by_pvr(host_pvr); - if (pvr_pcc == NULL) { - pvr_pcc = ppc_cpu_class_by_pvr_mask(host_pvr); - } + pvr_pcc = kvm_ppc_get_host_cpu_class(); if (pvr_pcc == NULL) { return -1; } diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index 3b2090e42e..20bfb59b1a 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -56,6 +56,7 @@ void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index, bool kvmppc_has_cap_fixup_hcalls(void); int kvmppc_enable_hwrng(void); int kvmppc_put_books_sregs(PowerPCCPU *cpu); +PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void); #else @@ -252,6 +253,12 @@ static inline int kvmppc_put_books_sregs(PowerPCCPU *cpu) { abort(); } + +static inline PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void) +{ + return NULL; +} + #endif #ifndef CONFIG_KVM diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index a1db5009c4..ca894ff4af 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8365,7 +8365,8 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) dc->desc = "POWER7"; dc->props = powerpc_servercpu_properties; pcc->pvr_match = ppc_pvr_match_power7; - pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06; + pcc->pcr_mask = PCR_VEC_DIS | PCR_VSX_DIS | PCR_COMPAT_2_05; + pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER7; pcc->check_pow = check_pow_nocheck; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | @@ -8445,7 +8446,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) dc->desc = "POWER8"; dc->props = powerpc_servercpu_properties; pcc->pvr_match = ppc_pvr_match_power8; - pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06; + pcc->pcr_mask = PCR_TM_DIS | PCR_COMPAT_2_06 | PCR_COMPAT_2_05; + pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER8; pcc->check_pow = check_pow_nocheck; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | @@ -9513,28 +9515,37 @@ int ppc_get_compat_smt_threads(PowerPCCPU *cpu) return ret; } +#ifdef TARGET_PPC64 void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp) { int ret = 0; CPUPPCState *env = &cpu->env; + PowerPCCPUClass *host_pcc; cpu->cpu_version = cpu_version; switch (cpu_version) { case CPU_POWERPC_LOGICAL_2_05: - env->spr[SPR_PCR] = PCR_COMPAT_2_05; + env->spr[SPR_PCR] = PCR_TM_DIS | PCR_VSX_DIS | PCR_COMPAT_2_07 | + PCR_COMPAT_2_06 | PCR_COMPAT_2_05; break; case CPU_POWERPC_LOGICAL_2_06: - env->spr[SPR_PCR] = PCR_COMPAT_2_06; - break; case CPU_POWERPC_LOGICAL_2_06_PLUS: - env->spr[SPR_PCR] = PCR_COMPAT_2_06; + env->spr[SPR_PCR] = PCR_TM_DIS | PCR_COMPAT_2_07 | PCR_COMPAT_2_06; + break; + case CPU_POWERPC_LOGICAL_2_07: + env->spr[SPR_PCR] = PCR_COMPAT_2_07; break; default: env->spr[SPR_PCR] = 0; break; } + host_pcc = kvm_ppc_get_host_cpu_class(); + if (host_pcc) { + env->spr[SPR_PCR] &= host_pcc->pcr_mask; + } + if (kvm_enabled()) { ret = kvmppc_set_compat(cpu, cpu->cpu_version); if (ret < 0) { @@ -9543,6 +9554,7 @@ void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp) } } } +#endif static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b) { |