Skip to content

Commit 071b24b

Browse files
committed
Input: fix regression when re-registering input handlers
Commit d469647 ("Input: simplify event handling logic") introduced code that would set handler->events() method to either input_handler_events_filter() or input_handler_events_default() or input_handler_events_null(), depending on the kind of input handler (a filter or a regular one) we are dealing with. Unfortunately this breaks cases when we try to re-register the same filter (as is the case with sysrq handler): after initial registration the handler will have 2 event handling methods defined, and will run afoul of the check in input_handler_check_methods(): input: input_handler_check_methods: only one event processing method can be defined (sysrq) sysrq: Failed to register input handler, error -22 Fix this by adding handle_events() method to input_handle structure and setting it up when registering a new input handle according to event handling methods defined in associated input_handler structure, thus avoiding modifying the input_handler structure. Reported-by: "Ned T. Crigler" <crigler@gmail.com> Reported-by: Christian Heusel <christian@heusel.eu> Tested-by: "Ned T. Crigler" <crigler@gmail.com> Tested-by: Peter Seiderer <ps.report@gmx.net> Fixes: d469647 ("Input: simplify event handling logic") Link: https://lore.kernel.org/r/Zx2iQp6csn42PJA7@xavtug Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
1 parent 2860586 commit 071b24b

File tree

2 files changed

+82
-62
lines changed

2 files changed

+82
-62
lines changed

drivers/input/input.c

