Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751047AbdIEKvj (ORCPT ); Tue, 5 Sep 2017 06:51:39 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:33261 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750738AbdIEKve (ORCPT ); Tue, 5 Sep 2017 06:51:34 -0400 X-Google-Smtp-Source: ADKCNb5NnATzrlg3ShLkg8X94vt72hvd4INa8Ev49c6Hhyu/pjvywnZtko5Tj89DEGGsG6AxsFC4Hw== Message-Id: <20170905120512.966890133@gmail.com> User-Agent: quilt/0.65 Date: Tue, 05 Sep 2017 12:51:59 +0100 From: Okash Khawaja To: Greg Kroah-Hartman , Samuel Thibault , linux-kernel@vger.kernel.org Cc: William Hubbs , Chris Brannon , Kirk Reiser , speakup@linux-speakup.org, devel@driverdev.osuosl.org, Okash Khawaja Subject: [patch 1/1] [patch] staging: speakup: fix speakup-r empty line lockup References: <20170905115158.279717403@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Disposition: inline; filename=speakup-r-fix.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2550 Lines: 79 When cursor is at beginning of an empty or whitespace-only line and speakup-r typed, kernel locks up. This happens because deadlock of in input_event function over dev->event_lock, as demonstrated by lockdep logs. The reason for that is speakup simulates a down arrow - because cursor is at an empty line - while inside key press notifier handler which is ultimately triggered from input_event function. The simulated key press leads to input_event being called again, this time under its own context. So the spinlock is dev->event_lock is acquired while still being held. This patch ensures that key press is not simulated from inside key press notifier handler. Instead it delegates to cursor_timer. It starts the timer and passes RA_DOWN_ARROW as argument. When timer handler runs and sees RA_DOWN_ARROW, it will then call kbd_fakekey2(RA_DOWN_ARROW) which will correctly simulate the keypress inside timer context. When not inside key press notifier callback, the behaviour will remain the same as before this patch. Signed-off-by: Okash Khawaja Reviewed-by: Samuel Thibault --- drivers/staging/speakup/main.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -1376,6 +1376,8 @@ static void reset_highlight_buffers(stru static int read_all_key; +static int in_keyboard_notifier; + static void start_read_all_timer(struct vc_data *vc, int command); enum { @@ -1408,7 +1410,10 @@ static void read_all_doc(struct vc_data cursor_track = read_all_mode; spk_reset_index_count(0); if (get_sentence_buf(vc, 0) == -1) { - kbd_fakekey2(vc, RA_DOWN_ARROW); + del_timer(&cursor_timer); + if (!in_keyboard_notifier) + speakup_fake_down_arrow(); + start_read_all_timer(vc, RA_DOWN_ARROW); } else { say_sentence_num(0, 0); synth_insert_next_index(0); @@ -2212,8 +2217,10 @@ static int keyboard_notifier_call(struct int ret = NOTIFY_OK; static int keycode; /* to hold the current keycode */ + in_keyboard_notifier = 1; + if (vc->vc_mode == KD_GRAPHICS) - return ret; + goto out; /* * First, determine whether we are handling a fake keypress on @@ -2225,7 +2232,7 @@ static int keyboard_notifier_call(struct */ if (speakup_fake_key_pressed()) - return ret; + goto out; switch (code) { case KBD_KEYCODE: @@ -2266,6 +2273,8 @@ static int keyboard_notifier_call(struct break; } } +out: + in_keyboard_notifier = 0; return ret; }