Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp13336590ybl; Sun, 29 Dec 2019 09:34:43 -0800 (PST) X-Google-Smtp-Source: APXvYqwbUcv+VNGViv3i1OPtVuV5Hb1gAjcGSmsPPoEEEXltuw+rHuzgYS5gkuAHAX23t55uv4yK X-Received: by 2002:a9d:6183:: with SMTP id g3mr70065160otk.304.1577640883072; Sun, 29 Dec 2019 09:34:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1577640883; cv=none; d=google.com; s=arc-20160816; b=lLdRinRVp0BEmso8VSHvw3ezQMuR8ImIJ+Yao7DePp8vo7WJz3V8dN0EMXNbzfqAaQ g3BSp1vGmDIpH+mv7qytgXGYWxuJ6X5Wa5ajgMVlijnRWCt9Q/bzTgwZp5QPRuWKfEFN DqcXH46dlUlQxWJv3Ywkh9v2abyxsDreQsWxmyxy7jqY0s1EklmGf4ueY6zzA3g3bL5p 6UWbG/e4oD7+La3mu3E5S6NADhpuOLwZFHWHABjTWBb2ta0y9tbTU5rJxCfJPT8XWjZr vX0e/QlK+9MLtF6HtRiZJvo0qrVe3wWUuc34tTNKHdAzBWrN41UgVJNVFdpaeEhT3/ca rjFw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=qiqqb2+TCh9wwJIIzMRvtXBXDSJOVJHi3yP7nb/NtXY=; b=KYSiJ8MZ/J3FuLc8/WRxTDNjL7Gd7nz31ZC1Gh5+/qeXKG8G8MMcdIj/5gSyh5mH3Y 4UETpRQKHot4e4/PIH8ZexryTVdEybExnq9M9ZmscUUJShujMFGZj4pObdh01W4+YM1c boVYEwCKCe+tVtHXh5RSkHlafszSNdLAZqjcLjmlUQXyXZ+dGntBU/DpOp1zDdK6f8Hg 6TPksayDOX3T41O8VEiZHHQpCveWkUqF3Vam+tDCprJQ2U928e+Frr85TKmUqAE2p/O+ wq9N9yJRbsrS3xnncIswscF82FfRM6jt2A4AZenjlHrXTB1p7NGXl0qId5H1FX8JSleo IHJA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=dOG6mSa4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v21si26029865otf.87.2019.12.29.09.34.32; Sun, 29 Dec 2019 09:34:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=dOG6mSa4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729166AbfL2Rd2 (ORCPT + 99 others); Sun, 29 Dec 2019 12:33:28 -0500 Received: from mail.kernel.org ([198.145.29.99]:34744 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729212AbfL2RdR (ORCPT ); Sun, 29 Dec 2019 12:33:17 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D8A90208E4; Sun, 29 Dec 2019 17:33:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1577640796; bh=K6kZh//plddoKE+Bou1hDAi2n+hfq3aeQAM/6bUceWg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dOG6mSa4AMMYuxKrXyAvlEkGQG9eMohmiqYBA3LlCE+PMYdLTUfktCdgxBOM63d65 oNpU7D3UoYjeHFm/qxe3WpvtQwRQfjZyPqmDwId/8d1CNIyp6LdhPm2NEpWZdXaJUd H3LaorSkgmDRGrRgodaJfLwK3tJz3KpxL/14VoFk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Andrew Jeffery , Joel Stanley , Sasha Levin Subject: [PATCH 4.19 143/219] fsi: core: Fix small accesses and unaligned offsets via sysfs Date: Sun, 29 Dec 2019 18:19:05 +0100 Message-Id: <20191229162530.042562527@linuxfoundation.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20191229162508.458551679@linuxfoundation.org> References: <20191229162508.458551679@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Andrew Jeffery [ Upstream commit 9f4c2b516b4f031e3cd0e45957f4150b3c1a083d ] Subtracting the offset delta from four-byte alignment lead to wrapping of the requested length where `count` is less than `off`. Generalise the length handling to enable and optimise aligned access sizes for all offset and size combinations. The new formula produces the following results for given offset and count values: offset count | length --------------+------- 0 1 | 1 0 2 | 2 0 3 | 2 0 4 | 4 0 5 | 4 1 1 | 1 1 2 | 1 1 3 | 1 1 4 | 1 1 5 | 1 2 1 | 1 2 2 | 2 2 3 | 2 2 4 | 2 2 5 | 2 3 1 | 1 3 2 | 1 3 3 | 1 3 4 | 1 3 5 | 1 We might need something like this for the cfam chardevs as well, for example we don't currently implement any alignment restrictions / handling in the hardware master driver. Signed-off-by: Andrew Jeffery Signed-off-by: Joel Stanley Link: https://lore.kernel.org/r/20191108051945.7109-6-joel@jms.id.au Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/fsi/fsi-core.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 2c31563fdcae..c6fa9b393e84 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -552,6 +552,31 @@ static int fsi_slave_scan(struct fsi_slave *slave) return 0; } +static unsigned long aligned_access_size(size_t offset, size_t count) +{ + unsigned long offset_unit, count_unit; + + /* Criteria: + * + * 1. Access size must be less than or equal to the maximum access + * width or the highest power-of-two factor of offset + * 2. Access size must be less than or equal to the amount specified by + * count + * + * The access width is optimal if we can calculate 1 to be strictly + * equal while still satisfying 2. + */ + + /* Find 1 by the bottom bit of offset (with a 4 byte access cap) */ + offset_unit = BIT(__builtin_ctzl(offset | 4)); + + /* Find 2 by the top bit of count */ + count_unit = BIT(8 * sizeof(unsigned long) - 1 - __builtin_clzl(count)); + + /* Constrain the maximum access width to the minimum of both criteria */ + return BIT(__builtin_ctzl(offset_unit | count_unit)); +} + static ssize_t fsi_slave_sysfs_raw_read(struct file *file, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) @@ -567,8 +592,7 @@ static ssize_t fsi_slave_sysfs_raw_read(struct file *file, return -EINVAL; for (total_len = 0; total_len < count; total_len += read_len) { - read_len = min_t(size_t, count, 4); - read_len -= off & 0x3; + read_len = aligned_access_size(off, count - total_len); rc = fsi_slave_read(slave, off, buf + total_len, read_len); if (rc) @@ -595,8 +619,7 @@ static ssize_t fsi_slave_sysfs_raw_write(struct file *file, return -EINVAL; for (total_len = 0; total_len < count; total_len += write_len) { - write_len = min_t(size_t, count, 4); - write_len -= off & 0x3; + write_len = aligned_access_size(off, count - total_len); rc = fsi_slave_write(slave, off, buf + total_len, write_len); if (rc) -- 2.20.1