From simon@comsys.ntu-kpi.kiev.ua  Fri Apr 12 10:54:45 2013
Return-Path: <simon@comsys.ntu-kpi.kiev.ua>
Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115])
	by hub.freebsd.org (Postfix) with ESMTP id 5D014F33
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 12 Apr 2013 10:54:45 +0000 (UTC)
	(envelope-from simon@comsys.ntu-kpi.kiev.ua)
Received: from comsys.kpi.ua (comsys.kpi.ua [77.47.192.42])
	by mx1.freebsd.org (Postfix) with ESMTP id 1BA341ED4
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 12 Apr 2013 10:54:44 +0000 (UTC)
Received: from pm513-1.comsys.kpi.ua ([10.18.52.101] helo=pm513-1.comsys.ntu-kpi.kiev.ua)
	by comsys.kpi.ua with esmtpsa (TLSv1:AES256-SHA:256)
	(Exim 4.63)
	(envelope-from <simon@comsys.ntu-kpi.kiev.ua>)
	id 1UQbcw-0004eo-L7
	for FreeBSD-gnats-submit@freebsd.org; Fri, 12 Apr 2013 13:54:42 +0300
Received: by pm513-1.comsys.ntu-kpi.kiev.ua (Postfix, from userid 1001)
	id 9D8991E089; Fri, 12 Apr 2013 13:54:41 +0300 (EEST)
Message-Id: <20130412105440.GA36243@pm513-1.comsys.ntu-kpi.kiev.ua>
Date: Fri, 12 Apr 2013 13:54:40 +0300
From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To: FreeBSD-gnats-submit@freebsd.org
Subject: atkbdc_setup() integer divide fault under QEMU / amd64

>Number:         177804
>Category:       kern
>Synopsis:       [keyboard] atkbdc_setup() integer divide fault under QEMU / amd64
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 12 11:00:00 UTC 2013
>Closed-Date:    
>Last-Modified:  Fri Apr 12 23:55:52 UTC 2013
>Originator:     Andrey Simonenko
>Release:        FreeBSD 10-CURRENT amd64
>Organization:
>Environment:
>Description:

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();
	read_status(sc);
	tscval[1] = rdtsc();
	DELAY(1000);
	tscval[2] = rdtsc();
	intr_restore(flags);
	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: [GIANT-LOCKED]
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
db>
----------------------------------------------------------------

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
40
isa_probe_children() at isa_probe_children+0x275/frame 0xffffffff80c72c90
mi_startup() at mi_startup+0x77/frame 0xffffffff80c72cb0
btext() at btext+0x2c
db>
----------------------------------------------------------------

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.

>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
