From e21120383f2dce32312f63ffca145ff8a87d41f5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 19:47:09 -0400 Subject: move compat handling of tty ioctls to tty_compat_ioctl() ioctls that are * callable only via tty_ioctl() * not driver-specific * not demand data structure conversions * either always need passing arg as is or always demand compat_ptr() get intercepted in tty_compat_ioctl() from the very beginning and redirecter to tty_ioctl(). As the result, their entries in fs/compat_ioctl.c (some of those had been missing, BTW) got removed, as well as n_tty_compat_ioctl_helper() (now it's never called with any cmd it would accept). Signed-off-by: Al Viro --- include/linux/tty.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index c56e3978b00f..414db2bce715 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -746,8 +746,6 @@ static inline int tty_audit_push(void) /* tty_ioctl.c */ extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); -extern long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg); /* vt.c */ -- cgit v1.2.3 From 2f46a2c1d4eb982b82c199e1bd5cddab12681275 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 21:53:32 -0400 Subject: tty_ioctl(): start taking TIOC[SG]SERIAL into separate methods ->set_serial() and ->get_serial() resp., both taking tty and a kernel pointer to serial_struct. Signed-off-by: Al Viro --- include/linux/tty_driver.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 71dbc891851a..358446247ccd 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -249,6 +249,7 @@ struct tty_struct; struct tty_driver; struct serial_icounter_struct; +struct serial_struct; struct tty_operations { struct tty_struct * (*lookup)(struct tty_driver *driver, @@ -287,6 +288,8 @@ struct tty_operations { int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew); int (*get_icount)(struct tty_struct *tty, struct serial_icounter_struct *icount); + int (*get_serial)(struct tty_struct *tty, struct serial_struct *p); + int (*set_serial)(struct tty_struct *tty, struct serial_struct *p); void (*show_fdinfo)(struct tty_struct *tty, struct seq_file *m); #ifdef CONFIG_CONSOLE_POLL int (*poll_init)(struct tty_driver *driver, int line, char *options); -- cgit v1.2.3 From 81732b26e05994552f347746eb11762e986079a0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 11 Sep 2018 23:28:07 -0400 Subject: usb-serial: begin switching to ->[sg]et_serial() add such methods for usb_serial_driver, provide tty_operations ->[sg]et_serial() calling those. For now the lack of methods in driver means ENOIOCTLCMD from usb-serial ->[sg]et_serial(), making tty_ioctl() fall back to calling ->ioctl(). Once all drivers are converted, we'll be returning -ENOTTY instead, completing the switchover. Reviewed-by: Johan Hovold Signed-off-by: Al Viro --- include/linux/usb/serial.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 106551a5616e..1c19f77ed541 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -285,6 +285,8 @@ struct usb_serial_driver { int (*write_room)(struct tty_struct *tty); int (*ioctl)(struct tty_struct *tty, unsigned int cmd, unsigned long arg); + int (*get_serial)(struct tty_struct *tty, struct serial_struct *ss); + int (*set_serial)(struct tty_struct *tty, struct serial_struct *ss); void (*set_termios)(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); void (*break_ctl)(struct tty_struct *tty, int break_state); -- cgit v1.2.3 From f0193d3ea73b966b5dbfa272c8228d743b8856ef Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 13 Sep 2018 22:12:15 -0400 Subject: change semantics of ldisc ->compat_ioctl() First of all, make it return int. Returning long when native method had never allowed that is ridiculous and inconvenient. More importantly, change the caller; if ldisc ->compat_ioctl() is NULL or returns -ENOIOCTLCMD, tty_compat_ioctl() will try to feed cmd and compat_ptr(arg) to ldisc's native ->ioctl(). That simplifies ->compat_ioctl() instances quite a bit - they only need to deal with ioctls that are neither generic tty ones (those would get shunted off to tty_ioctl()) nor simple compat pointer ones. Note that something like TCFLSH won't reach ->compat_ioctl(), even if ldisc ->ioctl() does handle it - it will be recognized earlier and passed to tty_ioctl() (and ultimately - ldisc ->ioctl()). For many ldiscs it means that NULL ->compat_ioctl() does the right thing. Those where it won't serve (see e.g. n_r3964.c) are also easily dealt with - we need to handle the numeric-argument ioctls (calling the native instance) and, if such would exist, the ioctls that need layout conversion, etc. All in-tree ldiscs dealt with. Signed-off-by: Al Viro --- include/linux/tty_ldisc.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 840894ca3fc0..b1e6043e9917 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -54,11 +54,17 @@ * low-level driver can "grab" an ioctl request before the line * discpline has a chance to see it. * - * long (*compat_ioctl)(struct tty_struct * tty, struct file * file, + * int (*compat_ioctl)(struct tty_struct * tty, struct file * file, * unsigned int cmd, unsigned long arg); * * Process ioctl calls from 32-bit process on 64-bit system * + * NOTE: only ioctls that are neither "pointer to compatible + * structure" nor tty-generic. Something private that takes + * an integer or a pointer to wordsize-sensitive structure + * belongs here, but most of ldiscs will happily leave + * it NULL. + * * void (*set_termios)(struct tty_struct *tty, struct ktermios * old); * * This function notifies the line discpline that a change has @@ -184,7 +190,7 @@ struct tty_ldisc_ops { const unsigned char *buf, size_t nr); int (*ioctl)(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); - long (*compat_ioctl)(struct tty_struct *tty, struct file *file, + int (*compat_ioctl)(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); void (*set_termios)(struct tty_struct *tty, struct ktermios *old); __poll_t (*poll)(struct tty_struct *, struct file *, -- cgit v1.2.3