Subject: Impossible fixup in do_ade

From: Daniel Jacobowitz <[email-masked]>
Date: Sat, 20 Sep 2003 11:20:36 -0400

Here's a snippet from emulate_load_store_insn.  See the way the sdl and sdr
are wrapped in fixups?  Well, the fixups can't trigger: we get to
emulate_load_store_insn a second time, and we hit the fact that sdl_op has a
"goto sigbus" before we hit the fixup_exception call.

It doesn't much matter, the bug I'm working on is whatever caused the first
call.  But we get a SIGBUS when arguably we ought to get a SIGSEGV.

        case sd_op:
#ifdef CONFIG_MIPS64
                /*
                 * A 32-bit kernel might be running on a 64-bit processor.  But
                 * if we're on a 32-bit processor and an i-cache incoherency
                 * or race makes us see a 64-bit instruction here the sdl/sdr
                 * would blow up, so for now we don't handle unaligned 64-bit
                 * instructions on 32-bit kernels.
                 */
                if (verify_area(VERIFY_WRITE, addr, 8))
                        goto sigbus;

                value = regs->regs[insn.i_format.rt];
                __asm__ __volatile__ (
#ifdef __BIG_ENDIAN
                        "1:\tsdl\t%1,(%2)\n"
                        "2:\tsdr\t%1, 7(%2)\n\t"
#endif
#ifdef __LITTLE_ENDIAN
                        "1:\tsdl\t%1, 7(%2)\n"
                        "2:\tsdr\t%1, (%2)\n\t"
#endif
                        "li\t%0, 0\n"
                        "3:\n\t"
                        ".section\t.fixup,\"ax\"\n\t"
                        "4:\tli\t%0, %3\n\t"
                        "j\t3b\n\t"
                        ".previous\n\t"
                        ".section\t__ex_table,\"a\"\n\t"
                        STR(PTR)"\t1b, 4b\n\t"
                        STR(PTR)"\t2b, 4b\n\t"
                        ".previous"
                : "=r" (res)
                : "r" (value), "r" (addr), "i" (-EFAULT));
                if (res)
                        goto fault;
                break;

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

---

From: Ralf Baechle <[email-masked]>
Date: Sun, 21 Sep 2003 09:00:33 -0700

> call.  But we get a SIGBUS when arguably we ought to get a SIGSEGV.

The fixup can be triggered - think of an missaligned load or store
inside the kernel itself.  If there's no fixup we'll simply assume the
instruction was in userspace and send a signal which is true unless there's
a kernel bug.

In case we deliver a signal at fault: I think it's arguable what signal is
the most appropriate one but for simplicity I decieded to consider the
address error exception as the cause so SIGBUS is the right signal.  We
simply don't gather sufficient information to deciede what the right
signal to send is and it's a very rare case anyway so nobody noticed yet :)

  Ralf