[PATCH 1/2] Subject: vt: selection: allow functions to be called from inside kernel

Samuel Thibault samuel.thibault at ens-lyon.org
Tue Apr 2 03:18:41 EDT 2019


Okash Khawaja, le ven. 29 mars 2019 11:31:03 +0000, a ecrit:
> This patch breaks set_selection() into two functions so that when
> called from kernel, copy_from_user() can be avoided. It also exports
> set_selection() and paste_selection().
> 
> These changes are used the following patch where speakup's selection
> functionality calls into the above functions, thereby doing away with
> parallel implementation.
> 
> Signed-off-by: Okash Khawaja <okash.khawaja at gmail.com>

Review-by: Samuel Thibault <samuel.thibault at ens-lyon.org>
Tested-by: Gregory Nowak <greg at gregn.net>

> ---
>  drivers/tty/vt/selection.c | 37 ++++++++++++++++++++++++-------------
>  include/linux/selection.h  |  3 +--
>  2 files changed, 25 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c
> index 07496c7..a43f9cd9 100644
> --- a/drivers/tty/vt/selection.c
> +++ b/drivers/tty/vt/selection.c
> @@ -80,6 +80,7 @@ void clear_selection(void)
>  		sel_start = -1;
>  	}
>  }
> +EXPORT_SYMBOL_GPL(clear_selection);
>  
>  /*
>   * User settable table: what characters are to be considered alphabetic?
> @@ -165,33 +166,41 @@ static int store_utf8(u32 c, char *p)
>   */
>  int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty)
>  {
> +	struct tiocl_selection v;
> +
> +	if (copy_from_user(&v, sel, sizeof(*sel)))
> +		return -EFAULT;
> +
> +	return do_set_selection(&v, tty);
> +}
> +
> +int do_set_selection(struct tiocl_selection *v, struct tty_struct *tty)
> +{
>  	struct vc_data *vc = vc_cons[fg_console].d;
>  	int new_sel_start, new_sel_end, spc;
> -	struct tiocl_selection v;
>  	char *bp, *obp;
>  	int i, ps, pe, multiplier;
>  	u32 c;
>  	int mode;
>  
>  	poke_blanked_console();
> -	if (copy_from_user(&v, sel, sizeof(*sel)))
> -		return -EFAULT;
>  
> -	v.xs = min_t(u16, v.xs - 1, vc->vc_cols - 1);
> -	v.ys = min_t(u16, v.ys - 1, vc->vc_rows - 1);
> -	v.xe = min_t(u16, v.xe - 1, vc->vc_cols - 1);
> -	v.ye = min_t(u16, v.ye - 1, vc->vc_rows - 1);
> -	ps = v.ys * vc->vc_size_row + (v.xs << 1);
> -	pe = v.ye * vc->vc_size_row + (v.xe << 1);
> +	v->xs = min_t(u16, v->xs - 1, vc->vc_cols - 1);
> +	v->ys = min_t(u16, v->ys - 1, vc->vc_rows - 1);
> +	v->xe = min_t(u16, v->xe - 1, vc->vc_cols - 1);
> +	v->ye = min_t(u16, v->ye - 1, vc->vc_rows - 1);
> +	ps = v->ys * vc->vc_size_row + (v->xs << 1);
> +	pe = v->ye * vc->vc_size_row + (v->xe << 1);
>  
> -	if (v.sel_mode == TIOCL_SELCLEAR) {
> +	if (v->sel_mode == TIOCL_SELCLEAR) {
>  		/* useful for screendump without selection highlights */
>  		clear_selection();
>  		return 0;
>  	}
>  
> -	if (mouse_reporting() && (v.sel_mode & TIOCL_SELMOUSEREPORT)) {
> -		mouse_report(tty, v.sel_mode & TIOCL_SELBUTTONMASK, v.xs, v.ys);
> +	if (mouse_reporting() && (v->sel_mode & TIOCL_SELMOUSEREPORT)) {
> +		mouse_report(tty, v->sel_mode & TIOCL_SELBUTTONMASK, v->xs,
> +			     v->ys);
>  		return 0;
>  	}
>  
> @@ -208,7 +217,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
>  	else
>  		use_unicode = 0;
>  
> -	switch (v.sel_mode)
> +	switch (v->sel_mode)
>  	{
>  		case TIOCL_SELCHAR:	/* character-by-character selection */
>  			new_sel_start = ps;
> @@ -322,6 +331,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
>  	sel_buffer_lth = bp - sel_buffer;
>  	return 0;
>  }
> +EXPORT_SYMBOL_GPL(do_set_selection);
>  
>  /* Insert the contents of the selection buffer into the
>   * queue of the tty associated with the current console.
> @@ -367,3 +377,4 @@ int paste_selection(struct tty_struct *tty)
>  	tty_ldisc_deref(ld);
>  	return 0;
>  }
> +EXPORT_SYMBOL_GPL(paste_selection);
> diff --git a/include/linux/selection.h b/include/linux/selection.h
> index a8f5b97..171d77d 100644
> --- a/include/linux/selection.h
> +++ b/include/linux/selection.h
> @@ -11,13 +11,12 @@
>  #include <linux/tiocl.h>
>  #include <linux/vt_buffer.h>
>  
> -struct tty_struct;
> -
>  extern struct vc_data *sel_cons;
>  struct tty_struct;
>  
>  extern void clear_selection(void);
>  extern int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty);
> +extern int do_set_selection(struct tiocl_selection *v, struct tty_struct *tty);
>  extern int paste_selection(struct tty_struct *tty);
>  extern int sel_loadlut(char __user *p);
>  extern int mouse_reporting(void);
> -- 
> 1.8.3.1
> 

-- 
Samuel
> X..., c'est un millefeuille avec une couche de crème patissière, une
> de sauce tomate et une de crème d'anchois... Mais c'est vrai que
> c'est un système ouvert: tu peux y rajouter des pépites de chocolat...
-+- Ol in Guide du linuxien pervers - "Remettez m'en une couche !" -+-


More information about the Speakup mailing list