FAILED: patch "[PATCH] counter: 104-quad-8: Fix race getting function mode and" failed to apply to 5.4-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
Possible dependencies:
d501d37841d3 ("counter: 104-quad-8: Fix race getting function mode and direction") aea8334b24fe ("counter: 104-quad-8: Convert to counter_priv() wrapper") 7aa2ba0df651 ("counter: 104-quad-8: Add IRQ support for the ACCES 104-QUAD-8") 09db4678bfbb ("counter: 104-quad-8: Replace mutex with spinlock")aaec1a0f76ec ("counter: Internalize sysfs interface code")ea434ff82649 ("counter: stm32-timer-cnt: Provide defines for slave mode selection") 05593a3fd103 ("counter: stm32-lptimer-cnt: Provide defines for clock polarities") 394a0150a064 ("counter: Rename counter_count_function to counter_function") 493b938a14ed ("counter: Rename counter_signal_value to counter_signal_level") b11eed1554e8 ("counter: Return error code on invalid modes")728246e8f726 ("counter: 104-quad-8: Return error when invalid mode during ceiling_write") d0ce3d5cf77d ("counter: stm32-timer-cnt: Add const qualifier for actions_list array") f83e6e59366b ("counter: stm32-lptimer-cnt: Add const qualifier for actions_list array") 0056a405c7ad ("counter: microchip-tcb-capture: Add const qualifier for actions_list array") 9b2574f61c49 ("counter: ftm-quaddec: Add const qualifier for actions_list array") 6a9eb0e31044 ("counter: 104-quad-8: Add const qualifier for actions_list array") 45af9ae84c60 ("counter: stm32-timer-cnt: Add const qualifier for functions_list array") 8a00fed665ad ("counter: stm32-lptimer-cnt: Add const qualifier for functions_list array") 7e0dcfcefeca ("counter: microchip-tcb-capture: Add const qualifier for functions_list array") 891b58b35fd6 ("counter: interrupt-cnt: Add const qualifier for functions_list array")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From d501d37841d3b7f18402d71a9ef057eb9dde127e Mon Sep 17 00:00:00 2001
From: William Breathitt Gray <[email protected]>
Date: Thu, 20 Oct 2022 10:11:21 -0400
Subject: [PATCH] counter: 104-quad-8: Fix race getting function mode and
direction
The quad8_action_read() function checks the Count function mode and Count direction without first acquiring a lock. This is a race condition because the function mode could change by the time the direction is checked.
Because the quad8_function_read() already acquires a lock internally, the quad8_function_read() is refactored to spin out the no-lock code to a new quad8_function_get() function.
To resolve the race condition in quad8_action_read(), a lock is acquired before calling quad8_function_get() and quad8_direction_read() in order to get both function mode and direction atomically.
drivers/counter/104-quad-8.c +42 -22
@@ -232,34 +232,45 @@ static const enum counter_function quad8_count_functions_list[] = { COUNTER_FUNCTION_QUADRATURE_X4, }; +static int quad8_function_get (const struct quad8 *const priv,const size_t id, +enum counter_function *const function) +{ +if (!priv->quadrature_mode[id]) { + *function =COUNTER_FUNCTION_PULSE_DIRECTION ; +return 0 ; + } + +switch (priv->quadrature_scale[id]) { +case 0 : + *function =COUNTER_FUNCTION_QUADRATURE_X1_A ; +return 0 ; +case 1 : + *function =COUNTER_FUNCTION_QUADRATURE_X2_A ; +return 0 ; +case 2 : + *function =COUNTER_FUNCTION_QUADRATURE_X4 ; +return 0 ; +default : +/* should never reach this path */ +return -EINVAL ; + } +} +static int quad8_function_read (struct counter_device *counter,struct counter_count *count,enum counter_function *function) {struct quad8 *const priv =counter_priv (counter); -const int id = count->id;unsigned long irqflags; +int retval;spin_lock_irqsave (&priv->lock, irqflags); -if (priv->quadrature_mode[id]) -switch (priv->quadrature_scale[id]) { -case 0 : - *function =COUNTER_FUNCTION_QUADRATURE_X1_A ; -break ; -case 1 : - *function =COUNTER_FUNCTION_QUADRATURE_X2_A ; -break ; -case 2 : - *function =COUNTER_FUNCTION_QUADRATURE_X4 ; -break ; - } -else - *function =COUNTER_FUNCTION_PULSE_DIRECTION ; + retval =quad8_function_get (priv, count->id, function);spin_unlock_irqrestore (&priv->lock, irqflags); -return 0 ; +return retval; } static int quad8_function_write(struct counter_device *counter,
@@ -359,6 +370,7 @@ static int quad8_action_read(struct counter_device *counter, enum counter_synapse_action *action) {struct quad8 *const priv =counter_priv (counter); +unsigned long irqflags;int err;enum counter_function function;const size_t signal_a_id = count->synapses[0 ].signal->id;
@@ -374,9 +386,21 @@ static int quad8_action_read(struct counter_device *counter,return 0 ; } - err =quad8_function_read (counter, count, &function); -if (err) +spin_lock_irqsave (&priv->lock, irqflags); + +/* Get Count function and direction atomically */ + err =quad8_function_get (priv, count->id, &function); +if (err) { +spin_unlock_irqrestore (&priv->lock, irqflags); +return err; + } + err =quad8_direction_read (counter, count, &direction); +if (err) { +spin_unlock_irqrestore (&priv->lock, irqflags);return err; + } + +spin_unlock_irqrestore (&priv->lock, irqflags);/* Default action mode */ *action =COUNTER_SYNAPSE_ACTION_NONE ;
@@ -389,10 +413,6 @@ static int quad8_action_read(struct counter_device *counter,return 0 ;case COUNTER_FUNCTION_QUADRATURE_X1_A :if (synapse->signal->id == signal_a_id) { - err =quad8_direction_read (counter, count, &direction); -if (err) -return err; -if (direction ==COUNTER_COUNT_DIRECTION_FORWARD ) *action =COUNTER_SYNAPSE_ACTION_RISING_EDGE ;else