Skip to content

Commit

Permalink
target/ppc: Check DEXCR on hash{st, chk} instructions
Browse files Browse the repository at this point in the history
Adds checks to the hashst and hashchk instructions to only execute if
enabled by the relevant aspect in the DEXCR and HDEXCR.

This behaviour is guarded behind TARGET_PPC64 since Power10 is
currently the only implementation which has the DEXCR.

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Nicholas Miehlbradt <nicholas@linux.ibm.com>
Message-Id: <20221220042330.2387944-3-nicholas@linux.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
  • Loading branch information
Nicholas Miehlbradt authored and danielhb committed Dec 20, 2022
1 parent 7799c5f commit bac9fdf
Showing 1 changed file with 43 additions and 15 deletions.
58 changes: 43 additions & 15 deletions target/ppc/excp_helper.c
Expand Up @@ -2902,29 +2902,57 @@ static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key)
return stage1_h ^ stage1_l;
}

static void do_hash(CPUPPCState *env, target_ulong ea, target_ulong ra,
target_ulong rb, uint64_t key, bool store)
{
uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash;

if (store) {
cpu_stq_data_ra(env, ea, calculated_hash, GETPC());
} else {
loaded_hash = cpu_ldq_data_ra(env, ea, GETPC());
if (loaded_hash != calculated_hash) {
raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
POWERPC_EXCP_TRAP, GETPC());
}
}
}

#include "qemu/guest-random.h"

#define HELPER_HASH(op, key, store) \
#ifdef TARGET_PPC64
#define HELPER_HASH(op, key, store, dexcr_aspect) \
void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \
target_ulong rb) \
{ \
uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash; \
\
if (store) { \
cpu_stq_data_ra(env, ea, calculated_hash, GETPC()); \
} else { \
loaded_hash = cpu_ldq_data_ra(env, ea, GETPC()); \
if (loaded_hash != calculated_hash) { \
raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, \
POWERPC_EXCP_TRAP, GETPC()); \
} \
if (env->msr & R_MSR_PR_MASK) { \
if (!(env->spr[SPR_DEXCR] & R_DEXCR_PRO_##dexcr_aspect##_MASK || \
env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \
return; \
} else if (!(env->msr & R_MSR_HV_MASK)) { \
if (!(env->spr[SPR_DEXCR] & R_DEXCR_PNH_##dexcr_aspect##_MASK || \
env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \
return; \
} else if (!(env->msr & R_MSR_S_MASK)) { \
if (!(env->spr[SPR_HDEXCR] & R_HDEXCR_HNU_##dexcr_aspect##_MASK)) \
return; \
} \
\
do_hash(env, ea, ra, rb, key, store); \
}
#else
#define HELPER_HASH(op, key, store, dexcr_aspect) \
void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \
target_ulong rb) \
{ \
do_hash(env, ea, ra, rb, key, store); \
}
#endif /* TARGET_PPC64 */

HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true)
HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false)
HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true)
HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false)
HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true, NPHIE)
HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false, NPHIE)
HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true, PHIE)
HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false, PHIE)
#endif /* CONFIG_TCG */

#if !defined(CONFIG_USER_ONLY)
Expand Down

0 comments on commit bac9fdf

Please sign in to comment.