diff options
Diffstat (limited to 'target-ppc')
-rw-r--r-- | target-ppc/helper.c | 9 | ||||
-rw-r--r-- | target-ppc/kvm.c | 14 | ||||
-rw-r--r-- | target-ppc/kvm_ppc.h | 5 | ||||
-rw-r--r-- | target-ppc/translate_init.c | 51 |
4 files changed, 54 insertions, 25 deletions
diff --git a/target-ppc/helper.c b/target-ppc/helper.c index f61b8b261e..b34dcbeb0f 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -3198,15 +3198,6 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model) if (tcg_enabled()) { ppc_translate_init(); } - /* Adjust cpu index for SMT */ -#if !defined(CONFIG_USER_ONLY) - if (kvm_enabled()) { - int smt = kvmppc_smt_threads(); - - env->cpu_index = (env->cpu_index / smp_threads)*smt - + (env->cpu_index % smp_threads); - } -#endif /* !CONFIG_USER_ONLY */ env->cpu_model_str = cpu_model; cpu_ppc_register_internal(env, def); diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index d929213a04..c09cc39c78 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -27,6 +27,7 @@ #include "kvm.h" #include "kvm_ppc.h" #include "cpu.h" +#include "cpus.h" #include "device_tree.h" #include "hw/sysbus.h" #include "hw/spapr.h" @@ -938,6 +939,19 @@ const ppc_def_t *kvmppc_host_cpu_def(void) return spec; } +int kvmppc_fixup_cpu(CPUPPCState *env) +{ + int smt; + + /* Adjust cpu index for SMT */ + smt = kvmppc_smt_threads(); + env->cpu_index = (env->cpu_index / smp_threads) * smt + + (env->cpu_index % smp_threads); + + return 0; +} + + bool kvm_arch_stop_on_emulation_error(CPUPPCState *env) { return true; diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index 8f1267c6cc..34ecad3e26 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -29,6 +29,7 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd); int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size); #endif /* !CONFIG_USER_ONLY */ const ppc_def_t *kvmppc_host_cpu_def(void); +int kvmppc_fixup_cpu(CPUPPCState *env); #else @@ -95,6 +96,10 @@ static inline const ppc_def_t *kvmppc_host_cpu_def(void) return NULL; } +static inline int kvmppc_fixup_cpu(CPUPPCState *env) +{ + return -1; +} #endif #ifndef CONFIG_KVM diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index b1f87854a0..067e07ea54 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -9889,6 +9889,28 @@ static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n) return 0; } +static int ppc_fixup_cpu(CPUPPCState *env) +{ + /* TCG doesn't (yet) emulate some groups of instructions that + * are implemented on some otherwise supported CPUs (e.g. VSX + * and decimal floating point instructions on POWER7). We + * remove unsupported instruction groups from the cpu state's + * instruction masks and hope the guest can cope. For at + * least the pseries machine, the unavailability of these + * instructions can be advertised to the guest via the device + * tree. */ + if ((env->insns_flags & ~PPC_TCG_INSNS) + || (env->insns_flags2 & ~PPC_TCG_INSNS2)) { + fprintf(stderr, "Warning: Disabling some instructions which are not " + "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")\n", + env->insns_flags & ~PPC_TCG_INSNS, + env->insns_flags2 & ~PPC_TCG_INSNS2); + } + env->insns_flags &= PPC_TCG_INSNS; + env->insns_flags2 &= PPC_TCG_INSNS2; + return 0; +} + int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def) { env->msr_mask = def->msr_mask; @@ -9897,25 +9919,22 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def) env->bus_model = def->bus_model; env->insns_flags = def->insns_flags; env->insns_flags2 = def->insns_flags2; - if (!kvm_enabled()) { - /* TCG doesn't (yet) emulate some groups of instructions that - * are implemented on some otherwise supported CPUs (e.g. VSX - * and decimal floating point instructions on POWER7). We - * remove unsupported instruction groups from the cpu state's - * instruction masks and hope the guest can cope. For at - * least the pseries machine, the unavailability of these - * instructions can be advertise to the guest via the device - * tree. - * - * FIXME: we should have a similar masking for CPU features - * not accessible under KVM, but so far, there aren't any of - * those. */ - env->insns_flags &= PPC_TCG_INSNS; - env->insns_flags2 &= PPC_TCG_INSNS2; - } env->flags = def->flags; env->bfd_mach = def->bfd_mach; env->check_pow = def->check_pow; + + if (kvm_enabled()) { + if (kvmppc_fixup_cpu(env) != 0) { + fprintf(stderr, "Unable to virtualize selected CPU with KVM\n"); + exit(1); + } + } else { + if (ppc_fixup_cpu(env) != 0) { + fprintf(stderr, "Unable to emulate selected CPU with TCG\n"); + exit(1); + } + } + if (create_ppc_opcodes(env, def) < 0) return -1; init_ppc_proc(env, def); |