At the end of the delay calibration routine, explcitly reset the timer.

This fixes a critical bug where a clock interrupt would happen sometime
between the call to hp300_calibrate_delay() and when proc0 is initialized.
This ends up dereferencing a bad pointer in itimerdecr(), which scribbles
over the first page of kernel text, specifically vectors 46 and 47 (decimal).

To complicate matters, the way the bug manifested itself was different
depending on whether or not DDB was configured into the kernel.  When
DDB is in the kernel, kernel text is mapped read/write.  When DDB is not
in the kernel, kernel text is mapped read-only.  Note that the kernel
scribble happens early, typically before the console is initialized.

In the non-DDB case, the kernel will hang as soon as it's loaded because
the access causes a fault (before the console is initialized, so you
don't see the trap).

In the DDB case, the access does _not_ cause a fault.  However, the
mechanism used to enter the kernel debugger is to issue a "trap #15".
Conveniently, this is one of the corrupted vectors (47), thus rendering
DDB useless (it actually caused a recursive panic/trap loop).

This _WILL_ be in the first 1.2 official patch.
This commit is contained in:
thorpej 1996-10-04 08:55:04 +00:00
parent 3b5c181c8b
commit 8672fd704e
1 changed files with 9 additions and 1 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: clock.c,v 1.14 1996/05/18 23:30:12 thorpej Exp $ */
/* $NetBSD: clock.c,v 1.15 1996/10/04 08:55:04 thorpej Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -164,6 +164,14 @@ hp300_calibrate_delay()
asm volatile(" movpw %0@(5),%1" : : "a" (clk), "d" (intvl));
}
/*
* Make sure the clock interrupt is disabled. Otherwise,
* we can end up calling hardclock() before proc0 is set up,
* causing a bad pointer deref.
*/
clk->clk_cr2 = CLK_CR1;
clk->clk_cr1 = CLK_RESET;
/*
* Sanity check the delay_divisor value. If we totally lost,
* assume a 50MHz CPU;