qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Henrique Barboza <danielhb413@gmail.com>
To: Leandro Lupori <leandro.lupori@eldorado.org.br>,
	qemu-devel@nongnu.org, qemu-ppc@nongnu.org
Cc: clg@kaod.org, david@gibson.dropbear.id.au, groug@kaod.org,
	npiggin@gmail.com, richard.henderson@linaro.org
Subject: Re: [PATCH v3 2/2] target/ppc: Implement ISA 3.00 tlbie[l]
Date: Thu, 14 Jul 2022 15:48:38 -0300	[thread overview]
Message-ID: <e23d167e-2a2e-5f85-1042-119c1c12803a@gmail.com> (raw)
In-Reply-To: <20220712193741.59134-3-leandro.lupori@eldorado.org.br>



On 7/12/22 16:37, Leandro Lupori wrote:
> This initial version supports the invalidation of one or all
> TLB entries. Flush by PID/LPID, or based in process/partition
> scope is not supported, because it would make using the
> generic QEMU TLB implementation hard. In these cases, all
> entries are flushed.
> 
> Signed-off-by: Leandro Lupori <leandro.lupori@eldorado.org.br>
> ---

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>


>   target/ppc/helper.h                          |   2 +
>   target/ppc/mmu-book3s-v3.h                   |  15 ++
>   target/ppc/mmu_helper.c                      | 154 +++++++++++++++++++
>   target/ppc/translate/storage-ctrl-impl.c.inc |  17 ++
>   4 files changed, 188 insertions(+)
> 
> diff --git a/target/ppc/helper.h b/target/ppc/helper.h
> index d627cfe6ed..90d16f00e7 100644
> --- a/target/ppc/helper.h
> +++ b/target/ppc/helper.h
> @@ -672,6 +672,8 @@ DEF_HELPER_FLAGS_1(tlbia, TCG_CALL_NO_RWG, void, env)
>   DEF_HELPER_FLAGS_2(tlbie, TCG_CALL_NO_RWG, void, env, tl)
>   DEF_HELPER_FLAGS_2(tlbiva, TCG_CALL_NO_RWG, void, env, tl)
>   #if defined(TARGET_PPC64)
> +DEF_HELPER_FLAGS_4(tlbie_isa300, TCG_CALL_NO_WG, void, \
> +        env, tl, tl, i32)
>   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)
> diff --git a/target/ppc/mmu-book3s-v3.h b/target/ppc/mmu-book3s-v3.h
> index d6d5ed8f8e..674377a19e 100644
> --- a/target/ppc/mmu-book3s-v3.h
> +++ b/target/ppc/mmu-book3s-v3.h
> @@ -50,6 +50,21 @@ struct prtb_entry {
>   
>   #ifdef TARGET_PPC64
>   
> +/*
> + * tlbie[l] helper flags
> + *
> + * RIC, PRS, R and local are passed as flags in the last argument.
> + */
> +#define TLBIE_F_RIC_SHIFT       0
> +#define TLBIE_F_PRS_SHIFT       2
> +#define TLBIE_F_R_SHIFT         3
> +#define TLBIE_F_LOCAL_SHIFT     4
> +
> +#define TLBIE_F_RIC_MASK        (3 << TLBIE_F_RIC_SHIFT)
> +#define TLBIE_F_PRS             (1 << TLBIE_F_PRS_SHIFT)
> +#define TLBIE_F_R               (1 << TLBIE_F_R_SHIFT)
> +#define TLBIE_F_LOCAL           (1 << TLBIE_F_LOCAL_SHIFT)
> +
>   static inline bool ppc64_use_proc_tbl(PowerPCCPU *cpu)
>   {
>       return !!(cpu->env.spr[SPR_LPCR] & LPCR_UPRT);
> diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> index 15239dc95b..b881aee23f 100644
> --- a/target/ppc/mmu_helper.c
> +++ b/target/ppc/mmu_helper.c
> @@ -429,6 +429,160 @@ void helper_tlbie(CPUPPCState *env, target_ulong addr)
>       ppc_tlb_invalidate_one(env, addr);
>   }
>   
> +#if defined(TARGET_PPC64)
> +
> +/* Invalidation Selector */
> +#define TLBIE_IS_VA         0
> +#define TLBIE_IS_PID        1
> +#define TLBIE_IS_LPID       2
> +#define TLBIE_IS_ALL        3
> +
> +/* Radix Invalidation Control */
> +#define TLBIE_RIC_TLB       0
> +#define TLBIE_RIC_PWC       1
> +#define TLBIE_RIC_ALL       2
> +#define TLBIE_RIC_GRP       3
> +
> +/* Radix Actual Page sizes */
> +#define TLBIE_R_AP_4K       0
> +#define TLBIE_R_AP_64K      5
> +#define TLBIE_R_AP_2M       1
> +#define TLBIE_R_AP_1G       2
> +
> +/* RB field masks */
> +#define TLBIE_RB_EPN_MASK   PPC_BITMASK(0, 51)
> +#define TLBIE_RB_IS_MASK    PPC_BITMASK(52, 53)
> +#define TLBIE_RB_AP_MASK    PPC_BITMASK(56, 58)
> +
> +void helper_tlbie_isa300(CPUPPCState *env, target_ulong rb, target_ulong rs,
> +                         uint32_t flags)
> +{
> +    unsigned ric = (flags & TLBIE_F_RIC_MASK) >> TLBIE_F_RIC_SHIFT;
> +    /*
> +     * With the exception of the checks for invalid instruction forms,
> +     * PRS is currently ignored, because we don't know if a given TLB entry
> +     * is process or partition scoped.
> +     */
> +    bool prs = flags & TLBIE_F_PRS;
> +    bool r = flags & TLBIE_F_R;
> +    bool local = flags & TLBIE_F_LOCAL;
> +    bool effR;
> +    unsigned is = extract64(rb, PPC_BIT_NR(53), 2), set;
> +    unsigned ap;        /* actual page size */
> +    target_ulong addr, pgoffs_mask;
> +
> +    qemu_log_mask(CPU_LOG_MMU,
> +        "%s: local=%d addr=" TARGET_FMT_lx " ric=%u prs=%d r=%d is=%u\n",
> +        __func__, local, rb & TARGET_PAGE_MASK, ric, prs, r, is);
> +
> +    effR = FIELD_EX64(env->msr, MSR, HV) ? r : env->spr[SPR_LPCR] & LPCR_HR;
> +
> +    /* Partial TLB invalidation is supported for Radix only for now. */
> +    if (!effR) {
> +        goto inval_all;
> +    }
> +
> +    /* Check for invalid instruction forms (effR=1). */
> +    if (unlikely(ric == TLBIE_RIC_GRP ||
> +                 ((ric == TLBIE_RIC_PWC || ric == TLBIE_RIC_ALL) &&
> +                                           is == TLBIE_IS_VA) ||
> +                 (!prs && is == TLBIE_IS_PID))) {
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +            "%s: invalid instruction form: ric=%u prs=%d r=%d is=%u\n",
> +            __func__, ric, prs, r, is);
> +        goto invalid;
> +    }
> +
> +    /* We don't cache Page Walks. */
> +    if (ric == TLBIE_RIC_PWC) {
> +        if (local) {
> +            set = extract64(rb, PPC_BIT_NR(51), 12);
> +            if (set != 0) {
> +                qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid set: %d\n",
> +                              __func__, set);
> +                goto invalid;
> +            }
> +        }
> +        return;
> +    }
> +
> +    /*
> +     * Invalidation by LPID or PID is not supported, so fallback
> +     * to full TLB flush in these cases.
> +     */
> +    if (is != TLBIE_IS_VA) {
> +        goto inval_all;
> +    }
> +
> +    /*
> +     * The results of an attempt to invalidate a translation outside of
> +     * quadrant 0 for Radix Tree translation (effR=1, RIC=0, PRS=1, IS=0,
> +     * and EA 0:1 != 0b00) are boundedly undefined.
> +     */
> +    if (unlikely(ric == TLBIE_RIC_TLB && prs && is == TLBIE_IS_VA &&
> +                 (rb & R_EADDR_QUADRANT) != R_EADDR_QUADRANT0)) {
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +            "%s: attempt to invalidate a translation outside of quadrant 0\n",
> +            __func__);
> +        goto inval_all;
> +    }
> +
> +    assert(is == TLBIE_IS_VA);
> +    assert(ric == TLBIE_RIC_TLB || ric == TLBIE_RIC_ALL);
> +
> +    ap = extract64(rb, PPC_BIT_NR(58), 3);
> +    switch (ap) {
> +    case TLBIE_R_AP_4K:
> +        pgoffs_mask = 0xfffull;
> +        break;
> +
> +    case TLBIE_R_AP_64K:
> +        pgoffs_mask = 0xffffull;
> +        break;
> +
> +    case TLBIE_R_AP_2M:
> +        pgoffs_mask = 0x1fffffull;
> +        break;
> +
> +    case TLBIE_R_AP_1G:
> +        pgoffs_mask = 0x3fffffffull;
> +        break;
> +
> +    default:
> +        /*
> +         * If the value specified in RS 0:31, RS 32:63, RB 54:55, RB 56:58,
> +         * RB 44:51, or RB 56:63, when it is needed to perform the specified
> +         * operation, is not supported by the implementation, the instruction
> +         * is treated as if the instruction form were invalid.
> +         */
> +        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid AP: %d\n", __func__, ap);
> +        goto invalid;
> +    }
> +
> +    addr = rb & TLBIE_RB_EPN_MASK & ~pgoffs_mask;
> +
> +    if (local) {
> +        tlb_flush_page(env_cpu(env), addr);
> +    } else {
> +        tlb_flush_page_all_cpus(env_cpu(env), addr);
> +    }
> +    return;
> +
> +inval_all:
> +    env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;
> +    if (!local) {
> +        env->tlb_need_flush |= TLB_NEED_GLOBAL_FLUSH;
> +    }
> +    return;
> +
> +invalid:
> +    raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
> +                           POWERPC_EXCP_INVAL |
> +                           POWERPC_EXCP_INVAL_INVAL, GETPC());
> +}
> +
> +#endif
> +
>   void helper_tlbiva(CPUPPCState *env, target_ulong addr)
>   {
>       /* tlbiva instruction only exists on BookE */
> diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc
> index 7793297dd4..467c390888 100644
> --- a/target/ppc/translate/storage-ctrl-impl.c.inc
> +++ b/target/ppc/translate/storage-ctrl-impl.c.inc
> @@ -21,6 +21,8 @@
>    * Store Control Instructions
>    */
>   
> +#include "mmu-book3s-v3.h"
> +
>   static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local)
>   {
>   #if defined(CONFIG_USER_ONLY)
> @@ -65,6 +67,21 @@ static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local)
>           tcg_gen_ext32u_tl(t0, cpu_gpr[rb]);
>           gen_helper_tlbie(cpu_env, t0);
>           tcg_temp_free(t0);
> +
> +#if defined(TARGET_PPC64)
> +    /*
> +     * ISA 3.1B says that MSR SF must be 1 when this instruction is executed;
> +     * otherwise the results are undefined.
> +     */
> +    } else if (a->r) {
> +        gen_helper_tlbie_isa300(cpu_env, cpu_gpr[rb], cpu_gpr[a->rs],
> +                tcg_constant_i32(a->ric << TLBIE_F_RIC_SHIFT |
> +                                 a->prs << TLBIE_F_PRS_SHIFT |
> +                                 a->r << TLBIE_F_R_SHIFT |
> +                                 local << TLBIE_F_LOCAL_SHIFT));
> +        return true;
> +#endif
> +
>       } else {
>           gen_helper_tlbie(cpu_env, cpu_gpr[rb]);
>       }


  reply	other threads:[~2022-07-14 18:59 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-12 19:37 [PATCH v3 0/2] target/ppc: Implement ISA 3.00 tlbie[l] Leandro Lupori
2022-07-12 19:37 ` [PATCH v3 1/2] target/ppc: Move tlbie[l] to decode tree Leandro Lupori
2022-07-14 18:45   ` Daniel Henrique Barboza
2022-07-14 19:31     ` Leandro Lupori
2022-07-14 19:36       ` Daniel Henrique Barboza
2022-07-12 19:37 ` [PATCH v3 2/2] target/ppc: Implement ISA 3.00 tlbie[l] Leandro Lupori
2022-07-14 18:48   ` Daniel Henrique Barboza [this message]
2022-07-14 20:48 ` [PATCH v3 0/2] " Daniel Henrique Barboza

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e23d167e-2a2e-5f85-1042-119c1c12803a@gmail.com \
    --to=danielhb413@gmail.com \
    --cc=clg@kaod.org \
    --cc=david@gibson.dropbear.id.au \
    --cc=groug@kaod.org \
    --cc=leandro.lupori@eldorado.org.br \
    --cc=npiggin@gmail.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).