Oops in 8250 serial driver after unregistering port

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi everybody,

I experienced the following oops when trying to read data from ttyS0 after 
deregistering the port by removing the associated driver.

Oops: kernel access of bad area, sig: 11 [#1]
PREEMPT
NIP: c0177ef4 LR: c012d278 CTR: c012d250
REGS: c3897cf0 TRAP: 0300   Not tainted  (2.6.23-gd2581171-dirty)
MSR: 00009032 <EE,ME,IR,DR>  CR: 48004222  XER: 20000000
DAR: 0000001c, DSISR: 20000000
TASK = c385a830[908] 'cat' THREAD: c3896000
GPR00: 00000020 c3897da0 c385a830 00000000 00000000 00000003 000000bf 00000000
GPR08: 00000202 c3c989d3 00000003 c3c98a08 48004224 10067024 03ff2000 00000001
GPR16: ffffffff 007fff00 00000000 00000000 00000000 1006262c 7fd5b808 10062644
GPR24: 00000000 00000000 00000000 c0344018 00000000 000000bf c02af6f8 00000003
NIP [c0177ef4] tbox_bus_write_reg+0x0/0x1c
LR [c012d278] serial_out+0x74/0x160
Call Trace:
[c3897da0] [00009032] 0x9032 (unreliable)
[c3897dc0] [c012f340] serial8250_pm+0xe0/0x12c
[c3897de0] [c012b7d4] uart_change_pm+0x58/0x5c
[c3897df0] [c012ba68] uart_close+0x17c/0x238
[c3897e10] [c0122324] release_dev+0x600/0x6c0
[c3897ec0] [c0122404] tty_release+0x20/0x3c
[c3897ee0] [c0065ea0] __fput+0x198/0x1b8
[c3897f00] [c0063eac] filp_close+0x54/0xac
[c3897f20] [c0063fa8] sys_close+0xa4/0x128
[c3897f40] [c000409c] ret_from_syscall+0x0/0x38
Instruction dump:
4bfba699 38ba00ac 7c641b78 3c60c024 38630044 4bea1085 80010024 7f83e378
bb410008 7c0803a6 38210020 4e800020 <8003001c> 54842834 7c840214 7cc429ae

The following patch gets rid of the oops.

diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index ef158c1..1574b80 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2886,6 +2886,8 @@ void serial8250_unregister_port(int line)
                uart->port.flags &= ~UPF_BOOT_AUTOCONF;
                uart->port.type = PORT_UNKNOWN;
                uart->port.dev = &serial8250_isa_devs->dev;
+               uart->port.iobase = 0;
+               uart->capabilities = 0;
                uart_add_one_port(&serial8250_reg, &uart->port);
        } else {
                uart->port.dev = NULL;

The issue is that the UART_CAP_SLEEP flag is set uart->capabilities when the 
port is registered, and is not reset afterwards. When the 8250 driver calls 
serial8250_pm, it will try to access the port. As the device disappeared this 
is obviously a bad idea.

Setting uart->capabilities to 0 in serial8250_unregister_port fixes the 
problem. Setting uart->port.iobase to 0 is not required, but prevent 
subsequent calls to serial8250_find_match_or_unused from skipping the 
unregistered port. This make the device <-> tty node association more 
predictable.

Is there any plan to get rid of the "let userspace open nonpresent ports" 
behaviour ? This would probably make the 8250 driver cleaner.

Please let me know if I should submit a single patch with both modifications, 
two patches or just the fix for the oops.

Best regards,

-- 
Laurent Pinchart
CSE Semaphore Belgium

Chaussée de Bruxelles, 732A
B-1410 Waterloo
Belgium

T +32 (2) 387 42 59
F +32 (2) 387 42 75

Attachment: pgpPhAh8Kkq68.pgp
Description: PGP signature


[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux