All of lore.kernel.org
 help / color / mirror / Atom feed
From: Blue Swirl <blauwirbel@gmail.com>
To: Stu Grossman <stu.grossman@gmail.com>
Cc: Qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] PowerPC code generation and the program counter
Date: Tue, 14 Sep 2010 16:10:27 +0000	[thread overview]
Message-ID: <AANLkTi=e8gjvzNQvkMGULq1Hx3Tq_NChdP5V30SOvogL@mail.gmail.com> (raw)
In-Reply-To: <AANLkTi=JANf-9_bGExXhSJ6DBdhdP7pcTQR0ObspMvxw@mail.gmail.com>

On Mon, Sep 13, 2010 at 4:51 AM, Stu Grossman <stu.grossman@gmail.com> wrote:
> I've been using qemu-12.4 to trace accesses to non-existent addresses, but I've
> found that the PC is incorrect when cpu_abort() is called from within the
> unassigned memory helper routines (unassigned_mem_read[bwl] and
> unassigned_mem_write[bwl]).  Even nearby instructions (plus or minus 10
> instructions or so) don't match the type of load or store being done, so this
> isn't a PC being current_instr+4 kind of thing.

If PC is not updated to match the value at the access instruction, it
will point to the last instruction that did update PC, or start of the
translation block (TB).

> I ended up modifying the GEN_LD* and GEN_ST* macros (in target-ppc/translate.c)
> to call gen_update_nip(ctx, ctx->nip - 4).  This fixed the above problem, which
> has helped enormously.
>
> Since I'm not a qemu expert, I was wondering about several things:
>
>        1) Was it really necessary to add gen_update_nip to the load and store
>           instructions in order to get the correct PC?  Could the correct PC
>           have been derived some other way, without a runtime cost for all
>           basic loads and stores?

This is the way used by Sparc. There save_state() updates PC, NPC and
forces lazy flag calculation.

It may be possible to avoid updating the state, if TB generation was
limited to allow only one instruction which can update the state per
TB. But shorter TBs will also decrease performance, so the trade-off
should be evaluated.

>        2) As the current code lacks that fix, the basic load and store
>           instructions will save an incorrect PC if an exception occurs.  If
>           so, how come nobody noticed this before?  I think that exceptions
>           would have srr0 pointing at the last instruction which called
>           gen_update_nip.  So when the target returns from a data exception,
>           it might re-execute some instructions.  Possibly harmless, but could
>           lead to subtle bugs...

Yes. Also, page fault handlers are not interested in the exact
location, only the page. Because we ensure that TBs will never cross
page boundaries, the page will be correct.

>
>        Thanks, Stu
>
> Here's the patch if anybody is interested:

Please resubmit with git send-email, with Signed-off-by line and a
short description. I think it should be applied.

>
> *** translate.c~        Sat Sep 11 23:43:25 2010
> --- translate.c Sun Sep 12 20:49:53 2010
> ***************
> *** 2549,2554 ****
> --- 2549,2555 ----
>  {
>         \
>      TCGv EA;
>         \
>      gen_set_access_type(ctx, ACCESS_INT);
>         \
> +     gen_update_nip(ctx, ctx->nip - 4);
>               \
>      EA = tcg_temp_new();
>         \
>      gen_addr_imm_index(ctx, EA, 0);
>         \
>      gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);
>         \
> ***************
> *** 2564,2569 ****
> --- 2565,2571 ----
>          gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>         \
>          return;
>         \
>      }
>         \
> +     gen_update_nip(ctx, ctx->nip - 4);
>               \
>      gen_set_access_type(ctx, ACCESS_INT);
>         \
>      EA = tcg_temp_new();
>         \
>      if (type == PPC_64B)
>         \
> ***************
> *** 2584,2589 ****
> --- 2586,2592 ----
>          gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>         \
>          return;
>         \
>      }
>         \
> +     gen_update_nip(ctx, ctx->nip - 4);
>               \
>      gen_set_access_type(ctx, ACCESS_INT);
>         \
>      EA = tcg_temp_new();
>         \
>      gen_addr_reg_index(ctx, EA);
>         \
> ***************
> *** 2596,2601 ****
> --- 2599,2605 ----
>  static void glue(gen_, name##x)(DisasContext *ctx)
>         \
>  {
>         \
>      TCGv EA;
>         \
> +     gen_update_nip(ctx, ctx->nip - 4);
>               \
>      gen_set_access_type(ctx, ACCESS_INT);
>         \
>      EA = tcg_temp_new();
>         \
>      gen_addr_reg_index(ctx, EA);
>         \
> ***************
> *** 2693,2698 ****
> --- 2697,2703 ----
>  static void glue(gen_, name)(DisasContext *ctx)
>                 \
>  {
>         \
>      TCGv EA;
>         \
> +     gen_update_nip(ctx, ctx->nip - 4);
>               \
>      gen_set_access_type(ctx, ACCESS_INT);
>         \
>      EA = tcg_temp_new();
>         \
>      gen_addr_imm_index(ctx, EA, 0);
>         \
> ***************
> *** 2708,2713 ****
> --- 2713,2719 ----
>          gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>         \
>          return;
>         \
>      }
>         \
> +     gen_update_nip(ctx, ctx->nip - 4);
>               \
>      gen_set_access_type(ctx, ACCESS_INT);
>         \
>      EA = tcg_temp_new();
>         \
>      if (type == PPC_64B)
>         \
> ***************
> *** 2727,2732 ****
> --- 2733,2739 ----
>          gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>         \
>          return;
>         \
>      }
>         \
> +     gen_update_nip(ctx, ctx->nip - 4);
>               \
>      gen_set_access_type(ctx, ACCESS_INT);
>         \
>      EA = tcg_temp_new();
>         \
>      gen_addr_reg_index(ctx, EA);
>         \
> ***************
> *** 2739,2744 ****
> --- 2746,2752 ----
>  static void glue(gen_, name##x)(DisasContext *ctx)
>                 \
>  {
>         \
>      TCGv EA;
>         \
> +     gen_update_nip(ctx, ctx->nip - 4);
>               \
>      gen_set_access_type(ctx, ACCESS_INT);
>         \
>      EA = tcg_temp_new();
>         \
>      gen_addr_reg_index(ctx, EA);
>         \
>
>

  parent reply	other threads:[~2010-09-14 16:11 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-13  4:51 [Qemu-devel] PowerPC code generation and the program counter Stu Grossman
2010-09-13  7:53 ` Alexander Graf
2010-09-14 16:10 ` Blue Swirl [this message]
2010-09-14 17:05   ` Edgar E. Iglesias
2010-09-14 17:48     ` Blue Swirl
2010-09-14 19:33       ` Edgar E. Iglesias

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='AANLkTi=e8gjvzNQvkMGULq1Hx3Tq_NChdP5V30SOvogL@mail.gmail.com' \
    --to=blauwirbel@gmail.com \
    --cc=Qemu-devel@nongnu.org \
    --cc=stu.grossman@gmail.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.