From 980381bbdeeee2266e23e953567d9b7fa6501dda Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 15 Jun 2016 20:35:17 +0200 Subject: [PATCH 05/13] ppc: Improve PCR bit selection in ppc_set_compat() RH-Author: Thomas Huth Message-id: <1466022918-18958-5-git-send-email-thuth@redhat.com> Patchwork-id: 70629 O-Subject: [RHEL-7.3 qemu-kvm-rhev PATCH 4/5] ppc: Improve PCR bit selection in ppc_set_compat() Bugzilla: 1341492 RH-Acked-by: Laszlo Ersek RH-Acked-by: Laurent Vivier RH-Acked-by: David Gibson When using an olderr PowerISA level, all the upper compatibility bits have to be enabled, too. For example when we want to run something in PowerISA 2.05 compatibility mode on POWER8, the bit for 2.06 has to be set beside the bit for 2.05. Additionally, to make sure that we do not set bits that are not supported by the host, we apply a mask with the known-to-be-good bits here, too. Signed-off-by: Thomas Huth [dwg: Added some #ifs to fix compile on 32-bit targets] Signed-off-by: David Gibson (cherry picked from commit eac4fba965136f61cc239a450bec12adcef6b449) Signed-off-by: Miroslav Rezanina --- target-ppc/cpu.h | 2 ++ target-ppc/translate_init.c | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 5a96c1e..8bf9af3 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1239,7 +1239,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 diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 1356ce8..0e295e5 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -9504,28 +9504,34 @@ 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; 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) { @@ -9534,6 +9540,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) { -- 1.8.3.1