Skip to contentSkip to conversation

M68k ColdFire ptrace/cache fix

DISCUSSION Michael Eager 3 participants 4 messages Jul 13, 2012 – Jul 16, 2012 2 messages not in the archive

Subsystems (2)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

A message that is not in the archive (sent off-list or not yet received): CAMuHMdUgZBgKSZK1YJnvqvcF1M82Q6mHL41K-6hdvhM69JCB+w@mail.gmail.com

#2 lore raw
Quoted 17 lines · Geert Uytterhoeven

Hi Michael,

Quoted 14 lines · Michael Eager

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
Quoted 8 lines
Quoted 6 lines

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.

Quoted 3 lines

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.

Quoted 2 lines

If yes, feel free to take this to [email protected].

Done.

Signature · 2 lines
Michael Eager	 [email protected]
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;
}

arch/m68k/kernel/ptrace.c renamed from arch/m68k/kernel/ptrace.c-orig +5 -0
@@ -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 */
#3 lore raw

Hi Michael,

Quoted 27 lines · Michael Eager
Quoted 15 lines · Geert Uytterhoeven
Quoted 14 lines · Michael Eager

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
Quoted 8 lines
Quoted 6 lines

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.

Quoted 8 lines
Quoted 3 lines

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.

Yeah, even 2.6.29 just called the generic version from the m68k-specific code, which moved a layer up in more recent kernels (commit faa47b466935e73251b18b17d51455b06ed65764 ("m68k: use generic code for ptrace requests") by Andreas).

Anyway, I'd expect the generic code to issue a cache flush/invalidate somewhere around the road, else it would fail for many more platforms.
So far I couldn't reproduce this (on 3.0 and 3.5-rc6) on 68040 (both ARAnyM and real hardware). Hence I'm more inclined to believe this is an issue in the Coldfire-specific code, cfr. the recent cache issues Greg discovered
(http://www.mail-archive.com/[email protected]/msg04929.html).

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#4 lore raw
Quoted 39 lines · Geert Uytterhoeven

Hi Michael,

Quoted 27 lines · Michael Eager
Quoted 15 lines · Geert Uytterhoeven
Quoted 14 lines · Michael Eager

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
Quoted 8 lines
Quoted 6 lines

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.

Quoted 8 lines
Quoted 3 lines

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.

Quoted 7 lines

Yeah, even 2.6.29 just called the generic version from the m68k-specific code, which moved a layer up in more recent kernels (commit faa47b466935e73251b18b17d51455b06ed65764 ("m68k: use generic code for ptrace requests") by Andreas).

Anyway, I'd expect the generic code to issue a cache flush/invalidate somewhere around the road, else it would fail for many more platforms.

I'd assume the same, but I couldn't find where this is happening.

Quoted 4 lines

So far I couldn't reproduce this (on 3.0 and 3.5-rc6) on 68040 (both ARAnyM and real hardware). Hence I'm more inclined to believe this is an issue in the Coldfire-specific code, cfr. the recent cache issues Greg discovered
(http://www.mail-archive.com/[email protected]/msg04929.html).

I'll see if this patch also fixes the problem.

Signature · 2 lines
Michael Eager	 [email protected]
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077
#5 lore raw

Hi Michael,

Quoted 29 lines · Michael Eager
Quoted 28 lines · Geert Uytterhoeven
Quoted 27 lines · Michael Eager
Quoted 15 lines · Geert Uytterhoeven
Quoted 14 lines · Michael Eager

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
Quoted 8 lines
Quoted 6 lines

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.

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 3 lines

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.

It can't be a stock 2.6.29 kernel. There is no ColdFire code in arch/m68k/ in 2.6.29. My best guess is that you are using a kernel supplied by Freescale with MMU ColdFire support.

Quoted 8 lines
Quoted 7 lines

Yeah, even 2.6.29 just called the generic version from the m68k-specific code, which moved a layer up in more recent kernels (commit faa47b466935e73251b18b17d51455b06ed65764 ("m68k: use generic code for ptrace requests") by Andreas).

Anyway, I'd expect the generic code to issue a cache flush/invalidate somewhere around the road, else it would fail for many more platforms.

Quoted 8 lines

I'd assume the same, but I couldn't find where this is happening.

Quoted 4 lines

So far I couldn't reproduce this (on 3.0 and 3.5-rc6) on 68040 (both ARAnyM and real hardware). Hence I'm more inclined to believe this is an issue in the Coldfire-specific code, cfr. the recent cache issues Greg discovered
(http://www.mail-archive.com/[email protected]/msg04929.html).

I'll see if this patch also fixes the problem.

I can't try this myself at the moment on 3.5-rc7 with the cache patch. My gdb and gdbserver seem to be version mis-matched.

Regards
Greg

------------------------------------------------------------------------

Greg Ungerer  --  Principal Engineer        EMAIL:     [email protected]
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close                             FAX:         +61 7 3217 5323
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com