Bug 42880 - unable to call uart_register_driver/uart_unregister_driver many times for one driver
unable to call uart_register_driver/uart_unregister_driver many times for one...
Product: Drivers
Classification: Unclassified
Component: Serial
All Linux
: P1 normal
Assigned To: Alan
Depends on:
  Show dependency treegraph
Reported: 2012-03-07 04:28 UTC by quangcm
Modified: 2012-07-01 09:39 UTC (History)
2 users (show)

See Also:
Kernel Version:
Tree: Mainline
Regression: No


Description quangcm 2012-03-07 04:28:46 UTC
I'm testing on linux-2.6.35. My test case is register/unregister an uart driver many times.
The first time I call uart_register_driver() then uart_unregister_driver() -> test case OK
Next, I call uart_register_driver() then uart_unregister_driver() again with the same uart_driver pointer -> segmentation fault occurred.

I've investigated this error and found this:
function uart_unregister_driver
	kfree(drv->state); //<-- free but not set null for drv->state

function uart_register_driver
	BUG_ON(drv->state); //<-- cause error when drv->state is not null

I have a question: does specification of uart_register_driver function allow it to be called only one time for one driver??? Is it true?

This is the error message and back-trace:

kernel BUG at drivers/serial/serial_core.c:2402!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c6a14000
[00000000] *pgd=66a01031, *pte=00000000, *ppte=00000000
Internal error: Oops: 817 [#1] PREEMPT SMP
last sysfs file: /sys/class/i2c-dev/i2c-0/dev
Modules linked in: uart_fakedrv
CPU: 0    Not tainted  ( #205)
PC is at __bug+0x1c/0x28
LR is at __bug+0x18/0x28
pc : [<c003a234>]    lr : [<c003a230>]    psr: 60000013
sp : c6a29eb8  ip : 00002d7c  fp : bebc1c24
r10: 00000000  r9 : c6a28000  r8 : c00369e8
r7 : 00000c21  r6 : c72a8800  r5 : bf002248  r4 : 00000000
r3 : 00000000  r2 : c6a29eac  r1 : c039a995  r0 : 00000037
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 10c5387d  Table: 66a1404a  DAC: 00000015
Process uart_test (pid: 513, stack limit = 0xc6a282f0)
Stack: (0xc6a29eb8 to 0xc6a2a000)
9ea0:                                                       0fd00040 c01937ac
9ec0: 00000000 00000001 000000e0 00000c21 c00369e8 bf001df4 c0446dc8 00000000
9ee0: c6a29f20 00000000 00000001 c6a28000 bebc1c24 c694dc80 00000000 000000e0
9f00: 00000c21 c00bf1dc c6c247d0 000000e0 c694dc80 00000c21 00000003 c00bf804
9f20: c73cb0d8 c0160a8c 00000001 00000001 c6a29f44 c00490f4 c68a39ac c0555c60
9f40: c0420600 60000093 c6a4d000 c0082ff4 00000000 c7006c80 60000013 c6a4d000
9f60: c70008a0 c694dc80 000000e0 00000c21 00000003 c00369e8 c6a28000 00000000
9f80: bebc1c24 c00bf880 00000003 00000000 000000e0 000000e4 00000140 4020a000
9fa0: 00000036 c0036840 000000e4 00000140 00000003 00000c21 000000e0 00000003
9fc0: 000000e4 00000140 4020a000 00000036 00000000 00000000 0000f060 bebc1c24
9fe0: 4020bb68 bebc1c00 000107d8 40194d9c 60000010 00000003 00000000 00000000
[<c003a234>] (__bug+0x1c/0x28) from [<c01937ac>] (uart_register_driver+0x20/0x160)
[<c01937ac>] (uart_register_driver+0x20/0x160) from [<bf001df4>] (uart_fakedrv_ioctl+0x1bf8/0x1d7c [uart_fakedrv])
[<bf001df4>] (uart_fakedrv_ioctl+0x1bf8/0x1d7c [uart_fakedrv]) from [<c00bf1dc>] (vfs_ioctl+0x7c/0xac)
[<c00bf1dc>] (vfs_ioctl+0x7c/0xac) from [<c00bf804>] (do_vfs_ioctl+0x508/0x550)
[<c00bf804>] (do_vfs_ioctl+0x508/0x550) from [<c00bf880>] (sys_ioctl+0x34/0x54)
[<c00bf880>] (sys_ioctl+0x34/0x54) from [<c0036840>] (ret_fast_syscall+0x0/0x30)
Code: e59f0010 e1a01003 eb0b448b e3a03000 (e5833000) 
---[ end trace bafb193c5c900268 ]---
Comment 1 Alan 2012-05-12 02:06:52 UTC
It never normally happens without the module being loaded/unloaded thus resettng drv

But it does look like a bug
Comment 2 Alan 2012-05-14 13:52:40 UTC
Patch queued for 3.5: 9e50db4548964c2adc9090392e4cdc49b0e730ff
Comment 3 Florian Mickler 2012-07-01 09:39:48 UTC
A patch referencing this bug report has been merged in Linux v3.5-rc1:

commit 1e66cded334e6cea596c72f6f650eec351b1e959
Author: Alan Cox <alan@linux.intel.com>
Date:   Mon May 14 14:51:22 2012 +0100

    tty: Allow uart_register/unregister/register

Note You need to log in before you can comment on or make changes to this bug.