qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: "Cédric Le Goater" <clg@kaod.org>
Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>
Subject: Re: [Qemu-devel] [PATCH 3/3] target/ppc: add support for hypervisor doorbells on book3s CPUs
Date: Thu, 18 Jan 2018 15:15:07 +1100	[thread overview]
Message-ID: <20180118041507.GF30352@umbus.fritz.box> (raw)
In-Reply-To: <20180116074157.16886-4-clg@kaod.org>

[-- Attachment #1: Type: text/plain, Size: 9225 bytes --]

On Tue, Jan 16, 2018 at 08:41:57AM +0100, Cédric Le Goater wrote:
> The hypervisor doorbells are used by skiboot and Linux on POWER9
> processors to wake up secondaries.
> 
> This adds processor control support to the Server architecture by
> reusing the Embedded support. They are very similar, only the bits
> definition of the CPU identifier differ.
> 
> Still to be done is message broadcast to all threads of the same
> processor.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  target/ppc/cpu.h            |  8 ++++++--
>  target/ppc/excp_helper.c    | 39 ++++++++++++++++++++++++++++++++-------
>  target/ppc/helper.h         |  2 +-
>  target/ppc/translate.c      | 13 ++++++++++++-
>  target/ppc/translate_init.c |  2 +-
>  5 files changed, 52 insertions(+), 12 deletions(-)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index b8f4dfc1084a..603a38cae83f 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -930,7 +930,7 @@ enum {
>  #define BOOKE206_MAX_TLBN      4
>  
>  /*****************************************************************************/
> -/* Embedded.Processor Control */
> +/* Server and Embedded Processor Control */
>  
>  #define DBELL_TYPE_SHIFT               27
>  #define DBELL_TYPE_MASK                (0x1f << DBELL_TYPE_SHIFT)
> @@ -940,11 +940,15 @@ enum {
>  #define DBELL_TYPE_G_DBELL_CRIT        (0x03 << DBELL_TYPE_SHIFT)
>  #define DBELL_TYPE_G_DBELL_MC          (0x04 << DBELL_TYPE_SHIFT)
>  
> -#define DBELL_BRDCAST                  (1 << 26)
> +#define DBELL_TYPE_DBELL_SERVER        (0x05 << DBELL_TYPE_SHIFT)
> +
> +#define DBELL_BRDCAST                  PPC_BIT(37)
>  #define DBELL_LPIDTAG_SHIFT            14
>  #define DBELL_LPIDTAG_MASK             (0xfff << DBELL_LPIDTAG_SHIFT)
>  #define DBELL_PIRTAG_MASK              0x3fff
>  
> +#define DBELL_PROCIDTAG_MASK           PPC_BITMASK(44, 63)
> +
>  /*****************************************************************************/
>  /* Segment page size information, used by recent hash MMUs
>   * The format of this structure mirrors kvm_ppc_smmu_info
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 4e548a448747..0f32cab1ff57 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -417,6 +417,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
>      case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */
>      case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */
> +    case POWERPC_EXCP_SDOOR_HV:  /* Hypervisor Doorbell interrupt            */
>      case POWERPC_EXCP_HV_EMU:
>          srr0 = SPR_HSRR0;
>          srr1 = SPR_HSRR1;
> @@ -846,6 +847,11 @@ static void ppc_hw_interrupt(CPUPPCState *env)
>              powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);
>              return;
>          }
> +        if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) {
> +            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL);
> +            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR_HV);
> +            return;
> +        }
>          if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
>              env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
>              powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PERFM);
> @@ -1088,8 +1094,8 @@ void helper_rfsvc(CPUPPCState *env)
>      do_rfi(env, env->lr, env->ctr & 0x0000FFFF);
>  }
>  
> -/* Embedded.Processor Control */
> -static int dbell2irq(target_ulong rb)
> +/* Server and Embedded Processor Control */
> +static int dbell2irq(target_ulong rb, bool book3s)
>  {
>      int msg = rb & DBELL_TYPE_MASK;
>      int irq = -1;
> @@ -1109,12 +1115,21 @@ static int dbell2irq(target_ulong rb)
>          break;
>      }
>  
> +    /* A Directed Hypervisor Doorbell message is sent only if the
> +     * message type is 5. All other types are reserved and the
> +     * instruction is a no-op */

I don't see that the logic here accomplishes that.  Other types will
return the same value as for embedded - that doesn't seem like it will
result in a no-op.

