Port-sgimips archive

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

Re: R4000 end-of-page bug



Stephen M. Rumble wrote:

>> Hmm... how was that solved under Linux?
> 
> I don't think it was. It seems like most of these early broken cpus  
> were limited to SGI systems, and Linux doesn't support them. I'd  
> actually be kind of surprised if your Indy had one. I've seen it only  
> on an Indigo.

Such R4000-Indys are probably rare, but mine has a 2.2 R4000.


> Looking at gcc quickly, it appears that mfix-r4000 handles erroneous  
> integer division results if they occur at the end of a page. Perhaps  
> that's what you're hitting. We probably should build with that option  
> anyway.

I have rebuilt the kernel with it, but it doesn't change much.


> The EOP bug is more nefarious and may be a security vulnerability. 
> Apparently when it is triggered, the jump target address is used as  
> the exception vector.

Oh, yes! That means without some hacks to the exception handler (wiring down
following pages) such an R4000 system will always be vulnerable? :|


BTW, I asked somebody who has more experience with gcc (Gunther Nikl) to do
the alignment-modification for us. And I'm currently testing the following
patch to src/gnu/dist/gcc4/gcc/config/mips/mips.c:

--- mips.c~ 2005-12-09 09:15:58.000000000 +0100
+++ mips.c  2009-03-06 20:39:58.000000000 +0100
@@ -5301,6 +5301,9 @@ print_operand (FILE *file, rtx op, int l
 
          if (set_nomacro++ == 0)
        fputs (".set\tnomacro\n\t", file);
+
+         if (TARGET_FIX_R4000)
+       fputs (".p2align 3\n\t", file);
        }
      break;
 
@@ -9326,10 +9329,16 @@ mips_output_conditional_branch (rtx insn
      output_asm_insn ("%#", 0);
 
    if (length <= 16)
-     output_asm_insn ("j\t%0", &orig_target);
+     {
+       if (TARGET_FIX_R4000)
+         output_asm_insn (".p2align 3", 0);
+       output_asm_insn ("j\t%0", &orig_target);
+     }
    else
      {
        output_asm_insn (mips_output_load_label (), &orig_target);
+       if (TARGET_FIX_R4000)
+         output_asm_insn (".p2align 3", 0);
        output_asm_insn ("jr\t%@%]", 0);
      }


I already recompiled the kernel and all jumps and most branches seem to be
aligned. And the kernel works! Now I'm recompiling the whole userland to see
if it makes any difference.

We made this fix depend on -mfix-r4000. 


-- 
    _  Frank Wille (frank%phoenix.owl.de@localhost)
 _ //  http://sun.hasenbraten.de/~frank/
 \X/   Phx @ #AmigaGer



Home | Main Index | Thread Index | Old Index