Commit 1d5d6682 authored by Al Viro's avatar Al Viro Committed by Greg Kroah-Hartman
Browse files

termios: uninline conversion helpers



default go into drivers/tty/tty_ioctl.c, unusual - into
arch/*/kernel/termios.c (only alpha and sparc have those).

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Link: https://lore.kernel.org/r/YxDmeUBHo0s/Ew8b@ZenIV


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 408e532e
Loading
Loading
Loading
Loading
+6 −71
Original line number Diff line number Diff line
@@ -12,76 +12,11 @@
*/
#define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\001\000"

/*
 * Translate a "termio" structure into a "termios". Ugh.
 */

#define user_termio_to_kernel_termios(a_termios, u_termio)			\
({										\
	struct ktermios *k_termios = (a_termios);				\
	struct termio k_termio;							\
	int canon, ret;								\
										\
	ret = copy_from_user(&k_termio, u_termio, sizeof(k_termio));		\
	if (!ret) {								\
		/* Overwrite only the low bits.  */				\
		*(unsigned short *)&k_termios->c_iflag = k_termio.c_iflag;	\
		*(unsigned short *)&k_termios->c_oflag = k_termio.c_oflag;	\
		*(unsigned short *)&k_termios->c_cflag = k_termio.c_cflag;	\
		*(unsigned short *)&k_termios->c_lflag = k_termio.c_lflag;	\
		canon = k_termio.c_lflag & ICANON;				\
										\
		k_termios->c_cc[VINTR]  = k_termio.c_cc[_VINTR];		\
		k_termios->c_cc[VQUIT]  = k_termio.c_cc[_VQUIT];		\
		k_termios->c_cc[VERASE] = k_termio.c_cc[_VERASE];		\
		k_termios->c_cc[VKILL]  = k_termio.c_cc[_VKILL];		\
		k_termios->c_cc[VEOL2]  = k_termio.c_cc[_VEOL2];		\
		k_termios->c_cc[VSWTC]  = k_termio.c_cc[_VSWTC];		\
		k_termios->c_cc[canon ? VEOF : VMIN]  = k_termio.c_cc[_VEOF];	\
		k_termios->c_cc[canon ? VEOL : VTIME] = k_termio.c_cc[_VEOL];	\
	}									\
	ret;									\
})

/*
 * Translate a "termios" structure into a "termio". Ugh.
 *
 * Note the "fun" _VMIN overloading.
 */
#define kernel_termios_to_user_termio(u_termio, a_termios)		\
({									\
	struct ktermios *k_termios = (a_termios);			\
	struct termio k_termio;						\
	int canon;							\
									\
	k_termio.c_iflag = k_termios->c_iflag;				\
	k_termio.c_oflag = k_termios->c_oflag;				\
	k_termio.c_cflag = k_termios->c_cflag;				\
	canon = (k_termio.c_lflag = k_termios->c_lflag) & ICANON;	\
									\
	k_termio.c_line = k_termios->c_line;				\
	k_termio.c_cc[_VINTR]  = k_termios->c_cc[VINTR];		\
	k_termio.c_cc[_VQUIT]  = k_termios->c_cc[VQUIT];		\
	k_termio.c_cc[_VERASE] = k_termios->c_cc[VERASE];		\
	k_termio.c_cc[_VKILL]  = k_termios->c_cc[VKILL];		\
	k_termio.c_cc[_VEOF]   = k_termios->c_cc[canon ? VEOF : VMIN];	\
	k_termio.c_cc[_VEOL]   = k_termios->c_cc[canon ? VEOL : VTIME];	\
	k_termio.c_cc[_VEOL2]  = k_termios->c_cc[VEOL2];		\
	k_termio.c_cc[_VSWTC]  = k_termios->c_cc[VSWTC];		\
									\
	copy_to_user(u_termio, &k_termio, sizeof(k_termio));		\
})

#define user_termios_to_kernel_termios(k, u) \
	copy_from_user(k, u, sizeof(struct termios2))

#define kernel_termios_to_user_termios(u, k) \
	copy_to_user(u, k, sizeof(struct termios2))

#define user_termios_to_kernel_termios_1(k, u) \
	copy_from_user(k, u, sizeof(struct termios))

#define kernel_termios_to_user_termios_1(u, k) \
	copy_to_user(u, k, sizeof(struct termios))