> +    if (book3s && msg == DBELL_TYPE_DBELL_SERVER) {
> +        irq = PPC_INTERRUPT_HDOORBELL;
> +    }
> +
>      return irq;
>  }
>  
>  void helper_msgclr(CPUPPCState *env, target_ulong rb)
>  {
> -    int irq = dbell2irq(rb);
> +    /* 64-bit server processors compliant with arch 2.x */
> +    bool book3s = (env->insns_flags & PPC_SEGMENT_64B);

Keying off an otherwise unrelated instruction bit seems bogus to me.

> +    int irq = dbell2irq(rb, book3s);
>  
>      if (irq < 0) {
>          return;
> @@ -1123,10 +1138,11 @@ void helper_msgclr(CPUPPCState *env, target_ulong rb)
>      env->pending_interrupts &= ~(1 << irq);
>  }
>  
> -void helper_msgsnd(target_ulong rb)
> +void helper_msgsnd(CPUPPCState *env, target_ulong rb)
>  {
> -    int irq = dbell2irq(rb);
> -    int pir = rb & DBELL_PIRTAG_MASK;
> +    /* 64-bit server processors compliant with arch 2.x */
> +    bool book3s = (env->insns_flags & PPC_SEGMENT_64B);
> +    int irq = dbell2irq(rb, book3s);
>      CPUState *cs;
>  
>      if (irq < 0) {
> @@ -1137,8 +1153,17 @@ void helper_msgsnd(target_ulong rb)
>      CPU_FOREACH(cs) {
>          PowerPCCPU *cpu = POWERPC_CPU(cs);
>          CPUPPCState *cenv = &cpu->env;
> +        bool send;
>  
> -        if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
> +        /* TODO: broadcast message to all threads of the same  processor */
> +        if (book3s) {
> +            int pir = rb & DBELL_PROCIDTAG_MASK;
> +            send = (cenv->spr_cb[SPR_PIR].default_value == pir);
> +        } else {
> +            int pir = rb & DBELL_PROCIDTAG_MASK;
> +            send = (rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir);
> +        }
> +        if (send) {
>              cenv->pending_interrupts |= 1 << irq;
>              cpu_interrupt(cs, CPU_INTERRUPT_HARD);
>          }

TBH, these functions are small enough and the booke vs. books
differences large enough that I think you'd be better off just having
separate implementations for the booke and books variants.  Those in
turn would have separate instruction bits.

> diff --git a/target/ppc/helper.h b/target/ppc/helper.h
> index bb6a94a8b390..3e98bd9eecb8 100644
> --- a/target/ppc/helper.h
> +++ b/target/ppc/helper.h
> @@ -677,7 +677,7 @@ DEF_HELPER_FLAGS_2(load_sr, TCG_CALL_NO_RWG, tl, env, tl)
>  DEF_HELPER_FLAGS_3(store_sr, TCG_CALL_NO_RWG, void, env, tl, tl)
>  
>  DEF_HELPER_FLAGS_1(602_mfrom, TCG_CALL_NO_RWG_SE, tl, tl)
> -DEF_HELPER_1(msgsnd, void, tl)
> +DEF_HELPER_2(msgsnd, void, env, tl)
>  DEF_HELPER_2(msgclr, void, env, tl)
>  #endif
>  
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index bcd36d53537f..1ad7e0fd4efd 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -6180,10 +6180,19 @@ static void gen_msgsnd(DisasContext *ctx)
>      GEN_PRIV;
>  #else
>      CHK_HV;
> -    gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
> +    gen_helper_msgsnd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
>  #endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
> +static void gen_msgsync(DisasContext *ctx)
> +{
> +#if defined(CONFIG_USER_ONLY)
> +    GEN_PRIV;
> +#else
> +    CHK_HV;
> +#endif /* defined(CONFIG_USER_ONLY) */
> +    /* interpreted as no-op */
> +}
>  
>  #if defined(TARGET_PPC64)
>  static void gen_maddld(DisasContext *ctx)
> @@ -6664,6 +6673,8 @@ GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001,
>                 PPC_NONE, PPC2_PRCNTL),
>  GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001,
>                 PPC_NONE, PPC2_PRCNTL),
> +GEN_HANDLER2_E(msgsync, "msgsync", 0x1F, 0x16, 0x1B, 0x00000000,
> +               PPC_NONE, PPC2_PRCNTL),
>  GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
>  GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
>  GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index 70ff15a51a6b..55c99c97e377 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -8866,7 +8866,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
>                          PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
>                          PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
>                          PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
> -                        PPC2_TM | PPC2_PM_ISA206 | PPC2_ISA300;
> +                        PPC2_TM | PPC2_PM_ISA206 | PPC2_ISA300 | PPC2_PRCNTL;
>      pcc->msr_mask = (1ull << MSR_SF) |
>                      (1ull << MSR_TM) |
>                      (1ull << MSR_VR) |

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  parent reply	other threads:[~2018-01-18  4:15 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-16  7:41 [Qemu-devel] [PATCH 0/3] target/ppc: add support for hypervisor doorbells Cédric Le Goater
2018-01-16  7:41 ` [Qemu-devel] [PATCH 1/3] target/ppc: fix doorbell and hypervisor doorbell definitions Cédric Le Goater
2018-01-16  7:41 ` [Qemu-devel] [PATCH 2/3] target/ppc: msgsnd and msgclr instructions need hypervisor privilege Cédric Le Goater
2018-01-16  7:41 ` [Qemu-devel] [PATCH 3/3] target/ppc: add support for hypervisor doorbells on book3s CPUs Cédric Le Goater
2018-01-16  7:45   ` Cédric Le Goater
2018-01-18  4:15   ` David Gibson [this message]
2018-01-18  8:13     ` Cédric Le Goater
2018-01-17  3:26 ` [Qemu-devel] [PATCH 0/3] target/ppc: add support for hypervisor doorbells David Gibson

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=20180118041507.GF30352@umbus.fritz.box \
    --to=david@gibson.dropbear.id.au \
    --cc=benh@kernel.crashing.org \
    --cc=clg@kaod.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.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).