Skip to content

Commit

Permalink
target/ppc: Fix ISA v3.0 (POWER9) slbia implementation
Browse files Browse the repository at this point in the history
The new ISA v3.0 slbia variants have not been implemented for TCG,
which can lead to crashing when a POWER9 machine boots Linux using
the hash MMU, for example ("disable_radix" kernel command line).

Add them.

Signed-off-by: Nicholas Piggin <[email protected]>
Message-Id: <[email protected]>
Reviewed-by: Cédric Le Goater <[email protected]>
[dwg: Fixed compile error for USER_ONLY builds]
Signed-off-by: David Gibson <[email protected]>
  • Loading branch information
npiggin authored and dgibson committed Mar 24, 2020
1 parent f9e3e1a commit 0418bf7
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 9 deletions.
2 changes: 1 addition & 1 deletion target/ppc/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ DEF_HELPER_FLAGS_3(store_slb, TCG_CALL_NO_RWG, void, env, tl, tl)
DEF_HELPER_2(load_slb_esid, tl, env, tl)
DEF_HELPER_2(load_slb_vsid, tl, env, tl)
DEF_HELPER_2(find_slb_vsid, tl, env, tl)
DEF_HELPER_FLAGS_1(slbia, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_2(slbia, TCG_CALL_NO_RWG, void, env, i32)
DEF_HELPER_FLAGS_2(slbie, TCG_CALL_NO_RWG, void, env, tl)
DEF_HELPER_FLAGS_2(slbieg, TCG_CALL_NO_RWG, void, env, tl)
#endif
Expand Down
56 changes: 49 additions & 7 deletions target/ppc/mmu-hash64.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,10 @@ void dump_slb(PowerPCCPU *cpu)
}
}

void helper_slbia(CPUPPCState *env)
void helper_slbia(CPUPPCState *env, uint32_t ih)
{
PowerPCCPU *cpu = env_archcpu(env);
int starting_entry;
int n;

/*
Expand All @@ -111,18 +112,59 @@ void helper_slbia(CPUPPCState *env)
* expected that slbmte is more common than slbia, and slbia is usually
* going to evict valid SLB entries, so that tradeoff is unlikely to be a
* good one.
*
* ISA v2.05 introduced IH field with values 0,1,2,6. These all invalidate
* the same SLB entries (everything but entry 0), but differ in what
* "lookaside information" is invalidated. TCG can ignore this and flush
* everything.
*
* ISA v3.0 introduced additional values 3,4,7, which change what SLBs are
* invalidated.
*/

/* XXX: Warning: slbia never invalidates the first segment */
for (n = 1; n < cpu->hash64_opts->slb_size; n++) {
ppc_slb_t *slb = &env->slb[n];
env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;

starting_entry = 1; /* default for IH=0,1,2,6 */

if (env->mmu_model == POWERPC_MMU_3_00) {
switch (ih) {
case 0x7:
/* invalidate no SLBs, but all lookaside information */
return;

if (slb->esid & SLB_ESID_V) {
slb->esid &= ~SLB_ESID_V;
case 0x3:
case 0x4:
/* also considers SLB entry 0 */
starting_entry = 0;
break;

case 0x5:
/* treat undefined values as ih==0, and warn */
qemu_log_mask(LOG_GUEST_ERROR,
"slbia undefined IH field %u.\n", ih);
break;

default:
/* 0,1,2,6 */
break;
}
}

env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;
for (n = starting_entry; n < cpu->hash64_opts->slb_size; n++) {
ppc_slb_t *slb = &env->slb[n];

if (!(slb->esid & SLB_ESID_V)) {
continue;
}
if (env->mmu_model == POWERPC_MMU_3_00) {
if (ih == 0x3 && (slb->vsid & SLB_VSID_C) == 0) {
/* preserves entries with a class value of 0 */
continue;
}
}

slb->esid &= ~SLB_ESID_V;
}
}

static void __helper_slbie(CPUPPCState *env, target_ulong addr,
Expand Down
5 changes: 4 additions & 1 deletion target/ppc/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -4997,9 +4997,12 @@ static void gen_slbia(DisasContext *ctx)
#if defined(CONFIG_USER_ONLY)
GEN_PRIV;
#else
uint32_t ih = (ctx->opcode >> 21) & 0x7;
TCGv_i32 t0 = tcg_const_i32(ih);

CHK_SV;

gen_helper_slbia(cpu_env);
gen_helper_slbia(cpu_env, t0);
#endif /* defined(CONFIG_USER_ONLY) */
}

Expand Down

0 comments on commit 0418bf7

Please sign in to comment.