qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: Richard Henderson <rth@twiddle.net>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v3 34/34] target-alpha: Emulate LL/SC using cmpxchg helpers
Date: Thu, 15 Sep 2016 15:38:08 +0100	[thread overview]
Message-ID: <87bmzpi5yn.fsf@linaro.org> (raw)
In-Reply-To: <1472935202-3342-35-git-send-email-rth@twiddle.net>


Richard Henderson <rth@twiddle.net> writes:

> Emulating LL/SC with cmpxchg is not correct, since it can
> suffer from the ABA problem.  However, portable parallel
> code is writting assuming only cmpxchg which means that in
> practice this is a viable alternative.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>  linux-user/main.c        |  49 ----------------------
>  target-alpha/cpu.h       |   4 --
>  target-alpha/helper.c    |   6 ---
>  target-alpha/machine.c   |   2 -
>  target-alpha/translate.c | 104 ++++++++++++++++++++---------------------------
>  5 files changed, 45 insertions(+), 120 deletions(-)
>
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 64838bf..6cdd0da 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -2994,51 +2994,6 @@ void cpu_loop(CPUM68KState *env)
>  #endif /* TARGET_M68K */
>
>  #ifdef TARGET_ALPHA
> -static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
> -{
> -    target_ulong addr, val, tmp;
> -    target_siginfo_t info;
> -    int ret = 0;
> -
> -    addr = env->lock_addr;
> -    tmp = env->lock_st_addr;
> -    env->lock_addr = -1;
> -    env->lock_st_addr = 0;
> -
> -    start_exclusive();
> -    mmap_lock();
> -
> -    if (addr == tmp) {
> -        if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
> -            goto do_sigsegv;
> -        }
> -
> -        if (val == env->lock_value) {
> -            tmp = env->ir[reg];
> -            if (quad ? put_user_u64(tmp, addr) : put_user_u32(tmp, addr)) {
> -                goto do_sigsegv;
> -            }
> -            ret = 1;
> -        }
> -    }
> -    env->ir[reg] = ret;
> -    env->pc += 4;
> -
> -    mmap_unlock();
> -    end_exclusive();
> -    return;
> -
> - do_sigsegv:
> -    mmap_unlock();
> -    end_exclusive();
> -
> -    info.si_signo = TARGET_SIGSEGV;
> -    info.si_errno = 0;
> -    info.si_code = TARGET_SEGV_MAPERR;
> -    info._sifields._sigfault._addr = addr;
> -    queue_signal(env, TARGET_SIGSEGV, &info);
> -}
> -
>  void cpu_loop(CPUAlphaState *env)
>  {
>      CPUState *cs = CPU(alpha_env_get_cpu(env));
> @@ -3212,10 +3167,6 @@ void cpu_loop(CPUAlphaState *env)
>                  queue_signal(env, info.si_signo, &info);
>              }
>              break;
> -        case EXCP_STL_C:
> -        case EXCP_STQ_C:
> -            do_store_exclusive(env, env->error_code, trapnr - EXCP_STL_C);
> -            break;
>          case EXCP_INTERRUPT:
>              /* Just indicate that signals should be handled asap.  */
>              break;
> diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
> index 9d9489c..a4068c8 100644
> --- a/target-alpha/cpu.h
> +++ b/target-alpha/cpu.h
> @@ -230,7 +230,6 @@ struct CPUAlphaState {
>      uint64_t pc;
>      uint64_t unique;
>      uint64_t lock_addr;
> -    uint64_t lock_st_addr;
>      uint64_t lock_value;
>
>      /* The FPCR, and disassembled portions thereof.  */
> @@ -346,9 +345,6 @@ enum {
>      EXCP_ARITH,
>      EXCP_FEN,
>      EXCP_CALL_PAL,
> -    /* For Usermode emulation.  */
> -    EXCP_STL_C,
> -    EXCP_STQ_C,
>  };
>
>  /* Alpha-specific interrupt pending bits.  */
> diff --git a/target-alpha/helper.c b/target-alpha/helper.c
> index 1ed0725..95453f5 100644
> --- a/target-alpha/helper.c
> +++ b/target-alpha/helper.c
> @@ -306,12 +306,6 @@ void alpha_cpu_do_interrupt(CPUState *cs)
>          case EXCP_CALL_PAL:
>              name = "call_pal";
>              break;
> -        case EXCP_STL_C:
> -            name = "stl_c";
> -            break;
> -        case EXCP_STQ_C:
> -            name = "stq_c";
> -            break;
>          }
>          qemu_log("INT %6d: %s(%#x) pc=%016" PRIx64 " sp=%016" PRIx64 "\n",
>                   ++count, name, env->error_code, env->pc, env->ir[IR_SP]);
> diff --git a/target-alpha/machine.c b/target-alpha/machine.c
> index 710b783..b99a123 100644
> --- a/target-alpha/machine.c
> +++ b/target-alpha/machine.c
> @@ -45,8 +45,6 @@ static VMStateField vmstate_env_fields[] = {
>      VMSTATE_UINTTL(unique, CPUAlphaState),
>      VMSTATE_UINTTL(lock_addr, CPUAlphaState),
>      VMSTATE_UINTTL(lock_value, CPUAlphaState),
> -    /* Note that lock_st_addr is not saved; it is a temporary
> -       used during the execution of the st[lq]_c insns.  */
>
>      VMSTATE_UINT8(ps, CPUAlphaState),
>      VMSTATE_UINT8(intr_flag, CPUAlphaState),
> diff --git a/target-alpha/translate.c b/target-alpha/translate.c
> index 2941159..ed353de 100644
> --- a/target-alpha/translate.c
> +++ b/target-alpha/translate.c
> @@ -99,7 +99,6 @@ static TCGv cpu_std_ir[31];
>  static TCGv cpu_fir[31];
>  static TCGv cpu_pc;
>  static TCGv cpu_lock_addr;
> -static TCGv cpu_lock_st_addr;
>  static TCGv cpu_lock_value;
>
>  #ifndef CONFIG_USER_ONLY
> @@ -116,7 +115,6 @@ void alpha_translate_init(void)
>      static const GlobalVar vars[] = {
>          DEF_VAR(pc),
>          DEF_VAR(lock_addr),
> -        DEF_VAR(lock_st_addr),
>          DEF_VAR(lock_value),
>      };
>
> @@ -198,6 +196,23 @@ static TCGv dest_sink(DisasContext *ctx)
>      return ctx->sink;
>  }
>
> +static void free_context_temps(DisasContext *ctx)
> +{
> +    if (!TCGV_IS_UNUSED_I64(ctx->sink)) {
> +        tcg_gen_discard_i64(ctx->sink);
> +        tcg_temp_free(ctx->sink);
> +        TCGV_UNUSED_I64(ctx->sink);
> +    }
> +    if (!TCGV_IS_UNUSED_I64(ctx->zero)) {
> +        tcg_temp_free(ctx->zero);
> +        TCGV_UNUSED_I64(ctx->zero);
> +    }
> +    if (!TCGV_IS_UNUSED_I64(ctx->lit)) {
> +        tcg_temp_free(ctx->lit);
> +        TCGV_UNUSED_I64(ctx->lit);
> +    }
> +}
> +
>  static TCGv load_gpr(DisasContext *ctx, unsigned reg)
>  {
>      if (likely(reg < 31)) {
> @@ -395,56 +410,37 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
>                                          int32_t disp16, int mem_idx,
>                                          TCGMemOp op)
>  {
> -    TCGv addr;
> -
> -    if (ra == 31) {
> -        /* ??? Don't bother storing anything.  The user can't tell
> -           the difference, since the zero register always reads zero.  */
> -        return NO_EXIT;
> -    }
> -
> -#if defined(CONFIG_USER_ONLY)
> -    addr = cpu_lock_st_addr;
> -#else
> -    addr = tcg_temp_local_new();
> -#endif
> +    TCGLabel *lab_fail, *lab_done;
> +    TCGv addr, val;
>
> +    addr = tcg_temp_new_i64();
>      tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
> +    free_context_temps(ctx);
>
> -#if defined(CONFIG_USER_ONLY)
> -    /* ??? This is handled via a complicated version of compare-and-swap
> -       in the cpu_loop.  Hopefully one day we'll have a real CAS opcode
> -       in TCG so that this isn't necessary.  */
> -    return gen_excp(ctx, (op & MO_SIZE) == MO_64 ? EXCP_STQ_C : EXCP_STL_C, ra);
> -#else
> -    /* ??? In system mode we are never multi-threaded, so CAS can be
> -       implemented via a non-atomic load-compare-store sequence.  */
> -    {
> -        TCGLabel *lab_fail, *lab_done;
> -        TCGv val;
> +    lab_fail = gen_new_label();
> +    lab_done = gen_new_label();
> +    tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
> +    tcg_temp_free_i64(addr);
>
> -        lab_fail = gen_new_label();
> -        lab_done = gen_new_label();
> -        tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
> +    val = tcg_temp_new_i64();
> +    tcg_gen_atomic_cmpxchg_i64(val, cpu_lock_addr, cpu_lock_value,
> +                               load_gpr(ctx, ra), mem_idx, op);
> +    free_context_temps(ctx);

I don't quite follow what free_context_temps() is doing and why it needs
to be done twice during the building of this instructions TCGOps?

>
> -        val = tcg_temp_new();
> -        tcg_gen_qemu_ld_i64(val, addr, mem_idx, op);
> -        tcg_gen_brcond_i64(TCG_COND_NE, val, cpu_lock_value, lab_fail);
> -
> -        tcg_gen_qemu_st_i64(ctx->ir[ra], addr, mem_idx, op);
> -        tcg_gen_movi_i64(ctx->ir[ra], 1);
> -        tcg_gen_br(lab_done);
> +    if (ra != 31) {
> +        tcg_gen_setcond_i64(TCG_COND_EQ, ctx->ir[ra], val, cpu_lock_value);
> +    }
> +    tcg_temp_free_i64(val);
> +    tcg_gen_br(lab_done);
>
> -        gen_set_label(lab_fail);
> +    gen_set_label(lab_fail);
> +    if (ra != 31) {
>          tcg_gen_movi_i64(ctx->ir[ra], 0);
> -
> -        gen_set_label(lab_done);
> -        tcg_gen_movi_i64(cpu_lock_addr, -1);
> -
> -        tcg_temp_free(addr);
> -        return NO_EXIT;
>      }
> -#endif
> +
> +    gen_set_label(lab_done);
> +    tcg_gen_movi_i64(cpu_lock_addr, -1);
> +    return NO_EXIT;
>  }
>
>  static bool in_superpage(DisasContext *ctx, int64_t addr)
> @@ -2914,6 +2910,10 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
>      /* Similarly for flush-to-zero.  */
>      ctx.tb_ftz = -1;
>
> +    TCGV_UNUSED_I64(ctx.zero);
> +    TCGV_UNUSED_I64(ctx.sink);
> +    TCGV_UNUSED_I64(ctx.lit);
> +
>      num_insns = 0;
>      max_insns = tb->cflags & CF_COUNT_MASK;
>      if (max_insns == 0) {
> @@ -2948,23 +2948,9 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
>          }
>          insn = cpu_ldl_code(env, ctx.pc);
>
> -        TCGV_UNUSED_I64(ctx.zero);
> -        TCGV_UNUSED_I64(ctx.sink);
> -        TCGV_UNUSED_I64(ctx.lit);
> -
>          ctx.pc += 4;
>          ret = translate_one(ctxp, insn);
> -
> -        if (!TCGV_IS_UNUSED_I64(ctx.sink)) {
> -            tcg_gen_discard_i64(ctx.sink);
> -            tcg_temp_free(ctx.sink);
> -        }
> -        if (!TCGV_IS_UNUSED_I64(ctx.zero)) {
> -            tcg_temp_free(ctx.zero);
> -        }
> -        if (!TCGV_IS_UNUSED_I64(ctx.lit)) {
> -            tcg_temp_free(ctx.lit);
> -        }
> +        free_context_temps(ctxp);
>
>          /* If we reach a page boundary, are single stepping,
>             or exhaust instruction count, stop generation.  */


--
Alex Bennée

  reply	other threads:[~2016-09-15 14:39 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-03 20:39 [Qemu-devel] [PATCH v3 00/34] cmpxchg-based emulation of atomics Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 01/34] atomics: add atomic_xor Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 02/34] atomics: add atomic_op_fetch variants Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 03/34] exec: Avoid direct references to Int128 parts Richard Henderson
