From 7d674f9150c361e5b992551b46516d41eede3722 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 11 May 2023 11:52:45 -0700 Subject: [PATCH] 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 --- drivers/input/serio/libps2.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) 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); -- 2.30.2