All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] PowerPC code generation and the program counter
@ 2010-09-13  4:51 Stu Grossman
  2010-09-13  7:53 ` Alexander Graf
  2010-09-14 16:10 ` Blue Swirl
  0 siblings, 2 replies; 6+ messages in thread
From: Stu Grossman @ 2010-09-13  4:51 UTC (permalink / raw)
  To: Qemu-devel

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.

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?
	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...

	Thanks, Stu

Here's the patch if anybody is interested:

*** 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);
         \

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] PowerPC code generation and the program counter
  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
  1 sibling, 0 replies; 6+ messages in thread
From: Alexander Graf @ 2010-09-13  7:53 UTC (permalink / raw)
  To: Stu Grossman; +Cc: Qemu-devel


On 13.09.2010, at 06:51, Stu Grossman 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.
> 
> 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?
> 	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...

Usually on a page fault, there is some tcg magic involved that tries to figure out which instruction inside the TB is responsible for the fault and sets pc accordingly.
Maybe that code path only gets involved when we generate a real page fault, so in your case you'd have to call the same on unassigned address accesses.


Alex

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] PowerPC code generation and the program counter
  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
  2010-09-14 17:05   ` Edgar E. Iglesias
  1 sibling, 1 reply; 6+ messages in thread
From: Blue Swirl @ 2010-09-14 16:10 UTC (permalink / raw)
  To: Stu Grossman; +Cc: Qemu-devel

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);
>         \
>
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] PowerPC code generation and the program counter
  2010-09-14 16:10 ` Blue Swirl
@ 2010-09-14 17:05   ` Edgar E. Iglesias
  2010-09-14 17:48     ` Blue Swirl
  0 siblings, 1 reply; 6+ messages in thread
From: Edgar E. Iglesias @ 2010-09-14 17:05 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Stu Grossman, Qemu-devel

On Tue, Sep 14, 2010 at 04:10:27PM +0000, Blue Swirl wrote:
> 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.

Hi!

There might be reasons you might need that logic in SPARC, but in general
I dont think the PC needs to be up to date at generated load/stores for
qemu to cope with MMU exceptions.


> 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.


I'm not sure I follow you here, but in general, MMU exception handlers
need to know the exact address of the instruction that caused the exception.


> >
> >        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.


I don't think the patch is needed.

IIUC:
When a load/store in QEMU causes a memory abort, QEMU will retranslate the
current TB in a "search" mode that creates side tables that make it possible
to map host PC to guest PC and restore the state. See translate-all.c:
cpu_restore_state().

For cases when that logic is not applied, the translator needs to generate
code to put the required state up to date. For example for exceptions that
the translator itself generates.

Accesses to unmapped addresses might be a case that is not handled today.
IMO, we should treat it similary to a memory abort and cpu_restore_state()
in the unmapped access exception code path.

Cheers

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] PowerPC code generation and the program counter
  2010-09-14 17:05   ` Edgar E. Iglesias
@ 2010-09-14 17:48     ` Blue Swirl
  2010-09-14 19:33       ` Edgar E. Iglesias
  0 siblings, 1 reply; 6+ messages in thread
From: Blue Swirl @ 2010-09-14 17:48 UTC (permalink / raw)
  To: Edgar E. Iglesias; +Cc: Stu Grossman, Qemu-devel

On Tue, Sep 14, 2010 at 5:05 PM, Edgar E. Iglesias
<edgar.iglesias@gmail.com> wrote:
> On Tue, Sep 14, 2010 at 04:10:27PM +0000, Blue Swirl wrote:
>> 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.
>
> Hi!
>
> There might be reasons you might need that logic in SPARC, but in general
> I dont think the PC needs to be up to date at generated load/stores for
> qemu to cope with MMU exceptions.

Maybe the reason is NPC and the flags, or unassigned access problem.

>> 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.
>
>
> I'm not sure I follow you here, but in general, MMU exception handlers
> need to know the exact address of the instruction that caused the exception.

Right, I was in a severe state of confusion.

>> >
>> >        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.
>
>
> I don't think the patch is needed.
>
> IIUC:
> When a load/store in QEMU causes a memory abort, QEMU will retranslate the
> current TB in a "search" mode that creates side tables that make it possible
> to map host PC to guest PC and restore the state. See translate-all.c:
> cpu_restore_state().
>
> For cases when that logic is not applied, the translator needs to generate
> code to put the required state up to date. For example for exceptions that
> the translator itself generates.
>
> Accesses to unmapped addresses might be a case that is not handled today.
> IMO, we should treat it similary to a memory abort and cpu_restore_state()
> in the unmapped access exception code path.

If this indeed is the case, maybe the fix will be generic and also
Sparc won't need to save state.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] PowerPC code generation and the program counter
  2010-09-14 17:48     ` Blue Swirl
@ 2010-09-14 19:33       ` Edgar E. Iglesias
  0 siblings, 0 replies; 6+ messages in thread
From: Edgar E. Iglesias @ 2010-09-14 19:33 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Stu Grossman, Qemu-devel

On Tue, Sep 14, 2010 at 05:48:30PM +0000, Blue Swirl wrote:
> On Tue, Sep 14, 2010 at 5:05 PM, Edgar E. Iglesias
> <edgar.iglesias@gmail.com> wrote:
> > On Tue, Sep 14, 2010 at 04:10:27PM +0000, Blue Swirl wrote:
> >> 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.
> >
> > Hi!
> >
> > There might be reasons you might need that logic in SPARC, but in general
> > I dont think the PC needs to be up to date at generated load/stores for
> > qemu to cope with MMU exceptions.
> 
> Maybe the reason is NPC and the flags, or unassigned access problem.

The lazy condition-code flags evaluation is a bit problematic at load/stores.

For CRIS (which implements the lazy CC flag optimization) I avoided
evaluating the flags at every load/store by instead putting the evaluation
in the slow path (target-cris/op_helper.c:tlb_fill()). The generated code
now only has to make sure that the condition-code bookkeeping is up to date
(i.e cc_op, operands etc).

It's a bit of a hack and I'm not 100% sure it's the right thing to do,
but it seems to be working fine :)


> >> 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.
> >
> >
> > I'm not sure I follow you here, but in general, MMU exception handlers
> > need to know the exact address of the instruction that caused the exception.
> 
> Right, I was in a severe state of confusion.

:)

Cheers

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-09-14 19:33 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
2010-09-14 17:05   ` Edgar E. Iglesias
2010-09-14 17:48     ` Blue Swirl
2010-09-14 19:33       ` Edgar E. Iglesias

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.