mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-25 02:48:21 +00:00
e5f5d0e20b
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 <okash.khawaja@gmail.com> Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
||
---|---|---|
.. | ||
buffers.c | ||
DefaultKeyAssignments | ||
devsynth.c | ||
fakekey.c | ||
i18n.c | ||
i18n.h | ||
Kconfig | ||
keyhelp.c | ||
kobjects.c | ||
main.c | ||
Makefile | ||
selection.c | ||
serialio.c | ||
serialio.h | ||
speakup_acnt.h | ||
speakup_acntpc.c | ||
speakup_acntsa.c | ||
speakup_apollo.c | ||
speakup_audptr.c | ||
speakup_bns.c | ||
speakup_decext.c | ||
speakup_decpc.c | ||
speakup_dectlk.c | ||
speakup_dtlk.c | ||
speakup_dtlk.h | ||
speakup_dummy.c | ||
speakup_keypc.c | ||
speakup_ltlk.c | ||
speakup_soft.c | ||
speakup_spkout.c | ||
speakup_txprt.c | ||
speakup.h | ||
speakupmap.h | ||
speakupmap.map | ||
spk_priv_keyinfo.h | ||
spk_priv.h | ||
spk_ttyio.c | ||
spk_types.h | ||
spkguide.txt | ||
synth.c | ||
thread.c | ||
TODO | ||
varhandlers.c |