diff options
author | Cédric Le Goater <clg@kaod.org> | 2018-06-06 09:33:53 +0200 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2018-06-12 10:44:36 +1000 |
commit | c8fd8373e42821984400382cd91b8bf4e7c14e3b (patch) | |
tree | 429581c1c7425f21eb676092f9348b971513471a /target/ppc/translate.c | |
parent | 3431bdf5a3c3bd732f78b0433471c2b1cb373564 (diff) | |
download | qemu-c8fd8373e42821984400382cd91b8bf4e7c14e3b.zip |
target/ppc: extend eieio for POWER9
POWER9 introduced a new variant of the eieio instruction using bit 6
as a hint to tell the CPU it is a store-forwarding barrier.
The usage of this eieio extension was recently added in Linux 4.17
which activated the "support for a store forwarding barrier at kernel
entry/exit".
Unfortunately, it is not possible to insert this new eieio instruction
without considerable change in ppc_tr_translate_insn(). So instead we
loosen the QEMU eieio instruction mask and modify the gen_eieio()
helper to test for bit6. On non-POWER9 CPUs, the bit6 is just ignored
but a warning is emitted as this is not an instruction software should
be using.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target/ppc/translate.c')
-rw-r--r-- | target/ppc/translate.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 8ba8f67dc5..5fe1ba6555 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -2967,7 +2967,28 @@ static void gen_stswx(DisasContext *ctx) /* eieio */ static void gen_eieio(DisasContext *ctx) { - tcg_gen_mb(TCG_MO_LD_ST | TCG_BAR_SC); + TCGBar bar = TCG_MO_LD_ST; + + /* + * POWER9 has a eieio instruction variant using bit 6 as a hint to + * tell the CPU it is a store-forwarding barrier. + */ + if (ctx->opcode & 0x2000000) { + /* + * ISA says that "Reserved fields in instructions are ignored + * by the processor". So ignore the bit 6 on non-POWER9 CPU but + * as this is not an instruction software should be using, + * complain to the user. + */ + if (!(ctx->insns_flags2 & PPC2_ISA300)) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid eieio using bit 6 at @" + TARGET_FMT_lx "\n", ctx->base.pc_next - 4); + } else { + bar = TCG_MO_ST_LD; + } + } + + tcg_gen_mb(bar | TCG_BAR_SC); } #if !defined(CONFIG_USER_ONLY) @@ -6483,7 +6504,7 @@ GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING), GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING), GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING), GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING), -GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO), +GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x01FFF801, PPC_MEM_EIEIO), GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM), GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206), GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206), |