From patchwork Wed Jan 9 03:50:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Hutterer X-Patchwork-Id: 10753391 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4FC23746 for ; Wed, 9 Jan 2019 03:50:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2DBB328DCC for ; Wed, 9 Jan 2019 03:50:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 21B9428DCE; Wed, 9 Jan 2019 03:50:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7985D28DCC for ; Wed, 9 Jan 2019 03:50:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727857AbfAIDuX (ORCPT ); Tue, 8 Jan 2019 22:50:23 -0500 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:52063 "EHLO out1-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727828AbfAIDuX (ORCPT ); Tue, 8 Jan 2019 22:50:23 -0500 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id 15FC12548F; Tue, 8 Jan 2019 22:50:20 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Tue, 08 Jan 2019 22:50:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=who-t.net; h= date:from:to:cc:subject:message-id:mime-version:content-type :in-reply-to; s=fm2; bh=O9xAKDuL/5m4z0FqZ89JAAi+LBUjo7gO4Mnfhwco yjI=; b=sUKefwVUPqKdW7AGussJvU8BDdRQVwQgmMqtFuCxWdc7vJvTLxpkPJU9 BBQ0BAtgGkbjzP7GS85IaevA9XCZIQDWCraAY6IqzUm48/xQH0OX90W9egIc1I7w N12UfXO0hUkFWMUrJlAhYJjfJgYn1rL3OESEaO9H2OoW/gd60D47sGRvoAFNsZqF 27WIiTy+1RNGzmcxdDq0GyQVM6OChRmDrvL9qc8exGl4t4sfUxGkvO6+vQm/D0JL /Ypkzno6G4QKiLYr4/EKGM1jgTnGGuE5nHTEfor1HEFWWcK/BVaF79oQKNcJg5xX ahs+T++5UDmPx9/E6nNGpos+6qZ6Fg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:subject:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=O9xAKDuL/5m4z0FqZ 89JAAi+LBUjo7gO4MnfhwcoyjI=; b=sNx16UJNbtbeufvBuQegBKT9xVDExI2n+ ZuHkdd7ptYeus0pbNGywBYol8BbwG/SDHu97tJv+SLWiJdDFbeG2SoJoWmUvJHHK fLy+7Z1C/5POF7gU4f2csjAF7UBJqsH28iqYwcnTxRYzsI3KSYYp2fmXn1uTwUD/ DbAx2CTSYSBLVIZc/QjqVEGcJUuM7YTCXEaRD50p+5LYfvjz9oJ7KchpAfD0tfoI 0eAus9rRZzpvXu+BMxQhJUq+B+aaPyiSLTHaTvb08yrvuyKyQBd8PDW1Vna8lVty uCMAVsIRsNrn484lna7nlYrB+cXTEEgo6Fv9wL8CxOcS0pD+xWz5w== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedtledrfedtgdeiieculddtuddrgedtkedrtddtmd cutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfhuthen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvffukfggtggujggfsehttdertddtredvnecuhfhrohhmpefrvghtvghr ucfjuhhtthgvrhgvrhcuoehpvghtvghrrdhhuhhtthgvrhgvrhesfihhohdqthdrnhgvth eqnecukfhppeduieejrddujeelrdduieeirddvleenucfrrghrrghmpehmrghilhhfrhho mhepphgvthgvrhdrhhhuthhtvghrvghrseifhhhoqdhtrdhnvghtnecuvehluhhsthgvrh fuihiivgeptd X-ME-Proxy: Received: from jelly (167-179-166-29.a7b3a6.bne.nbn.aussiebb.net [167.179.166.29]) by mail.messagingengine.com (Postfix) with ESMTPA id 9E1CE100E5; Tue, 8 Jan 2019 22:50:16 -0500 (EST) Date: Wed, 9 Jan 2019 13:50:18 +1000 From: Peter Hutterer To: "Pandruvada, Srinivas" Cc: "linux-input@vger.kernel.org" , "srinivas.pandruvada@linux.intel.com" , "benjamin.tissoires@redhat.com" , "Song, Hongyan" , "Xu, Even" , "jkosina@suse.cz" , "Pelton, Kyle D" Subject: [PATCH] HID: core: replace the collection tree pointers with indices Message-ID: <20190109035018.GA12679@jelly> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <2f514df549c828a9828a09a3addef7d7dee8f47f.camel@intel.com> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Introduced in c53431eb696f3c64c12c00afb81048af54b61532 "HID: core: store the collections as a basic tree". Previously, the pointer to the parent collection was stored. If a device exceeds 16 collections (HID_DEFAULT_NUM_COLLECTIONS), the array to store the collections is reallocated, the pointer to the parent collection becomes invalid. Replace the pointers with an index-based lookup into the collections array. Reported-by: Pandruvada, Srinivas Signed-off-by: Peter Hutterer --- I have a test locally for hid-tools now but it relies on the kernel crashing, so it's going to generate false positives. I verified the test with printks though. drivers/hid/hid-core.c | 32 +++++++++++++++++++++----------- include/linux/hid.h | 4 ++-- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f41d5fe51abe..f9093dedf647 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -125,6 +125,7 @@ static int open_collection(struct hid_parser *parser, unsigned type) { struct hid_collection *collection; unsigned usage; + int collection_index; usage = parser->local.usage[0]; @@ -167,13 +168,13 @@ static int open_collection(struct hid_parser *parser, unsigned type) parser->collection_stack[parser->collection_stack_ptr++] = parser->device->maxcollection; - collection = parser->device->collection + - parser->device->maxcollection++; + collection_index = parser->device->maxcollection++; + collection = parser->device->collection + collection_index; collection->type = type; collection->usage = usage; collection->level = parser->collection_stack_ptr - 1; - collection->parent = parser->active_collection; - parser->active_collection = collection; + collection->parent_idx = parser->active_collection_idx; + parser->active_collection_idx = collection_index; if (type == HID_COLLECTION_APPLICATION) parser->device->maxapplication++; @@ -192,8 +193,13 @@ static int close_collection(struct hid_parser *parser) return -EINVAL; } parser->collection_stack_ptr--; - if (parser->active_collection) - parser->active_collection = parser->active_collection->parent; + if (parser->active_collection_idx != -1) { + struct hid_device *device = parser->device; + struct hid_collection *c; + + c = &device->collection[parser->active_collection_idx]; + parser->active_collection_idx = c->parent_idx; + } return 0; } @@ -819,6 +825,7 @@ static int hid_scan_report(struct hid_device *hid) return -ENOMEM; parser->device = hid; + parser->active_collection_idx = -1; hid->group = HID_GROUP_GENERIC; /* @@ -1006,10 +1013,12 @@ static void hid_apply_multiplier_to_field(struct hid_device *hid, usage = &field->usage[i]; collection = &hid->collection[usage->collection_index]; - while (collection && collection != multiplier_collection) - collection = collection->parent; + while (collection->parent_idx != -1 && + collection != multiplier_collection) + collection = &hid->collection[collection->parent_idx]; - if (collection || multiplier_collection == NULL) + if (collection->parent_idx != -1 || + multiplier_collection == NULL) usage->resolution_multiplier = effective_multiplier; } @@ -1044,9 +1053,9 @@ static void hid_apply_multiplier(struct hid_device *hid, * applicable fields later. */ multiplier_collection = &hid->collection[multiplier->usage->collection_index]; - while (multiplier_collection && + while (multiplier_collection->parent_idx != -1 && multiplier_collection->type != HID_COLLECTION_LOGICAL) - multiplier_collection = multiplier_collection->parent; + multiplier_collection = &hid->collection[multiplier_collection->parent_idx]; effective_multiplier = hid_calculate_multiplier(hid, multiplier); @@ -1170,6 +1179,7 @@ int hid_open_report(struct hid_device *device) } parser->device = device; + parser->active_collection_idx = -1; end = start + size; diff --git a/include/linux/hid.h b/include/linux/hid.h index 93db548f8761..554e82d812da 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -429,7 +429,7 @@ struct hid_local { */ struct hid_collection { - struct hid_collection *parent; + int parent_idx; /* device->collection */ unsigned type; unsigned usage; unsigned level; @@ -657,7 +657,7 @@ struct hid_parser { unsigned int *collection_stack; unsigned int collection_stack_ptr; unsigned int collection_stack_size; - struct hid_collection *active_collection; + int active_collection_idx; /* device->collection */ struct hid_device *device; unsigned int scan_flags; };