Lines changed: 73 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,12 @@ static void input_pass_values(struct input_dev *dev,
119119

120120
handle = rcu_dereference(dev->grab);
121121
if (handle) {
122-
count = handle->handler->events(handle, vals, count);
122+
count = handle->handle_events(handle, vals, count);
123123
} else {
124124
list_for_each_entry_rcu(handle, &dev->h_list, d_node)
125125
if (handle->open) {
126-
count = handle->handler->events(handle, vals,
127-
count);
126+
count = handle->handle_events(handle, vals,
127+
count);
128128
if (!count)
129129
break;
130130
}
@@ -2537,57 +2537,6 @@ static int input_handler_check_methods(const struct input_handler *handler)
25372537
return 0;
25382538
}
25392539

2540-
/*
2541-
* An implementation of input_handler's events() method that simply
2542-
* invokes handler->event() method for each event one by one.
2543-
*/
2544-
static unsigned int input_handler_events_default(struct input_handle *handle,
2545-
struct input_value *vals,
2546-
unsigned int count)
2547-
{
2548-
struct input_handler *handler = handle->handler;
2549-
struct input_value *v;
2550-
2551-
for (v = vals; v != vals + count; v++)
2552-
handler->event(handle, v->type, v->code, v->value);
2553-
2554-
return count;
2555-
}
2556-
2557-
/*
2558-
* An implementation of input_handler's events() method that invokes
2559-
* handler->filter() method for each event one by one and removes events
2560-
* that were filtered out from the "vals" array.
2561-
*/
2562-
static unsigned int input_handler_events_filter(struct input_handle *handle,
2563-
struct input_value *vals,
2564-
unsigned int count)
2565-
{
2566-
struct input_handler *handler = handle->handler;
2567-
struct input_value *end = vals;
2568-
struct input_value *v;
2569-
2570-
for (v = vals; v != vals + count; v++) {
2571-
if (handler->filter(handle, v->type, v->code, v->value))
2572-
continue;
2573-
if (end != v)
2574-
*end = *v;
2575-
end++;
2576-
}
2577-
2578-
return end - vals;
2579-
}
2580-
2581-
/*
2582-
* An implementation of input_handler's events() method that does nothing.
2583-
*/
2584-
static unsigned int input_handler_events_null(struct input_handle *handle,
2585-
struct input_value *vals,
2586-
unsigned int count)
2587-
{
2588-
return count;
2589-
}
2590-
25912540
/**
25922541
* input_register_handler - register a new input handler
25932542
* @handler: handler to be registered
@@ -2607,13 +2556,6 @@ int input_register_handler(struct input_handler *handler)
26072556

26082557
INIT_LIST_HEAD(&handler->h_list);
26092558

2610-
if (handler->filter)
2611-
handler->events = input_handler_events_filter;
2612-
else if (handler->event)
2613-
handler->events = input_handler_events_default;
2614-
else if (!handler->events)
2615-
handler->events = input_handler_events_null;
2616-
26172559
error = mutex_lock_interruptible(&input_mutex);
26182560
if (error)
26192561
return error;
@@ -2687,6 +2629,75 @@ int input_handler_for_each_handle(struct input_handler *handler, void *data,
26872629
}
26882630
EXPORT_SYMBOL(input_handler_for_each_handle);
26892631

2632+
/*
2633+
* An implementation of input_handle's handle_events() method that simply
2634+
* invokes handler->event() method for each event one by one.
2635+
*/
2636+
static unsigned int input_handle_events_default(struct input_handle *handle,
2637+
struct input_value *vals,
2638+
unsigned int count)
2639+
{
2640+
struct input_handler *handler = handle->handler;
2641+
struct input_value *v;
2642+
2643+
for (v = vals; v != vals + count; v++)
2644+
handler->event(handle, v->type, v->code, v->value);
2645+
2646+
return count;
2647+
}
2648+
2649+
/*
2650+
* An implementation of input_handle's handle_events() method that invokes
2651+
* handler->filter() method for each event one by one and removes events
2652+
* that were filtered out from the "vals" array.
2653+
*/
2654+
static unsigned int input_handle_events_filter(struct input_handle *handle,
2655+
struct input_value *vals,
2656+
unsigned int count)
2657+
{
2658+
struct input_handler *handler = handle->handler;
2659+
struct input_value *end = vals;
2660+
struct input_value *v;
2661+
2662+
for (v = vals; v != vals + count; v++) {
2663+
if (handler->filter(handle, v->type, v->code, v->value))
2664+
continue;
2665+
if (end != v)
2666+
*end = *v;
2667+
end++;
2668+
}
2669+
2670+
return end - vals;
2671+
}
2672+
2673+
/*
2674+
* An implementation of input_handle's handle_events() method that does nothing.
2675+
*/
2676+
static unsigned int input_handle_events_null(struct input_handle *handle,
2677+
struct input_value *vals,
2678+
unsigned int count)
2679+
{
2680+
return count;
2681+
}
2682+
2683+
/*
2684+
* Sets up appropriate handle->event_handler based on the input_handler
2685+
* associated with the handle.
2686+
*/
2687+
static void input_handle_setup_event_handler(struct input_handle *handle)
2688+
{
2689+
struct input_handler *handler = handle->handler;
2690+
2691+
if (handler->filter)
2692+
handle->handle_events = input_handle_events_filter;
2693+
else if (handler->event)
2694+
handle->handle_events = input_handle_events_default;
2695+
else if (handler->events)
2696+
handle->handle_events = handler->events;
2697+
else
2698+
handle->handle_events = input_handle_events_null;
2699+
}
2700+
26902701
/**
26912702
* input_register_handle - register a new input handle
26922703
* @handle: handle to register
@@ -2704,6 +2715,7 @@ int input_register_handle(struct input_handle *handle)
27042715
struct input_dev *dev = handle->dev;
27052716
int error;
27062717

2718+
input_handle_setup_event_handler(handle);
27072719
/*
27082720
* We take dev->mutex here to prevent race with
27092721
* input_release_device().

include/linux/input.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,16 @@ struct input_handler {
339339
* @name: name given to the handle by handler that created it
340340
* @dev: input device the handle is attached to
341341
* @handler: handler that works with the device through this handle
342+
* @handle_events: event sequence handler. It is set up by the input core
343+
* according to event handling method specified in the @handler. See
344+
* input_handle_setup_event_handler().
345+
* This method is being called by the input core with interrupts disabled
346+
* and dev->event_lock spinlock held and so it may not sleep.
342347
* @d_node: used to put the handle on device's list of attached handles
343348
* @h_node: used to put the handle on handler's list of handles from which
344349
* it gets events
345350
*/
346351
struct input_handle {
347-
348352
void *private;
349353

350354
int open;
@@ -353,6 +357,10 @@ struct input_handle {
353357
struct input_dev *dev;
354358
struct input_handler *handler;
355359

360+
unsigned int (*handle_events)(struct input_handle *handle,
361+
struct input_value *vals,
362+
unsigned int count);
363+
356364
struct list_head d_node;
357365
struct list_head h_node;
358366
};

0 commit comments

Comments
 (0)