linux-next: manual merge of the tty tree with the tty.current tree
Subsystems (2)
Mark Brown
maintainerHi all,
Today's linux-next merge of the tty tree got a conflict in:
drivers/tty/serial/serial_core.c
between commit:
499485a67fbac ("serial: core: fix NULL pointer dereference in serial_core_unregister_port()")
from the tty.current tree and commit:
b290393074a14 ("serial: core: fix NULL/dangling port_dev on failed re-register")
from the tty tree.
I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts.
drivers/tty/serial/serial_core.c +0 -0
@@@ -33,7 -33,6 +33,6 @@@#include <linux/uaccess.h> #include "serial_base.h" -#include "8250/8250.h" /* For hub6_match_port() */ /* * This is used to lock changes in serial line configuration. struct uart_state *state = container_of(port, struct uart_state, port); struct uart_port *uport; unsigned long flags; -unsigned long page; +u8 *buf; /* * Initialise and allocate the transmit and temporary * buffer. */ - page =get_zeroed_page (GFP_KERNEL ); -if (!page) + buf =kzalloc (PAGE_SIZE ,GFP_KERNEL ); +if (!buf)return -ENOMEM ; uport =uart_port_ref_lock (state, &flags);if (!state->port.xmit_buf) { - state->port.xmit_buf = (unsigned char *)page; + state->port.xmit_buf = buf;kfifo_init (&state->port.xmit_fifo, state->port.xmit_buf,PAGE_SIZE );uart_port_unlock_deref (uport, flags); }else {uart_port_unlock_deref (uport, flags);/* -* Do not free() the page under the port lock, see +* Do not free() the buffer under the port lock, see * uart_free_xmit_buf(). */ -free_page (page); +kfree (buf); }return 0 ; struct uart_state *state = container_of(port, struct uart_state, port);struct uart_port *uport;unsigned long flags; -char *xmit_buf; +u8 *xmit_buf;/* -* Do not free() the transmit buffer page under the port lock since +* Do not free() the transmit buffer under the port lock since * this can create various circular locking scenarios. For instance, * console driver may need to allocate/free a debug object, which * can end up in printk() recursion. INIT_KFIFO(port->xmit_fifo); uart_port_unlock_deref(uport, flags); - free_page((unsigned long)xmit_buf); +kfree(xmit_buf); } /* upf_t old_flags, new_flags; int retval; - if (!uport) + if (!uport || tty_io_error(tty)) return -EIO; new_port = new_info->port; guard(mutex)(&port->mutex); uport = uart_port_check(state); - if (!uport) + if (!uport || tty_io_error(tty)) return -EIO; if (uport->type != PORT_UNKNOWN && uport->ops->break_ctl) */ scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &port->mutex) { uport =uart_port_check (state); - if (!uport) + if (!uport || tty_io_error(tty)) return -EIO;if (tty_port_users (port) !=1 ) * FIXME: This wants extracting into a common all driver implementation * of TIOCMWAIT using tty_port. */ -static int uart_wait_modem_status(struct uart_state *state, unsigned long arg) +static int uart_wait_modem_status(struct tty_struct *tty, struct uart_state *state, unsigned long arg) {struct uart_port *uport;struct tty_port *port = &state->port; uport =uart_port_ref (state);if (!uport)return -EIO ; - scoped_guard(uart_port_lock_irq, uport) { -memcpy (&cprev, &uport->icount,sizeof (struct uart_icount )); -uart_enable_ms (uport); + +mutex_lock (&port->mutex); + if (tty_io_error(tty)) { +mutex_unlock (&port->mutex); + ret = -EIO ; + goto out_deref; } +uart_port_lock_irq (uport); +memcpy (&cprev, &uport->icount,sizeof (struct uart_icount )); +uart_enable_ms (uport); +uart_port_unlock_irq (uport); + +mutex_unlock (&port->mutex); +add_wait_queue (&port->delta_msr_wait, &wait);for (;;) { -scoped_guard (uart_port_lock_irq, uport) -memcpy (&cnow, &uport->icount,sizeof (struct uart_icount )); -set_current_state (TASK_INTERRUPTIBLE ); +uart_port_lock_irq (uport); +memcpy (&cnow, &uport->icount,sizeof (struct uart_icount )); +uart_port_unlock_irq (uport); + if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ((arg &TIOCM_DSR ) && (cnow.dsr != cprev.dsr)) || ((arg &TIOCM_CD ) && (cnow.dcd != cprev.dcd)) || break; } + if (tty_io_error(tty)) { + ret = -EIO ; + break; + } +schedule ();/* see if a signal did it */ }__set_current_state (TASK_RUNNING );remove_wait_queue (&port->delta_msr_wait, &wait); +out_deref:uart_port_deref (uport);return ret;/* This should only be used when the hardware is present. */ if (cmd ==TIOCMIWAIT ) - return uart_wait_modem_status(state, arg); + return uart_wait_modem_status(tty, state, arg);/* rs485_config requires more locking than others */ if (cmd ==TIOCSRS485 ) {struct uart_state *state = tty->driver_data;struct uart_port *uport; - struct tty_port *port = &state->port; - - if (!tty_port_initialized(port)) - return;guard (mutex)(&state->port.mutex); uport =uart_port_check (state); - if (uport && uport->ops->set_ldisc) + if (!uport || tty_io_error(tty)) + return; + + if (uport->ops->set_ldisc) uport->ops->set_ldisc(uport, &tty->termios); }guard (mutex)(&state->port.mutex); uport =uart_port_check (state); - if (!uport) + if (!uport || tty_io_error(tty)) return;/* * 'timeout' / 'expire' give us the maximum amount of time * we wait. */ - while (!port->ops->tx_empty(port)) { + for (;;) { + mutex_lock(&state->port.mutex); + if (tty_io_error(tty) || port->ops->tx_empty(port)) { + mutex_unlock(&state->port.mutex); + break; + } +mutex_unlock (&state->port.mutex); +msleep_interruptible (jiffies_to_msecs (char_time));if (signal_pending (current))break ;/** * uart_parse_earlycon - Parse earlycon options -* @p: ptr to 2nd field (ie., just beyond '<name>,') +* @p: ptr to 2nd field (ie., just beyond '<name>,'); %NULL if +* no console options were supplied * @iotype: ptr for decoded iotype (out) * @addr: ptr for decoded mapbase/iobase (out) * @options: ptr for <options> field; %NULL if not present (out) int uart_parse_earlycon(char *p, enum uart_iotype *iotype, resource_size_t *addr, char **options) { +if (!p) +return -EINVAL; +if (strncmp(p, "mmio,", 5) == 0) { *iotype = UPIO_MEM; p += 5; state->uart_port = NULL; } - /** -* uart_match_port - are the two ports equivalent? -* @port1: first port -* @port2: second port -* -* This utility function can be used to determine whether two uart_port -* structures describe the same port. -*/ -bool uart_match_port (const struct uart_port *port1, -const struct uart_port *port2) - { -if (port1->iotype != port2->iotype) -return false; -else if (port1->iotype ==UPIO_PORT ) -return port1->iobase == port2->iobase; -else if (port1->iotype ==UPIO_HUB6 ) -return hub6_match_port (port1, port2); -else if (uart_iotype_mmio (port1->iotype)) -return port1->mapbase == port2->mapbase; -else if (port1->iotype ==UPIO_BUS ) -return true; -else -return false; - } -EXPORT_SYMBOL (uart_match_port); -static struct serial_ctrl_device * serial_core_get_ctrl_dev(struct serial_port_device *port_dev) { guard(mutex)(&port_mutex); - /* May have never been registered. */ +/* + * A NULL port device means there is no registered port device to + * remove: serial_core_remove_one_port() clears port_dev on + * teardown, and it is never set if registration failed before + * serial_core_port_device_add(). + */ port_dev = port->port_dev;if (!port_dev)return ;
Quoted 14 lines · Mark Brown
Hi all,
Today's linux-next merge of the tty tree got a conflict in:
drivers/tty/serial/serial_core.cbetween commit:
499485a67fbac("serial: core: fix NULL pointer dereference inserial_core_unregister_port()")from the tty.current tree and commit:
b290393074a14("serial: core: fix NULL/danglingport_devon failed re-register")
Quoted 8 lines
from the tty tree.
I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts.
Ick, this is messy, sorry. I'll fix it up next week when I get the tty.current tree to Linus.
greg k-h