Skip to content

Commit

Permalink
m68k: Disable/restore interrupts in hwreg_present()/hwreg_write()
Browse files Browse the repository at this point in the history
hwreg_present() and hwreg_write() temporarily change the VBR register to
another vector table. This table contains a valid bus error handler
only, all other entries point to arbitrary addresses.

If an interrupt comes in while the temporary table is active, the
processor will start executing at such an arbitrary address, and the
kernel will crash.

While most callers run early, before interrupts are enabled, or
explicitly disable interrupts, Finn Thain pointed out that macsonic has
one callsite that doesn't, causing intermittent boot crashes.
There's another unsafe callsite in hilkbd.

Fix this for good by disabling and restoring interrupts inside
hwreg_present() and hwreg_write().

Explicitly disabling interrupts can be removed from the callsites later.

Reported-by: Finn Thain <fthain@telegraphics.com.au>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: stable@vger.kernel.org
  • Loading branch information
Geert Uytterhoeven committed Oct 3, 2014
1 parent fd4d453 commit e4dc601
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions arch/m68k/mm/hwtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@
int hwreg_present( volatile void *regp )
{
int ret = 0;
unsigned long flags;
long save_sp, save_vbr;
long tmp_vectors[3];

local_irq_save(flags);
__asm__ __volatile__
( "movec %/vbr,%2\n\t"
"movel #Lberr1,%4@(8)\n\t"
Expand All @@ -46,6 +48,7 @@ int hwreg_present( volatile void *regp )
: "=&d" (ret), "=&r" (save_sp), "=&r" (save_vbr)
: "a" (regp), "a" (tmp_vectors)
);
local_irq_restore(flags);

return( ret );
}
Expand All @@ -58,9 +61,11 @@ EXPORT_SYMBOL(hwreg_present);
int hwreg_write( volatile void *regp, unsigned short val )
{
int ret;
unsigned long flags;
long save_sp, save_vbr;
long tmp_vectors[3];

local_irq_save(flags);
__asm__ __volatile__
( "movec %/vbr,%2\n\t"
"movel #Lberr2,%4@(8)\n\t"
Expand All @@ -78,6 +83,7 @@ int hwreg_write( volatile void *regp, unsigned short val )
: "=&d" (ret), "=&r" (save_sp), "=&r" (save_vbr)
: "a" (regp), "a" (tmp_vectors), "g" (val)
);
local_irq_restore(flags);

return( ret );
}
Expand Down

0 comments on commit e4dc601

Please sign in to comment.