Skip to content

Commit

Permalink
Merge pull request #2 from rmatinata/rmm-new-hput_char2
Browse files Browse the repository at this point in the history
target-ppc: Handle additional bits in H_GET_CPU_CHARACTERISTICS
  • Loading branch information
malcolmcrossley committed Mar 6, 2018
2 parents 8188e66 + 9e7dc71 commit ffccbb8
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 96 deletions.
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

0 comments on commit ffccbb8

Please sign in to comment.