[PATCH v3 1/2] vt: selection: allow functions to be called from inside kernel
Samuel Thibault
samuel.thibault at ens-lyon.org
Thu Apr 4 07:34:34 EDT 2019
Okash Khawaja, le jeu. 04 avril 2019 10:04:41 +0100, 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>
When resending without changes, you can include my
Reviewed-by: Samuel Thibault <samuel.thibault at ens-lyon.org>
so people know that this part is reviewed already.
> ---
> 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 07496c711d7d..a43f9cd9bdd6 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?
> @@ -164,34 +165,42 @@ static int store_utf8(u32 c, char *p)
> * a lot under the lock but its hardly a performance path
> */
> 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 a8f5b97b216f..171d77dfc825 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);
> --
> 2.21.0
>
--
Samuel
As usual, this being a 1.3.x release, I haven't even compiled this
kernel yet. So if it works, you should be doubly impressed.
(Linus Torvalds, announcing kernel 1.3.3 on the linux-kernel mailing list.)
More information about the Speakup
mailing list