From: Aniroop Mathur Date: Fri, 30 Oct 2015 11:15:37 +0000 (-0700) Subject: Input: evdev - fix bug in checking duplicate clock change request X-Git-Tag: firefly_0821_release~176^2~541^2~15^2 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=bf5f18d708802737fa0db6306f6b9148f85b2efd;p=firefly-linux-kernel-4.4.55.git Input: evdev - fix bug in checking duplicate clock change request clk_type and clkid stores different predefined clock identification values so they cannot be compared for checking duplicate clock change request. Therefore, lets fix it to avoid unexpected results. Signed-off-by: Aniroop Mathur Signed-off-by: Dmitry Torokhov --- diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 6b10f5b29218..e9ae3d500a55 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -56,7 +56,7 @@ struct evdev_client { struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; - int clk_type; + unsigned int clk_type; bool revoked; unsigned long *evmasks[EV_CNT]; unsigned int bufsize; @@ -191,37 +191,39 @@ static void evdev_queue_syn_dropped(struct evdev_client *client) static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) { unsigned long flags; - - if (client->clk_type == clkid) - return 0; + unsigned int clk_type; switch (clkid) { case CLOCK_REALTIME: - client->clk_type = EV_CLK_REAL; + clk_type = EV_CLK_REAL; break; case CLOCK_MONOTONIC: - client->clk_type = EV_CLK_MONO; + clk_type = EV_CLK_MONO; break; case CLOCK_BOOTTIME: - client->clk_type = EV_CLK_BOOT; + clk_type = EV_CLK_BOOT; break; default: return -EINVAL; } - /* - * Flush pending events and queue SYN_DROPPED event, - * but only if the queue is not empty. - */ - spin_lock_irqsave(&client->buffer_lock, flags); + if (client->clk_type != clk_type) { + client->clk_type = clk_type; - if (client->head != client->tail) { - client->packet_head = client->head = client->tail; - __evdev_queue_syn_dropped(client); - } + /* + * Flush pending events and queue SYN_DROPPED event, + * but only if the queue is not empty. + */ + spin_lock_irqsave(&client->buffer_lock, flags); - spin_unlock_irqrestore(&client->buffer_lock, flags); + if (client->head != client->tail) { + client->packet_head = client->head = client->tail; + __evdev_queue_syn_dropped(client); + } + + spin_unlock_irqrestore(&client->buffer_lock, flags); + } return 0; }