2016-09-09 17:14   ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 04/34] int128: Use __int128 if available Richard Henderson
2016-09-09 17:19   ` Alex Bennée
2016-09-09 17:38     ` Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 05/34] int128: Add int128_make128 Richard Henderson
2016-09-09 13:01   ` Leon Alrae
2016-09-09 20:16     ` Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 06/34] tcg: Add EXCP_ATOMIC Richard Henderson
2016-09-12 14:16   ` Alex Bennée
2016-09-12 20:19     ` Richard Henderson
2016-09-13  6:42       ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 07/34] HACK: Always enable parallel_cpus Richard Henderson
2016-09-12 14:20   ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 08/34] cputlb: Replace SHIFT with DATA_SIZE Richard Henderson
2016-09-12 14:22   ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 09/34] cputlb: Move probe_write out of softmmu_template.h Richard Henderson
2016-09-12 14:35   ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 10/34] cputlb: Remove includes from softmmu_template.h Richard Henderson
2016-09-12 14:38   ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 11/34] cputlb: Move most of iotlb code out of line Richard Henderson
2016-09-12 15:26   ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 12/34] cputlb: Tidy some macros Richard Henderson
2016-09-12 15:28   ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 13/34] tcg: Add atomic helpers Richard Henderson
2016-09-09 13:11   ` Leon Alrae
2016-09-09 14:46   ` Leon Alrae
2016-09-09 16:26     ` Richard Henderson
2016-09-12  7:59       ` Leon Alrae
2016-09-12 16:13         ` Richard Henderson
2016-09-13 12:32           ` Leon Alrae
2016-09-12 13:47   ` Alex Bennée
2016-09-13 18:00     ` Richard Henderson
2017-03-24 10:14       ` Nikunj A Dadhania
2017-03-24 10:58         ` Alex Bennée
2017-03-24 17:27           ` Nikunj A Dadhania
2017-03-27 11:56           ` Nikunj A Dadhania
2016-09-13 17:06   ` Alex Bennée
2016-09-13 17:26     ` Richard Henderson
2016-09-13 18:45       ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 14/34] tcg: Add atomic128 helpers Richard Henderson
2016-09-13 11:18   ` Alex Bennée
2016-09-13 14:18     ` Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 15/34] tcg: Add CONFIG_ATOMIC64 Richard Henderson
2016-09-14 10:12   ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 16/34] target-i386: emulate LOCK'ed cmpxchg using cmpxchg helpers Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 17/34] target-i386: emulate LOCK'ed OP instructions using atomic helpers Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 18/34] target-i386: emulate LOCK'ed INC using atomic helper Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 19/34] target-i386: emulate LOCK'ed NOT " Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 20/34] target-i386: emulate LOCK'ed NEG using cmpxchg helper Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 21/34] target-i386: emulate LOCK'ed XADD using atomic helper Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 22/34] target-i386: emulate LOCK'ed BTX ops using atomic helpers Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 23/34] target-i386: emulate XCHG using atomic helper Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 24/34] target-i386: remove helper_lock() Richard Henderson
2016-09-14 11:14   ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 25/34] tests: add atomic_add-bench Richard Henderson
2016-09-14 13:53   ` Alex Bennée
2016-09-15  2:23     ` Emilio G. Cota
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 26/34] target-arm: Rearrange aa32 load and store functions Richard Henderson
2016-09-14 15:58   ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 27/34] target-arm: emulate LL/SC using cmpxchg helpers Richard Henderson
2016-09-14 16:03   ` Alex Bennée
2016-09-14 16:38     ` Richard Henderson
2016-10-20 17:51       ` Pranith Kumar
2016-10-20 18:00         ` Richard Henderson
2016-10-20 18:58           ` Pranith Kumar
2016-10-20 19:02             ` Richard Henderson
2016-10-20 19:07               ` Pranith Kumar
2016-10-21  4:34                 ` Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 28/34] target-arm: emulate SWP with atomic_xchg helper Richard Henderson
2016-09-14 16:05   ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 29/34] target-arm: emulate aarch64's LL/SC using cmpxchg helpers Richard Henderson
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 30/34] linux-user: remove handling of ARM's EXCP_STREX Richard Henderson
2016-09-15  9:36   ` Alex Bennée
2016-09-03 20:39 ` [Qemu-devel] [PATCH v3 31/34] linux-user: remove handling of aarch64's EXCP_STREX Richard Henderson
2016-09-15  9:36   ` Alex Bennée
2016-09-03 20:40 ` [Qemu-devel] [PATCH v3 32/34] target-arm: remove EXCP_STREX + cpu_exclusive_{test, info} Richard Henderson
2016-09-15  9:39   ` Alex Bennée
2016-09-03 20:40 ` [Qemu-devel] [PATCH v3 33/34] target-alpha: Introduce MMU_PHYS_IDX Richard Henderson
2016-09-15 10:10   ` Alex Bennée
2016-09-15 16:38     ` Richard Henderson
2016-09-03 20:40 ` [Qemu-devel] [PATCH v3 34/34] target-alpha: Emulate LL/SC using cmpxchg helpers Richard Henderson
2016-09-15 14:38   ` Alex Bennée [this message]
2016-09-15 16:48     ` Richard Henderson
2016-09-15 17:48       ` Alex Bennée
2016-09-15 18:28         ` Richard Henderson
2016-09-03 21:25 ` [Qemu-devel] [PATCH v3 00/34] cmpxchg-based emulation of atomics no-reply
2016-09-03 21:26 ` no-reply
2016-09-09 18:33 ` Alex Bennée
2016-09-09 19:07   ` Richard Henderson
2016-09-09 19:29     ` Alex Bennée
2016-09-09 20:03       ` Richard Henderson
2016-09-09 20:11       ` Richard Henderson
2016-09-15 14:39 ` Alex Bennée

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=87bmzpi5yn.fsf@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /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).