mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2025-01-10 16:31:18 +01:00
Guard against the i8254 timer being uninitialzed if DELAY() is
called early for console i/o. The timer is usually in BIOS mode if it isn't explicitly initialized. Then it counts twice as fast and has a max count of 65535 instead of 11932. The larger count tended to cause infinite loops for delays of > 20 us. Such delays are rare. For syscons and kbdio, DELAY() is only called early enough to matter for ddb input after booting with -d, and the delay is too small to matter (and too small to be correct) except in the PC98 case. For pcvt, DELAY() is not used for small delays (pcvt uses its own broken routine instead of the standard broken one), but some versions call DELAY() with a large arg when they unnecessarily initialize the keyboard for doing console output. The problem is more serious for pcvt because there is always some early console output. Guard against the i8254 timer being partially or incorrectly initialized. This would have prevented the endless loop. Should be in 2.2.
This commit is contained in:
parent
3d0c754cd0
commit
6bed7e5140
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=21783
@ -146,6 +146,7 @@ static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
|
||||
#endif
|
||||
static void set_timer_freq(u_int freq, int intr_freq);
|
||||
|
||||
static void
|
||||
clkintr(struct clockframe frame)
|
||||
@ -361,7 +362,7 @@ getit(void)
|
||||
void
|
||||
DELAY(int n)
|
||||
{
|
||||
int prev_tick, tick, ticks_left, sec, usec;
|
||||
int delta, prev_tick, tick, ticks_left, sec, usec;
|
||||
|
||||
#ifdef DELAYDEBUG
|
||||
int getit_calls = 1;
|
||||
@ -377,6 +378,13 @@ DELAY(int n)
|
||||
if (state == 1)
|
||||
printf("DELAY(%d)...", n);
|
||||
#endif
|
||||
/*
|
||||
* Guard against the timer being uninitialized if we are called
|
||||
* early for console i/o.
|
||||
*/
|
||||
if (timer0_max_count == 0)
|
||||
set_timer_freq(timer_freq, hz);
|
||||
|
||||
/*
|
||||
* Read the counter first, so that the rest of the setup overhead is
|
||||
* counted. Guess the initial overhead is 20 usec (on most systems it
|
||||
@ -404,11 +412,20 @@ DELAY(int n)
|
||||
#ifdef DELAYDEBUG
|
||||
++getit_calls;
|
||||
#endif
|
||||
if (tick > prev_tick)
|
||||
ticks_left -= prev_tick - (tick - timer0_max_count);
|
||||
else
|
||||
ticks_left -= prev_tick - tick;
|
||||
delta = prev_tick - tick;
|
||||
prev_tick = tick;
|
||||
if (delta < 0) {
|
||||
delta += timer0_max_count;
|
||||
/*
|
||||
* Guard against timer0_max_count being wrong.
|
||||
* This shouldn't happen in normal operation,
|
||||
* but it may happen if set_timer_freq() is
|
||||
* traced.
|
||||
*/
|
||||
if (delta < 0)
|
||||
delta = 0;
|
||||
}
|
||||
ticks_left -= delta;
|
||||
}
|
||||
#ifdef DELAYDEBUG
|
||||
if (state == 1)
|
||||
|
@ -146,6 +146,7 @@ static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
|
||||
#endif
|
||||
static void set_timer_freq(u_int freq, int intr_freq);
|
||||
|
||||
static void
|
||||
clkintr(struct clockframe frame)
|
||||
@ -361,7 +362,7 @@ getit(void)
|
||||
void
|
||||
DELAY(int n)
|
||||
{
|
||||
int prev_tick, tick, ticks_left, sec, usec;
|
||||
int delta, prev_tick, tick, ticks_left, sec, usec;
|
||||
|
||||
#ifdef DELAYDEBUG
|
||||
int getit_calls = 1;
|
||||
@ -377,6 +378,13 @@ DELAY(int n)
|
||||
if (state == 1)
|
||||
printf("DELAY(%d)...", n);
|
||||
#endif
|
||||
/*
|
||||
* Guard against the timer being uninitialized if we are called
|
||||
* early for console i/o.
|
||||
*/
|
||||
if (timer0_max_count == 0)
|
||||
set_timer_freq(timer_freq, hz);
|
||||
|
||||
/*
|
||||
* Read the counter first, so that the rest of the setup overhead is
|
||||
* counted. Guess the initial overhead is 20 usec (on most systems it
|
||||
@ -404,11 +412,20 @@ DELAY(int n)
|
||||
#ifdef DELAYDEBUG
|
||||
++getit_calls;
|
||||
#endif
|
||||
if (tick > prev_tick)
|
||||
ticks_left -= prev_tick - (tick - timer0_max_count);
|
||||
else
|
||||
ticks_left -= prev_tick - tick;
|
||||
delta = prev_tick - tick;
|
||||
prev_tick = tick;
|
||||
if (delta < 0) {
|
||||
delta += timer0_max_count;
|
||||
/*
|
||||
* Guard against timer0_max_count being wrong.
|
||||
* This shouldn't happen in normal operation,
|
||||
* but it may happen if set_timer_freq() is
|
||||
* traced.
|
||||
*/
|
||||
if (delta < 0)
|
||||
delta = 0;
|
||||
}
|
||||
ticks_left -= delta;
|
||||
}
|
||||
#ifdef DELAYDEBUG
|
||||
if (state == 1)
|
||||
|
@ -146,6 +146,7 @@ static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
|
||||
#endif
|
||||
static void set_timer_freq(u_int freq, int intr_freq);
|
||||
|
||||
static void
|
||||
clkintr(struct clockframe frame)
|
||||
@ -361,7 +362,7 @@ getit(void)
|
||||
void
|
||||
DELAY(int n)
|
||||
{
|
||||
int prev_tick, tick, ticks_left, sec, usec;
|
||||
int delta, prev_tick, tick, ticks_left, sec, usec;
|
||||
|
||||
#ifdef DELAYDEBUG
|
||||
int getit_calls = 1;
|
||||
@ -377,6 +378,13 @@ DELAY(int n)
|
||||
if (state == 1)
|
||||
printf("DELAY(%d)...", n);
|
||||
#endif
|
||||
/*
|
||||
* Guard against the timer being uninitialized if we are called
|
||||
* early for console i/o.
|
||||
*/
|
||||
if (timer0_max_count == 0)
|
||||
set_timer_freq(timer_freq, hz);
|
||||
|
||||
/*
|
||||
* Read the counter first, so that the rest of the setup overhead is
|
||||
* counted. Guess the initial overhead is 20 usec (on most systems it
|
||||
@ -404,11 +412,20 @@ DELAY(int n)
|
||||
#ifdef DELAYDEBUG
|
||||
++getit_calls;
|
||||
#endif
|
||||
if (tick > prev_tick)
|
||||
ticks_left -= prev_tick - (tick - timer0_max_count);
|
||||
else
|
||||
ticks_left -= prev_tick - tick;
|
||||
delta = prev_tick - tick;
|
||||
prev_tick = tick;
|
||||
if (delta < 0) {
|
||||
delta += timer0_max_count;
|
||||
/*
|
||||
* Guard against timer0_max_count being wrong.
|
||||
* This shouldn't happen in normal operation,
|
||||
* but it may happen if set_timer_freq() is
|
||||
* traced.
|
||||
*/
|
||||
if (delta < 0)
|
||||
delta = 0;
|
||||
}
|
||||
ticks_left -= delta;
|
||||
}
|
||||
#ifdef DELAYDEBUG
|
||||
if (state == 1)
|
||||
|
@ -146,6 +146,7 @@ static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
|
||||
#endif
|
||||
static void set_timer_freq(u_int freq, int intr_freq);
|
||||
|
||||
static void
|
||||
clkintr(struct clockframe frame)
|
||||
@ -361,7 +362,7 @@ getit(void)
|
||||
void
|
||||
DELAY(int n)
|
||||
{
|
||||
int prev_tick, tick, ticks_left, sec, usec;
|
||||
int delta, prev_tick, tick, ticks_left, sec, usec;
|
||||
|
||||
#ifdef DELAYDEBUG
|
||||
int getit_calls = 1;
|
||||
@ -377,6 +378,13 @@ DELAY(int n)
|
||||
if (state == 1)
|
||||
printf("DELAY(%d)...", n);
|
||||
#endif
|
||||
/*
|
||||
* Guard against the timer being uninitialized if we are called
|
||||
* early for console i/o.
|
||||
*/
|
||||
if (timer0_max_count == 0)
|
||||
set_timer_freq(timer_freq, hz);
|
||||
|
||||
/*
|
||||
* Read the counter first, so that the rest of the setup overhead is
|
||||
* counted. Guess the initial overhead is 20 usec (on most systems it
|
||||
@ -404,11 +412,20 @@ DELAY(int n)
|
||||
#ifdef DELAYDEBUG
|
||||
++getit_calls;
|
||||
#endif
|
||||
if (tick > prev_tick)
|
||||
ticks_left -= prev_tick - (tick - timer0_max_count);
|
||||
else
|
||||
ticks_left -= prev_tick - tick;
|
||||
delta = prev_tick - tick;
|
||||
prev_tick = tick;
|
||||
if (delta < 0) {
|
||||
delta += timer0_max_count;
|
||||
/*
|
||||
* Guard against timer0_max_count being wrong.
|
||||
* This shouldn't happen in normal operation,
|
||||
* but it may happen if set_timer_freq() is
|
||||
* traced.
|
||||
*/
|
||||
if (delta < 0)
|
||||
delta = 0;
|
||||
}
|
||||
ticks_left -= delta;
|
||||
}
|
||||
#ifdef DELAYDEBUG
|
||||
if (state == 1)
|
||||
|
@ -146,6 +146,7 @@ static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
|
||||
#endif
|
||||
static void set_timer_freq(u_int freq, int intr_freq);
|
||||
|
||||
static void
|
||||
clkintr(struct clockframe frame)
|
||||
@ -361,7 +362,7 @@ getit(void)
|
||||
void
|
||||
DELAY(int n)
|
||||
{
|
||||
int prev_tick, tick, ticks_left, sec, usec;
|
||||
int delta, prev_tick, tick, ticks_left, sec, usec;
|
||||
|
||||
#ifdef DELAYDEBUG
|
||||
int getit_calls = 1;
|
||||
@ -377,6 +378,13 @@ DELAY(int n)
|
||||
if (state == 1)
|
||||
printf("DELAY(%d)...", n);
|
||||
#endif
|
||||
/*
|
||||
* Guard against the timer being uninitialized if we are called
|
||||
* early for console i/o.
|
||||
*/
|
||||
if (timer0_max_count == 0)
|
||||
set_timer_freq(timer_freq, hz);
|
||||
|
||||
/*
|
||||
* Read the counter first, so that the rest of the setup overhead is
|
||||
* counted. Guess the initial overhead is 20 usec (on most systems it
|
||||
@ -404,11 +412,20 @@ DELAY(int n)
|
||||
#ifdef DELAYDEBUG
|
||||
++getit_calls;
|
||||
#endif
|
||||
if (tick > prev_tick)
|
||||
ticks_left -= prev_tick - (tick - timer0_max_count);
|
||||
else
|
||||
ticks_left -= prev_tick - tick;
|
||||
delta = prev_tick - tick;
|
||||
prev_tick = tick;
|
||||
if (delta < 0) {
|
||||
delta += timer0_max_count;
|
||||
/*
|
||||
* Guard against timer0_max_count being wrong.
|
||||
* This shouldn't happen in normal operation,
|
||||
* but it may happen if set_timer_freq() is
|
||||
* traced.
|
||||
*/
|
||||
if (delta < 0)
|
||||
delta = 0;
|
||||
}
|
||||
ticks_left -= delta;
|
||||
}
|
||||
#ifdef DELAYDEBUG
|
||||
if (state == 1)
|
||||
|
Loading…
Reference in New Issue
Block a user