summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormickey <mickey@openbsd.org>1998-05-13 19:49:25 +0000
committermickey <mickey@openbsd.org>1998-05-13 19:49:25 +0000
commitfa47d16ca409b014c8216f812e15e153cfdc482a (patch)
tree31ee5b0f64db928c672b9c6efd8cfeba0be6fa16
parentgenerate int errorcodes instead of long to match the new libcom_err (diff)
downloadwireguard-openbsd-fa47d16ca409b014c8216f812e15e153cfdc482a.tar.xz
wireguard-openbsd-fa47d16ca409b014c8216f812e15e153cfdc482a.zip
making kernel, drinking LI tea and writing an opus magnum enspired
by the freebsd commit logs: first of all i should state that we are the only os that uses pentium counters in their microtime (freebsd, netbsd, etc checked). the bug fixed derives from the fact that #UD (divide by zero) is generated in two cases: a) divide by zero; b) divide overflow. so, the later case was the one causing panics on reboot. due to the divl insn design in the intel processors, the possible sizes of operands and results are: 16/8=8,8; 32/16=16,16; 64/32=32,32. the division will generate an #UD exception when the quotient won't fit into result, that is 32bit in our case (64bit is divided on 32bit). problem solved by normalizing the dividend by the divisor, so the quotient would not result a divide overflow. tested by: mickey, gene, mickey. talked over: mickey, gene, marc, maillists, mickey.
-rw-r--r--sys/arch/i386/i386/microtime.s21
1 files changed, 15 insertions, 6 deletions
diff --git a/sys/arch/i386/i386/microtime.s b/sys/arch/i386/i386/microtime.s
index 27b417abe52..6234c91f9ae 100644
--- a/sys/arch/i386/i386/microtime.s
+++ b/sys/arch/i386/i386/microtime.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: microtime.s,v 1.10 1997/12/30 23:35:19 mickey Exp $ */
+/* $OpenBSD: microtime.s,v 1.11 1998/05/13 19:49:25 mickey Exp $ */
/* $NetBSD: microtime.s,v 1.16 1995/04/17 12:06:47 cgd Exp $ */
/*-
@@ -57,6 +57,7 @@ ENTRY(microtime)
#endif
movb $(TIMER_SEL0|TIMER_LATCH),%al
+ pushfl
cli # disable interrupts
outb %al,$TIMER_MODE # latch timer 0's counter
@@ -125,7 +126,7 @@ common_microtime:
movl _time,%edx # get time.tv_sec
addl _time+4,%eax # add time.tv_usec
- sti # enable interrupts
+ popfl # enable interrupts
cmpl $1000000,%eax # carry in timeval?
jb 3f
@@ -147,14 +148,22 @@ common_microtime:
#if defined (NTP)
.align 2, 0x90
pentium_microtime:
+ pushfl
cli
.byte 0x0f, 0x31 # RDTSC
subl _pentium_base_tsc,%eax
sbbl _pentium_base_tsc+4,%edx
- orl %ecx, %ecx
- jnz 1f
- incl %ecx
-1: divl %ecx # convert to usec
+ /*
+ * correct the high word first so we won't
+ * receive a result overflow aka div/0 fault
+ */
+ pushl %eax
+ movl %edx, %eax
+ shll $16, %edx
+ divw %cx
+ movzwl %dx, %edx
+ popl %eax
+ divl %ecx
jmp common_microtime
#endif
#endif