Received: by 10.223.185.116 with SMTP id b49csp1040651wrg; Fri, 23 Feb 2018 10:50:13 -0800 (PST) X-Google-Smtp-Source: AH8x227XsGVRH832oZvbEZmBCvEhZKIsSA9MHLNV6DPetsBm9P87CCeHh/XXuXYh4GY9CtS1Xdi0 X-Received: by 10.99.38.67 with SMTP id m64mr2165795pgm.2.1519411813521; Fri, 23 Feb 2018 10:50:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519411813; cv=none; d=google.com; s=arc-20160816; b=EHUimpT76rb2GiouJbqRp3ca6QeWJST5b6CAy/zrnbgOs1NIJwPoELBOQsyp2/EPSh rbS537gF9hAOZTZtJ5Z667cjUlAcD/wGVGLBvnZsTquexX9jEmRh1IbnV2iA2ktSoEkG O2dJIjc2A59P1HoLxo/jMpBILI7Sdn/GGADqehwTE0NRWEJrwJSa/npb6TChMtQHAn/g QrwInVIcriWJt/TfKkKgnZnHrMI/0ROTCp9KTmd31md7wvfxVeaHyM1V/xS24b3vCgqW biYAwIJjZAaiQYmmp3zb56nuzx2yZXksuBnwXOBsBvqqKjFTJY72ENAqXT6+2wxyhsM9 8/Ag== 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=o+6mAg6OVndRH6ssaav5B89yewrWKAJtQHg8NkHQ+Hs=; b=RsuxjxxfwWJOwZygqubn9oZYCFHmqmpPOIqCVEK4AgiVa0vCzpIOK3Wts7IOQCdUhN 2JQOM0wDjV6GYhWbHnur3t4dhK1Bh3VGih8z4L6Y0C7iu7OSlqlxgm15TvNQUcX0Ngna WZSV2uM/fw5121Ys3rT8fDftpSqgM84hUCdjNd3eYlvQs5sR9DFVgPVuRtSmY2jz459l YGf8Huq4xHUSPvlV+47XJZccgc8eWEux2mUcPxpuH8NIvqtERB2eh9W1xEJ1bicch1qi CbHgHKqYOaftq++z8iMpISYWBYd97TGfUJHzrJT2S+QMsTSZ/kIefMHXjs8vtpPWRxue Cxyg== 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 t10-v6si2133182plh.403.2018.02.23.10.49.59; Fri, 23 Feb 2018 10:50:13 -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 S934487AbeBWStK (ORCPT + 99 others); Fri, 23 Feb 2018 13:49:10 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:45168 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933827AbeBWStH (ORCPT ); Fri, 23 Feb 2018 13:49:07 -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 8DCE11166; Fri, 23 Feb 2018 18:49:06 +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.9 127/145] [media] tc358743: fix register i2c_rd/wr functions Date: Fri, 23 Feb 2018 19:27:13 +0100 Message-Id: <20180223170741.251305784@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180223170724.669759283@linuxfoundation.org> References: <20180223170724.669759283@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.9-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 @@ -193,57 +193,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 --------------- */ @@ -1236,7 +1240,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; } @@ -1262,7 +1266,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;