int user_termio_to_kernel_termios(struct ktermios *, struct termio __user *);
int kernel_termios_to_user_termio(struct termio __user *, struct ktermios *);
int user_termios_to_kernel_termios(struct ktermios *, struct termios2 __user *);
int kernel_termios_to_user_termios(struct termios2 __user *, struct ktermios *);
int user_termios_to_kernel_termios_1(struct ktermios *, struct termios __user *);
int kernel_termios_to_user_termios_1(struct termios __user *, struct ktermios *);

#endif	/* _ALPHA_TERMIOS_H */
+1 −1
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ ccflags-y := -Wno-sign-compare

obj-y    := entry.o traps.o process.o osf_sys.o irq.o \
	    irq_alpha.o signal.o setup.o ptrace.o time.o \
	    systbls.o err_common.o io.o bugs.o
	    systbls.o err_common.o io.o bugs.o termios.o

obj-$(CONFIG_VGA_HOSE)	+= console.o
obj-$(CONFIG_SMP)	+= smp.o
+57 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
#include <linux/uaccess.h>
#include <linux/termios.h>

int user_termio_to_kernel_termios(struct ktermios *termios,
						struct termio __user *termio)
{
	struct termio v;
	bool canon;

	if (copy_from_user(&v, termio, sizeof(struct termio)))
		return -EFAULT;

	termios->c_iflag = (0xffff0000 & termios->c_iflag) | v.c_iflag;
	termios->c_oflag = (0xffff0000 & termios->c_oflag) | v.c_oflag;
	termios->c_cflag = (0xffff0000 & termios->c_cflag) | v.c_cflag;
	termios->c_lflag = (0xffff0000 & termios->c_lflag) | v.c_lflag;
	termios->c_line = (0xffff0000 & termios->c_lflag) | v.c_line;

	canon = v.c_lflag & ICANON;
	termios->c_cc[VINTR]  = v.c_cc[_VINTR];
	termios->c_cc[VQUIT]  = v.c_cc[_VQUIT];
	termios->c_cc[VERASE] = v.c_cc[_VERASE];
	termios->c_cc[VKILL]  = v.c_cc[_VKILL];
	termios->c_cc[VEOL2]  = v.c_cc[_VEOL2];
	termios->c_cc[VSWTC]  = v.c_cc[_VSWTC];
	termios->c_cc[canon ? VEOF : VMIN]  = v.c_cc[_VEOF];
	termios->c_cc[canon ? VEOL : VTIME] = v.c_cc[_VEOL];

	return 0;
}

int kernel_termios_to_user_termio(struct termio __user *termio,
						struct ktermios *termios)
{
	struct termio v;
	bool canon;

	memset(&v, 0, sizeof(struct termio));
	v.c_iflag = termios->c_iflag;
	v.c_oflag = termios->c_oflag;
	v.c_cflag = termios->c_cflag;
	v.c_lflag = termios->c_lflag;
	v.c_line = termios->c_line;

	canon = v.c_lflag & ICANON;
	v.c_cc[_VINTR]  = termios->c_cc[VINTR];
	v.c_cc[_VQUIT]  = termios->c_cc[VQUIT];
	v.c_cc[_VERASE] = termios->c_cc[VERASE];
	v.c_cc[_VKILL]  = termios->c_cc[VKILL];
	v.c_cc[_VEOF]   = termios->c_cc[canon ? VEOF : VMIN];
	v.c_cc[_VEOL]   = termios->c_cc[canon ? VEOL : VTIME];
	v.c_cc[_VEOL2]  = termios->c_cc[VEOL2];
	v.c_cc[_VSWTC]  = termios->c_cc[VSWTC];

	return copy_to_user(termio, &v, sizeof(struct termio));
}
+6 −35
Original line number Diff line number Diff line
@@ -19,40 +19,11 @@
*/
#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"

/*
 * Translate a "termio" structure into a "termios". Ugh.
 */
#define SET_LOW_TERMIOS_BITS(termios, termio, x) {	\
	unsigned short __tmp;				\
	get_user(__tmp,&(termio)->x);			\
	*(unsigned short *) &(termios)->x = __tmp;	\
}

#define user_termio_to_kernel_termios(termios, termio)		\
({								\
	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag);		\
	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag);		\
	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag);		\
	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag);		\
	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC);	\
})

/*
 * Translate a "termios" structure into a "termio". Ugh.
 */
