Re: M68k ColdFire ptrace/cache fix

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 07/13/2012 01:06 PM, Geert Uytterhoeven wrote:
Hi Michael,

On Fri, Jul 13, 2012 at 9:14 PM, Michael Eager <eager@xxxxxxxxxxxx> wrote:
I've tracked down a problem in gdb/gdbserver to ptrace() not
clearing the i/d cache after modifying memory.

To reproduce:
   m68k-gcc -g -o cf-gdb-test-no-io cf-gdb-test-no-io.c
   scp cf-gdb-test-no-io <target>:/
   on target:   gdbserver :1234 cf-gdb-test-no-io
   m68k-gcc cf-gdb-test-no-io
   (gdb) b 8
   (gdb) b 10
   (gdb) tar rem <target>:1234
   (gdb) c
   (gdb) c

Program will hit first breakpoint, but not second breakpoint.

It appears that the instruction at the last breakpoint location
is in the icache and does not get flushed when the bp is written.

After applying the attached patch, gdb/gdbserver behavior is correct.

Thanks for your report and patch!

I attached the test program, which I previously forgot.

Does this happen only in 2.6.29, or also in current kernels?
The first hunk of your patch no longer applies, as the affected code is
gone and those cases are now handled purely by the generic code.

I'm working with a client's environment using 2.6.29, so I can't verify
that the same failure occurs in recent kernels.  But I don't see anything
in ptrace.c in the latest kernel which would clear the i/d caches when
writing to memory.


If yes, feel free to take this to linux-m68k@xxxxxxxxxxxxxxxxxxxx.

Done.


--
Michael Eager	 eager@xxxxxxxxxxxx
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077


int work (int a)
{
  return a * 2;
}

int main (void)
{
  int a = 10;
  int b = work (a);
  b = work (b);

  a = b * a;

  return 0;
}
--- linux-2.6.29/arch/m68k/kernel/ptrace.c-orig	2012-06-30 06:37:34.000000000 -0700
+++ linux-2.6.29/arch/m68k/kernel/ptrace.c	2012-07-13 11:25:24.000000000 -0700
@@ -24,6 +24,7 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/processor.h>
+#include <asm/cacheflush_mm.h>
 
 /*
  * does not yet catch signals sent when the child dies.
@@ -157,6 +158,8 @@ long arch_ptrace(struct task_struct *chi
 	case PTRACE_POKETEXT:	/* write the word at location addr. */
 	case PTRACE_POKEDATA:
 		ret = generic_ptrace_pokedata(child, addr, data);
+		flush_dcache ();
+		flush_icache ();
 		break;
 
 	case PTRACE_POKEUSR:	/* write the word at location addr in the USER area */
@@ -183,6 +186,8 @@ long arch_ptrace(struct task_struct *chi
 			child->thread.fp[addr - 21] = data;
 		} else
 			goto out_eio;
+		flush_dcache ();
+		flush_icache ();
 		break;
 
 	case PTRACE_SYSCALL:	/* continue and stop at next (return from) syscall */

[Index of Archives]     [Video for Linux]     [Yosemite News]     [Linux S/390]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux