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 */