Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 14 additions & 50 deletions hw/ppc/spapr_hcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
42 changes: 8 additions & 34 deletions target-ppc/kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down
18 changes: 6 additions & 12 deletions target-ppc/kvm_ppc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down