Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp7956imm; Thu, 20 Sep 2018 16:29:12 -0700 (PDT) X-Google-Smtp-Source: ANB0VdaRy9u0q7jU9VH96fYYJya4n3mk4VpMSCu9VVNchmg0v5imZCKXk7G2VByZYFn9Ldf0egre X-Received: by 2002:a63:2906:: with SMTP id p6-v6mr38450207pgp.204.1537486152264; Thu, 20 Sep 2018 16:29:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1537486152; cv=none; d=google.com; s=arc-20160816; b=Zo/EuEOBKu4NIeKPBxCj79K7f4NxvGJ54kAzzr6Z4NkNvUx4A7dEKxI8sDkAhzQj9l +b+IhJjIg4QNlFhNl9w6aJpgkzu8KxWSQOb+tFPrHhiKTozyLwadgXo8i/LcOcDgpW6S VXbjuv1u5fIGRa4Z1x6n1jW9YzT4eOeFjGrs/FZAgQafVBFZnPFe2L5ZJa1n3Ra81DyP QquaokD3qqpepIbaZCCzo4iU5ApdJSI3M1qhczwjbKaY58+eXYdGN+SrHkG5FsIofe2R 3c72ZL4kTvjjwdpf9MTB16ck5nQbn3fI/IqRQbAVaIMaWHdLmurG+AeRJMoM9KXY2BVk QyxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:mime-version :message-id:date:dkim-signature; bh=0eUfEmnxFezrSWKVS8+HPs0FXoxcazz84MXUQZFdxbU=; b=lK3uBoWEo8zCHwPjgLlRJ6jPbKvLpv/2an/Aw5IqychTezjXY6DwlopX+BRgRCTYtD Kgiy0W65CF4SAZhPUqezokyxbEDYIfhNP5cGYWWwCQ8tlUluf2OyBfpHVVgKxJ4hpz9B JJRWwhy7ABXHNCyekKxxvp3R9dMWv93gJl/QMOmo3sXK93AUB0rufDS+ebEg6IsZgB5W 9sm5jKnBGHAMlqXE31KiHcwmuP3M7om+OTTpV46ghtPcJH9GsTni7kSc3MNH7q/Cnrk4 gAj9RI+cD2nL/1h6j80LGge6rqTuHrxNidv9nm8iBdtOh382yG0vH5BSrZ90+eHajWEo Iavg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=fJyVxQ7c; 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; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 11-v6si4781702pgr.63.2018.09.20.16.28.52; Thu, 20 Sep 2018 16:29:12 -0700 (PDT) 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=@google.com header.s=20161025 header.b=fJyVxQ7c; 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; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726023AbeIUFOk (ORCPT + 99 others); Fri, 21 Sep 2018 01:14:40 -0400 Received: from mail-qk1-f202.google.com ([209.85.222.202]:55206 "EHLO mail-qk1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725780AbeIUFOk (ORCPT ); Fri, 21 Sep 2018 01:14:40 -0400 Received: by mail-qk1-f202.google.com with SMTP id o190-v6so8981078qkc.21 for ; Thu, 20 Sep 2018 16:28:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=0eUfEmnxFezrSWKVS8+HPs0FXoxcazz84MXUQZFdxbU=; b=fJyVxQ7cgqSl7e6mSUlC8lQHPTUObhfrBxGToeWQ0k1leOJcsGULvoRDU7Uw0ZNR/B 8SM5Rr4Ckeq3EGNIxrjiWc1qyofJTfVBNLxhJWet85O6Ztv+4ZxdapPzdL9kpLJFY8z/ GtcSOPDMFi3k8dtLNzmtonLBpQvh9/TP/lBageq0hh9jbkJPnPUbTnp7lZfUut28Vphh kP1kt5aZ1qRYHrO8f3SNrvSJgJKzsf2O4ubkuXLW7S7SKfSgy8a6b6s0E+IkEnm4LY8G K5+5x9s8Tynk3Cj7639sccDWn+ceuAPJGnE78tFx/0PZTx4/NldDUA6YF7Y4sWhrpOvb /y0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=0eUfEmnxFezrSWKVS8+HPs0FXoxcazz84MXUQZFdxbU=; b=Get7FeV1KAY/Ux4JKPkddvX3UHxKZ2/p8Id2DNj2adK70hHVOafOYam3jsvIkJ5iNo XrBG2yEwgNEl1DmlleeOoYxL/dY2f+j0knWm0Gxw9huLP6c0IqbmbqZ17LbDTZrKzLXd T0kIVvwHJEvA08iO4Wvo8J/dTmAF24zoyzDTzR0DG74HmFzNEntuLOITg5ROScDbFo1T 1BEe9y6blIIlzDNrSrSkFlgW+ups6HGxlMll3T3fcI8iyYyoX2+Y5TABbhukgoHOvKKc vBHD4rrYgJCnN7+I2WK5UQVWchQCaFmTo3/ZIvhdjxaQPz0g+ACXrAqU3ZCQ71YEKkdM RD3w== X-Gm-Message-State: APzg51CjxrwtzcNzge7lewJNj8QpV3TKYn2dGkiQ65xTUfu4/1KY+or5 NljBhBmGDkDSvu/MyHJle6nfc95DgWn248esBFiPwA== X-Received: by 2002:a0c:b138:: with SMTP id q53-v6mr14496850qvc.29.1537486119413; Thu, 20 Sep 2018 16:28:39 -0700 (PDT) Date: Thu, 20 Sep 2018 16:28:20 -0700 Message-Id: <20180920232820.243734-1-brendanhiggins@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.19.0.444.g18242da7ef-goog Subject: [PATCH] i2c: aspeed: fixed invalid clock parameters for very large divisors From: Brendan Higgins To: jae.hyun.yoo@linux.intel.com, benh@kernel.crashing.org, joel@jms.id.au, andrew@aj.id.au Cc: linux-i2c@vger.kernel.org, openbmc@lists.ozlabs.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org, Brendan Higgins Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The function that computes clock parameters from divisors did not respect the maximum size of the bitfields that the parameters were written to. This fixes the bug. This bug can be reproduced with (and this fix verified with) the test at: https://kunit-review.googlesource.com/c/linux/+/1035/ Discovered-by-KUnit: https://kunit-review.googlesource.com/c/linux/+/1035/ Signed-off-by: Brendan Higgins --- drivers/i2c/busses/i2c-aspeed.c | 38 +++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index c258c4d9a4c0..c1c3f0a4d805 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -705,9 +705,18 @@ static const struct i2c_algorithm aspeed_i2c_algo = { #endif /* CONFIG_I2C_SLAVE */ }; -static u32 aspeed_i2c_get_clk_reg_val(u32 clk_high_low_max, u32 divisor) +static u32 aspeed_i2c_get_clk_reg_val(u32 clk_high_low_mask, u32 divisor) { - u32 base_clk, clk_high, clk_low, tmp; + u32 base_clk, clk_high_low_max, clk_high, clk_low, tmp; + + /* + * SCL_high and SCL_low represent a value 1 greater than what is stored + * since a zero divider is meaningless. Thus, the max value each can + * store is every bit set + 1. Since SCL_high and SCL_low are added + * together (see below), the max value of both is the max value of one + * them times two. + */ + clk_high_low_max = (clk_high_low_mask + 1) * 2; /* * The actual clock frequency of SCL is: @@ -731,15 +740,22 @@ static u32 aspeed_i2c_get_clk_reg_val(u32 clk_high_low_max, u32 divisor) */ base_clk = divisor > clk_high_low_max ? ilog2((divisor - 1) / clk_high_low_max) + 1 : 0; - tmp = (divisor + (1 << base_clk) - 1) >> base_clk; - clk_low = tmp / 2; - clk_high = tmp - clk_low; - if (clk_high) - clk_high--; + if (base_clk > ASPEED_I2CD_TIME_BASE_DIVISOR_MASK) { + base_clk = ASPEED_I2CD_TIME_BASE_DIVISOR_MASK; + clk_low = clk_high_low_mask; + clk_high = clk_high_low_mask; + } else { + tmp = (divisor + (1 << base_clk) - 1) >> base_clk; + clk_low = tmp / 2; + clk_high = tmp - clk_low; + + if (clk_high) + clk_high--; - if (clk_low) - clk_low--; + if (clk_low) + clk_low--; + } return ((clk_high << ASPEED_I2CD_TIME_SCL_HIGH_SHIFT) @@ -755,7 +771,7 @@ static u32 aspeed_i2c_24xx_get_clk_reg_val(u32 divisor) * clk_high and clk_low are each 3 bits wide, so each can hold a max * value of 8 giving a clk_high_low_max of 16. */ - return aspeed_i2c_get_clk_reg_val(16, divisor); + return aspeed_i2c_get_clk_reg_val(GENMASK(2, 0), divisor); } static u32 aspeed_i2c_25xx_get_clk_reg_val(u32 divisor) @@ -764,7 +780,7 @@ static u32 aspeed_i2c_25xx_get_clk_reg_val(u32 divisor) * clk_high and clk_low are each 4 bits wide, so each can hold a max * value of 16 giving a clk_high_low_max of 32. */ - return aspeed_i2c_get_clk_reg_val(32, divisor); + return aspeed_i2c_get_clk_reg_val(GENMASK(3, 0), divisor); } /* precondition: bus.lock has been acquired. */ -- 2.19.0.444.g18242da7ef-goog