diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 152eb090d678..9bc9c330aaa6 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1044,57 +1044,21 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu, target_ulong opcode, target_ulong *args) { - uint64_t characteristics = H_CPU_CHAR_HON_BRANCH_HINTS & - ~H_CPU_CHAR_THR_RECONF_TRIG; - uint64_t behaviour = H_CPU_BEHAV_FAVOUR_SECURITY; - int safe_cache = kvmppc_get_cap_safe_cache(); - int safe_bounds_check = kvmppc_get_cap_safe_bounds_check(); - int safe_indirect_branch = kvmppc_get_cap_safe_indirect_branch(); - - switch (safe_cache) { - case 1: - characteristics |= H_CPU_CHAR_L1D_FLUSH_ORI30; - characteristics |= H_CPU_CHAR_L1D_FLUSH_TRIG2; - characteristics |= H_CPU_CHAR_L1D_THREAD_PRIV; - behaviour |= H_CPU_BEHAV_L1D_FLUSH_PR; - break; - case 2: - break; - default: /* broken */ - if (safe_cache != 0) { - error_report("Invalid value for safe cache (%d), assuming broken", - safe_cache); + uint64_t characteristics = kvmppc_get_cap_ppc_cpu_char_character(); + uint64_t behaviour = kvmppc_get_cap_ppc_cpu_char_behaviour(); + + characteristics |= H_CPU_CHAR_HON_BRANCH_HINTS; + + if (behaviour & H_CPU_BEHAV_L1D_FLUSH_PR) { + /* + * To enable P8->P9 & P9->P8 migration, if either of the cache flush + * instructions are available, then tell the guest to use both. + */ + if (characteristics & (H_CPU_CHAR_L1D_FLUSH_ORI30 | + H_CPU_CHAR_L1D_FLUSH_TRIG2)) { + characteristics |= H_CPU_CHAR_L1D_FLUSH_ORI30 | + H_CPU_CHAR_L1D_FLUSH_TRIG2; } - behaviour |= H_CPU_BEHAV_L1D_FLUSH_PR; - break; - } - - switch (safe_bounds_check) { - case 1: - characteristics |= H_CPU_CHAR_SPEC_BAR_ORI31; - behaviour |= H_CPU_BEHAV_BNDS_CHK_SPEC_BAR; - break; - case 2: - break; - default: /* broken */ - if (safe_bounds_check != 0) { - error_report("Invalid value for safe bounds check (%d), assuming broken", - safe_bounds_check); - } - behaviour |= H_CPU_BEHAV_BNDS_CHK_SPEC_BAR; - break; - } - - switch (safe_indirect_branch) { - case 2: - characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED; - break; - default: /* broken */ - if (safe_indirect_branch != 0) { - error_report("Invalid value for safe indirect branch (%d), assuming broken", - safe_indirect_branch); - } - break; } args[0] = characteristics; diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 17a0d4cbd85b..f338ae1de4ae 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -80,9 +80,8 @@ static int cap_ppc_watchdog; static int cap_papr; static int cap_htab_fd; static int cap_fixup_hcalls; -static int cap_ppc_safe_cache; -static int cap_ppc_safe_bounds_check; -static int cap_ppc_safe_indirect_branch; +static uint64_t cap_ppc_cpu_char_character; +static uint64_t cap_ppc_cpu_char_behaviour; static uint32_t debug_inst_opcode; @@ -2350,11 +2349,6 @@ static void kvmppc_get_cpu_characteristics(KVMState *s) struct kvm_ppc_cpu_char c; int ret; - /* Assume broken */ - cap_ppc_safe_cache = 0; - cap_ppc_safe_bounds_check = 0; - cap_ppc_safe_indirect_branch = 0; - ret = kvm_vm_check_extension(s, KVM_CAP_PPC_GET_CPU_CHAR); if (!ret) { return; @@ -2363,39 +2357,19 @@ static void kvmppc_get_cpu_characteristics(KVMState *s) if (ret < 0) { return; } - /* Parse and set cap_ppc_safe_cache */ - if (~c.behaviour & c.b_mask & H_CPU_BEHAV_L1D_FLUSH_PR) { - cap_ppc_safe_cache = 2; - } else if ((c.character & c.c_mask & H_CPU_CHAR_L1D_THREAD_PRIV) && - (c.character & c.c_mask & (H_CPU_CHAR_L1D_FLUSH_ORI30 | - H_CPU_CHAR_L1D_FLUSH_TRIG2))) { - cap_ppc_safe_cache = 1; - } - /* Parse and set cap_ppc_safe_bounds_check */ - if (~c.behaviour & c.b_mask & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR) { - cap_ppc_safe_bounds_check = 2; - } else if (c.character & c.c_mask & H_CPU_CHAR_SPEC_BAR_ORI31) { - cap_ppc_safe_bounds_check = 1; - } - /* Parse and set cap_ppc_safe_indirect_branch */ - if (c.character & H_CPU_CHAR_BCCTRL_SERIALISED) { - cap_ppc_safe_indirect_branch = 2; - } -} -int kvmppc_get_cap_safe_cache(void) -{ - return cap_ppc_safe_cache; + cap_ppc_cpu_char_character = c.character & c.c_mask; + cap_ppc_cpu_char_behaviour = c.behaviour & c.b_mask; } -int kvmppc_get_cap_safe_bounds_check(void) +uint64_t kvmppc_get_cap_ppc_cpu_char_character(void) { - return cap_ppc_safe_bounds_check; + return cap_ppc_cpu_char_character; } -int kvmppc_get_cap_safe_indirect_branch(void) +uint64_t kvmppc_get_cap_ppc_cpu_char_behaviour(void) { - return cap_ppc_safe_indirect_branch; + return cap_ppc_cpu_char_behaviour; } static PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc) diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index 1fb7714bff05..15c8af37f7eb 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -54,9 +54,8 @@ void kvmppc_hash64_free_pteg(uint64_t token); void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index, target_ulong pte0, target_ulong pte1); bool kvmppc_has_cap_fixup_hcalls(void); -int kvmppc_get_cap_safe_cache(void); -int kvmppc_get_cap_safe_bounds_check(void); -int kvmppc_get_cap_safe_indirect_branch(void); +uint64_t kvmppc_get_cap_ppc_cpu_char_character(void); +uint64_t kvmppc_get_cap_ppc_cpu_char_behaviour(void); int kvmppc_enable_hwrng(void); int kvmppc_put_books_sregs(PowerPCCPU *cpu); PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void); @@ -247,19 +246,14 @@ static inline bool kvmppc_has_cap_fixup_hcalls(void) abort(); } -static inline int kvmppc_get_cap_safe_cache(void) +static inline uint64_t kvmppc_get_cap_ppc_cpu_char_character(void) { - return 0; -} - -static inline int kvmppc_get_cap_safe_bounds_check(void) -{ - return 0; + return 0ULL; } -static inline int kvmppc_get_cap_safe_indirect_branch(void) +static inline uint64_t kvmppc_get_cap_ppc_cpu_char_behaviour(void) { - return 0; + return 0ULL; } static inline int kvmppc_enable_hwrng(void)