kern/177804: atkbdc_setup() integer divide fault under QEMU / amd64

Andrey Simonenko simon at
Fri Apr 12 11:00:01 UTC 2013

>Number:         177804
>Category:       kern
>Synopsis:       atkbdc_setup() integer divide fault under QEMU / amd64
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 12 11:00:00 UTC 2013
>Originator:     Andrey Simonenko
>Release:        FreeBSD 10-CURRENT amd64

QEMU / amd64 (0.11.1_12) often results in integer divide fault in
the atkbdc_setup() function.

There is one division in dev/atkbdc/atkbdc.c:atkbdc_setup() if
it is built for amd64:

	flags = intr_disable();
	tscval[0] = rdtsc();
	tscval[1] = rdtsc();
	tscval[2] = rdtsc();
	read_delay = tscval[1] - tscval[0];
	read_delay /= (tscval[2] - tscval[1]) / 1000;
	sc->retry = 100000 / ((KBDD_DELAYTIME * 2) + read_delay);

I modified this function to verify why there can division by zero,
the debug message is:

log(LOG_DEBUG, "------------->>>>> %lu %lu %lu\n",
    tscval[2], tscval[1], tscval[2] - tscval[1]);

This is output from qemu:

kbd0 at atkbd0
atkbd0: [GIANT-LOCKED]
psm0: <PS/2 Mouse> irq 12 on atkbdc0
psm0: model IntelliMouse Explorer, device ID 4
fdc0: <floppy drive controller> port 0x3f2-0x3f5,0x3f7 irq 6 drq 2 on acpi0
fdc0: does not respond
device_attach: fdc0 attach returned 6
uart0: <Non-standard ns8250 class UART with FIFOs> port 0x3f8-0x3ff irq 4 flags
0x10 on acpi0
------------->>>>> 29041115531 29041115531 0

Fatal trap 18: integer divide fault while in kernel mode
cpuid = 0; apic id = 00
instruction pointer     = 0x20:0xffffffff8059d2af
stack pointer           = 0x28:0xffffffff80c72a60
frame pointer           = 0x28:0xffffffff80c72aa0
code segment            = base 0x0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags        = interrupt enabled, IOPL = 0
current process         = 0 (swapper)
[ thread pid 0 tid 100000 ]
Stopped at      atkbdc_setup+0xff:      divq    %rbx,%eax

And backtrace:

db> bt
Tracing pid 0 tid 100000 td 0xffffffff808e6b60
atkbdc_setup() at atkbdc_setup+0xff/frame 0xffffffff80c72aa0
atkbdc_configure() at atkbdc_configure+0x85/frame 0xffffffff80c72ac0
atkbd_configure() at atkbd_configure+0x12/frame 0xffffffff80c72b00
kbd_configure() at kbd_configure+0x51/frame 0xffffffff80c72b20
sckbdprobe() at sckbdprobe+0x1d/frame 0xffffffff80c72b40
sc_probe_unit() at sc_probe_unit+0x52/frame 0xffffffff80c72b60
scprobe() at scprobe+0x8c/frame 0xffffffff80c72b90
device_probe_child() at device_probe_child+0x1f8/frame 0xffffffff80c72bf0
device_probe() at device_probe+0x55/frame 0xffffffff80c72c20
device_probe_and_attach() at device_probe_and_attach+0x31/frame 0xffffffff80c72c
isa_probe_children() at isa_probe_children+0x275/frame 0xffffffff80c72c90
mi_startup() at mi_startup+0x77/frame 0xffffffff80c72cb0
btext() at btext+0x2c

So, the bug really is not in atkbdc_setup(), but in DELAY() or in QEMU,
that under some conditions cannot perform delay for 1 ms.


More information about the freebsd-bugs mailing list