Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp13387307ybl; Sun, 29 Dec 2019 10:39:51 -0800 (PST) X-Google-Smtp-Source: APXvYqxBPkikgRHZCyaOJSrbSCFLpua5bftLckM86m0V0BjGYP25Yxx/+TFPm2v6rqiXh/lcKHXS X-Received: by 2002:a9d:da2:: with SMTP id 31mr67129534ots.319.1577644791287; Sun, 29 Dec 2019 10:39:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1577644791; cv=none; d=google.com; s=arc-20160816; b=e6+McaXRLVVyFfdL+FyyNnGh6/CFtLty+Yp6cidg0TVGMSvR1lEjC/AMq4zzQyM93h VqF0zklcwkvygAx1u92OTCk0xnedANG0is9oxd1wAr4jGbECEvEdQYZU1/HDd11loHnc DI/m9I5lowlgm9t5zXa1AeyFVtDaE4y8lXE91C0kdu3+oBFFVBr7V2RQbUadkKYbop00 plDVm//aCmj3vyRgkc+7UvPSKIkcHg80dMeZQCeaBsOsH/RBJCXp24SWC6eddG0CgEqX E9GZdgSdLmMhsIEpKbB2Z4d++dSl+5cXGZtchCxuSLhepPLDv9TTj1QW9351qnzRx5zj 6nzg== 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=v+m4SsRtY427ySCEMnNmdWq1tnmCzlA4IZBTRZuCaXg=; b=CsBqaea9KGCAJNIlSaN8Pl8EwF+9/dIInXejmO8IZkBHSyrFZ0oPlSyPfxvJHGQSRZ cgGpn5qI7afuQXDt8Uh5T95/NJ8+X/znVbGdUNSMGGty9fGtqQGMcYSCxLvE0/5xMXrZ XVw/G3RVWgpBpYMbAb77QdqxDLFJNWrs8ork+OJNJn8Qf6TKvPotDZVO1WqPrpT0EZE8 dF3HhBYzFhezZKoHqu68gL3UwJfcyucKghZR8xjtriIMzKQ/DIKCojNRhMTQKUnOYRkg illFBljjkHap3a106gZBeE1+ZnjDp7+A9g9c9YG8juS/vM6AnYKStZZj55tTi/DHyVYJ HRVA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="a/rYRTn8"; 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 h13si15399067otk.291.2019.12.29.10.39.40; Sun, 29 Dec 2019 10:39:51 -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="a/rYRTn8"; 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 S1727599AbfL2RZU (ORCPT + 99 others); Sun, 29 Dec 2019 12:25:20 -0500 Received: from mail.kernel.org ([198.145.29.99]:44976 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727423AbfL2RZS (ORCPT ); Sun, 29 Dec 2019 12:25:18 -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 9468E207FD; Sun, 29 Dec 2019 17:25:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1577640318; bh=CcqVOzCJUCjmArfNzVBqeAf0Sqnu5j4gjsL2BCfwo10=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a/rYRTn8qXQIv6uDM3V2e3ZPn8NdydAT7PjqVZPSnx45v9H6Kd0XK0B/DUTbvKt67 bOqVy3Rjg5R44kNoCLqXGeDD/tQDuGKvUuq1EIFgOI0ny/LO1sX9B4MFLEqvSAarnW pwX0xvgSOYltdnlE4pIpdoYzvRfnDdEGCPFPemt4= 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.14 108/161] fsi: core: Fix small accesses and unaligned offsets via sysfs Date: Sun, 29 Dec 2019 18:19:16 +0100 Message-Id: <20191229162429.484622923@linuxfoundation.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20191229162355.500086350@linuxfoundation.org> References: <20191229162355.500086350@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 4ea63d9bd131..8feca59c1f6b 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -419,6 +419,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) @@ -434,8 +459,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) @@ -462,8 +486,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