From: Dmitry Torokhov Date: Thu, 11 May 2023 18:52:45 +0000 (-0700) Subject: Input: libps2 - fix aborting PS/2 commands X-Git-Tag: v6.5-rc1~155^2^2~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7d674f9150c361e5b992551b46516d41eede3722;p=thirdparty%2Fkernel%2Flinux.git Input: libps2 - fix aborting PS/2 commands When aborting PS/2 command the kernel should [re]set all flags before waking up waiters, otherwise waiting thread may read obsolete values of flags. Reported-by: Raul Rangel Reviewed-by: Raul E Rangel Link: https://lore.kernel.org/r/20230511185252.386941-6-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 14b70a78875d2..09eb605364bba 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -478,15 +478,22 @@ bool ps2_handle_response(struct ps2dev *ps2dev, u8 data) } EXPORT_SYMBOL(ps2_handle_response); +/* + * Clears state of PS/2 device after communication error by resetting majority + * of flags and waking up waiters, if any. + */ void ps2_cmd_aborted(struct ps2dev *ps2dev) { - if (ps2dev->flags & PS2_FLAG_ACK) + unsigned long old_flags = ps2dev->flags; + + /* reset all flags except last nak */ + ps2dev->flags &= PS2_FLAG_NAK; + + if (old_flags & PS2_FLAG_ACK) ps2dev->nak = 1; - if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD)) + if (old_flags & (PS2_FLAG_ACK | PS2_FLAG_CMD)) wake_up(&ps2dev->wait); - /* reset all flags except last nack */ - ps2dev->flags &= PS2_FLAG_NAK; } EXPORT_SYMBOL(ps2_cmd_aborted);