Received: by 10.223.185.116 with SMTP id b49csp1031475wrg; Fri, 23 Feb 2018 10:39:35 -0800 (PST) X-Google-Smtp-Source: AH8x225lRc5zIXKRHq3P3Fdac54BLG0OfCHPAIjy04qt/vPk4XJ2aMAon4wyWN2f6TZw2+181Juu X-Received: by 10.101.92.66 with SMTP id v2mr2128109pgr.341.1519411175428; Fri, 23 Feb 2018 10:39:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519411175; cv=none; d=google.com; s=arc-20160816; b=IBvCtoobRwfKaUkgP/vOyV8k/yu5xJfWSZgqPFLbwHDhMCLtMdUTHEoID8kSPP8jSU xIfsv7sOMFB0IzZif1qCa7Idsabxd7NRZbxMlTyDITdNyDrtZP3gc+lG8Z001iJbJxyz i3ks7ShHf1uLBeKhSUX4hbJFGG1jxZCdKljrstReHruyYuj76I5qwzKZFZGY+fsonc0b D8C6Sem2/NfoOSuCFuFz1kIn50qcHrjRLHUPTG5CqMflC0csPO/c26rzwjKnuhWBWU1w rvsVWKpCgREBaV2DYtuoSG/iNflXpcoxNhKxI86oKrWzqXOkv/TYWKiq19zJWzttgTMF gT+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=1PaKlv1PWLdkC9AaepMJpWUYwBxFeP16AptJDIazUps=; b=kENTAjvQ2kmxj1VpmadwDDmW77EhD56p/0gnucH/Kimg8BNYbEyup8+Eyg65wX129y SbvH3qIQUVpH+O/TqM1R8cFYKfTi69QWA48ZVV1GrZB87+58TpSZtjf/uSO4yToreUSb D4B2/LXmUZCTpJkiX0QOeYOmG+WQwDEplmDyTDJdCMWdUmp2oR0eQOfPlqBv7jidyVH+ 7v/yVl8WO5UhKq0Mu5GQeh2pE2g8NY+nuOASqkTHOREV92czc6Pd82g2Rz2V5vvMBgxZ Vsct5xnZiurCOSmGQca8v7HE9ZCwCFFjdmSzI0D7ntHqNIrzNnT/IgMOR4FF8qnPQV/t k82Q== ARC-Authentication-Results: i=1; mx.google.com; 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 u7si2185774pfb.216.2018.02.23.10.39.21; Fri, 23 Feb 2018 10:39:35 -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; 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 S932451AbeBWSio (ORCPT + 99 others); Fri, 23 Feb 2018 13:38:44 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:39402 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754024AbeBWSil (ORCPT ); Fri, 23 Feb 2018 13:38:41 -0500 Received: from localhost (LFbn-1-12258-90.w90-92.abo.wanadoo.fr [90.92.71.90]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 266D8111B; Fri, 23 Feb 2018 18:38:40 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Arnd Bergmann , Hans Verkuil , Mauro Carvalho Chehab Subject: [PATCH 4.4 130/193] [media] tc358743: fix register i2c_rd/wr functions Date: Fri, 23 Feb 2018 19:26:03 +0100 Message-Id: <20180223170346.213655459@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180223170325.997716448@linuxfoundation.org> References: <20180223170325.997716448@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 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 4.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Arnd Bergmann commit 3538aa6ecfb2dd727a40f9ebbbf25a0c2afe6226 upstream. While testing with CONFIG_UBSAN, I got this warning: drivers/media/i2c/tc358743.c: In function 'tc358743_probe': drivers/media/i2c/tc358743.c:1930:1: error: the frame size of 2480 bytes is larger than 2048 bytes [-Werror=frame-larger-than=] The problem is that the i2c_rd8/wr8/rd16/... functions in this driver pass a pointer to a local variable into a common function, and each call to one of them adds another variable plus redzone to the stack. I also noticed that the way this is done is broken on big-endian machines, as we copy the registers in CPU byte order. To address both those problems, I'm adding two helper functions for reading a register of up to 32 bits with correct endianess and change all other functions to use that instead. Just to be sure we don't get the problem back with changed optimizations in gcc, I'm also marking the new functions as 'noinline', although my tests with gcc-7 don't require that. Signed-off-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/tc358743.c | 46 +++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 21 deletions(-) --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -197,57 +197,61 @@ static void i2c_wr(struct v4l2_subdev *s } } -static u8 i2c_rd8(struct v4l2_subdev *sd, u16 reg) +static noinline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n) { - u8 val; + __le32 val = 0; - i2c_rd(sd, reg, &val, 1); + i2c_rd(sd, reg, (u8 __force *)&val, n); - return val; + return le32_to_cpu(val); +} + +static noinline void i2c_wrreg(struct v4l2_subdev *sd, u16 reg, u32 val, u32 n) +{ + __le32 raw = cpu_to_le32(val); + + i2c_wr(sd, reg, (u8 __force *)&raw, n); +} + +static u8 i2c_rd8(struct v4l2_subdev *sd, u16 reg) +{ + return i2c_rdreg(sd, reg, 1); } static void i2c_wr8(struct v4l2_subdev *sd, u16 reg, u8 val) { - i2c_wr(sd, reg, &val, 1); + i2c_wrreg(sd, reg, val, 1); } static void i2c_wr8_and_or(struct v4l2_subdev *sd, u16 reg, u8 mask, u8 val) { - i2c_wr8(sd, reg, (i2c_rd8(sd, reg) & mask) | val); + i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 2) & mask) | val, 2); } static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg) { - u16 val; - - i2c_rd(sd, reg, (u8 *)&val, 2); - - return val; + return i2c_rdreg(sd, reg, 2); } static void i2c_wr16(struct v4l2_subdev *sd, u16 reg, u16 val) { - i2c_wr(sd, reg, (u8 *)&val, 2); + i2c_wrreg(sd, reg, val, 2); } static void i2c_wr16_and_or(struct v4l2_subdev *sd, u16 reg, u16 mask, u16 val) { - i2c_wr16(sd, reg, (i2c_rd16(sd, reg) & mask) | val); + i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 2) & mask) | val, 2); } static u32 i2c_rd32(struct v4l2_subdev *sd, u16 reg) { - u32 val; - - i2c_rd(sd, reg, (u8 *)&val, 4); - - return val; + return i2c_rdreg(sd, reg, 4); } static void i2c_wr32(struct v4l2_subdev *sd, u16 reg, u32 val) { - i2c_wr(sd, reg, (u8 *)&val, 4); + i2c_wrreg(sd, reg, val, 4); } /* --------------- STATUS --------------- */ @@ -1240,7 +1244,7 @@ static int tc358743_g_register(struct v4 reg->size = tc358743_get_reg_size(reg->reg); - i2c_rd(sd, reg->reg, (u8 *)®->val, reg->size); + reg->val = i2c_rdreg(sd, reg->reg, reg->size); return 0; } @@ -1266,7 +1270,7 @@ static int tc358743_s_register(struct v4 reg->reg == BCAPS) return 0; - i2c_wr(sd, (u16)reg->reg, (u8 *)®->val, + i2c_wrreg(sd, (u16)reg->reg, reg->val, tc358743_get_reg_size(reg->reg)); return 0;