#define kernel_termios_to_user_termio(termio, termios)		\
({								\
	put_user((termios)->c_iflag, &(termio)->c_iflag);	\
	put_user((termios)->c_oflag, &(termio)->c_oflag);	\
	put_user((termios)->c_cflag, &(termio)->c_cflag);	\
	put_user((termios)->c_lflag, &(termio)->c_lflag);	\
	put_user((termios)->c_line,  &(termio)->c_line);	\
	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC);	\
})

#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
int user_termio_to_kernel_termios(struct ktermios *, struct termio __user *);
int kernel_termios_to_user_termio(struct termio __user *, struct ktermios *);
int user_termios_to_kernel_termios(struct ktermios *, struct termios2 __user *);
int kernel_termios_to_user_termios(struct termios2 __user *, struct ktermios *);
int user_termios_to_kernel_termios_1(struct ktermios *, struct termios __user *);
int kernel_termios_to_user_termios_1(struct termios __user *, struct ktermios *);

#endif /* _ASM_IA64_TERMIOS_H */
+6 −78
Original line number Diff line number Diff line
@@ -23,83 +23,11 @@

#include <linux/string.h>

/*
 * Translate a "termio" structure into a "termios". Ugh.
 */
static inline int user_termio_to_kernel_termios(struct ktermios *termios,
	struct termio __user *termio)
{
	unsigned short iflag, oflag, cflag, lflag;
	unsigned int err;

	if (!access_ok(termio, sizeof(struct termio)))
		return -EFAULT;

	err = __get_user(iflag, &termio->c_iflag);
	termios->c_iflag = (termios->c_iflag & 0xffff0000) | iflag;
	err |=__get_user(oflag, &termio->c_oflag);
	termios->c_oflag = (termios->c_oflag & 0xffff0000) | oflag;
	err |=__get_user(cflag, &termio->c_cflag);
	termios->c_cflag = (termios->c_cflag & 0xffff0000) | cflag;
	err |=__get_user(lflag, &termio->c_lflag);
	termios->c_lflag = (termios->c_lflag & 0xffff0000) | lflag;
	err |=__get_user(termios->c_line, &termio->c_line);
	if (err)
		return -EFAULT;

	if (__copy_from_user(termios->c_cc, termio->c_cc, NCC))
		return -EFAULT;

	return 0;
}

/*
 * Translate a "termios" structure into a "termio". Ugh.
 */
static inline int kernel_termios_to_user_termio(struct termio __user *termio,
	struct ktermios *termios)
{
	int err;

	if (!access_ok(termio, sizeof(struct termio)))
		return -EFAULT;

	err = __put_user(termios->c_iflag, &termio->c_iflag);
	err |= __put_user(termios->c_oflag, &termio->c_oflag);
	err |= __put_user(termios->c_cflag, &termio->c_cflag);
	err |= __put_user(termios->c_lflag, &termio->c_lflag);
	err |= __put_user(termios->c_line, &termio->c_line);
	if (err)
		return -EFAULT;

	if (__copy_to_user(termio->c_cc, termios->c_cc, NCC))
		return -EFAULT;

	return 0;
}

static inline int user_termios_to_kernel_termios(struct ktermios __user *k,
	struct termios2 *u)
{
	return copy_from_user(k, u, sizeof(struct termios2)) ? -EFAULT : 0;
}

static inline int kernel_termios_to_user_termios(struct termios2 __user *u,
	struct ktermios *k)
{
	return copy_to_user(u, k, sizeof(struct termios2)) ? -EFAULT : 0;
}

static inline int user_termios_to_kernel_termios_1(struct ktermios *k,
	struct termios __user *u)
{
	return copy_from_user(k, u, sizeof(struct termios)) ? -EFAULT : 0;
}

static inline int kernel_termios_to_user_termios_1(struct termios __user *u,
	struct ktermios *k)
{
	return copy_to_user(u, k, sizeof(struct termios)) ? -EFAULT : 0;
}
int user_termio_to_kernel_termios(struct ktermios *, struct termio __user *);
int kernel_termios_to_user_termio(struct termio __user *, struct ktermios *);
int user_termios_to_kernel_termios(struct ktermios *, struct termios2 __user *);
int kernel_termios_to_user_termios(struct termios2 __user *, struct ktermios *);
int user_termios_to_kernel_termios_1(struct ktermios *, struct termios __user *);
int kernel_termios_to_user_termios_1(struct termios __user *, struct ktermios *);

#endif /* _ASM_TERMIOS_H */
Loading