Received: by 2002:a25:e74b:0:0:0:0:0 with SMTP id e72csp1965860ybh; Tue, 14 Jul 2020 11:51:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwZ90vxjn/U90KQMeExnfox6hc7ulOehC7E9SGbvcGkeGoiQvyCgrafRMNJ9YXQMfHRahqU X-Received: by 2002:aa7:c314:: with SMTP id l20mr6274134edq.150.1594752717481; Tue, 14 Jul 2020 11:51:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594752717; cv=none; d=google.com; s=arc-20160816; b=NItXUFsScyLdsoAoQGmfA9R6J/EzKZrm6pdR+HLgk5H0IF7UKk/8n2xq7HdwniGCvB XE8YR/MGOlDvb8oy97BdnFTojRlJY33/XfKW2PACCPl3JhpFWMtUW+NcWgYHGJvAZ9Ti dRvMJ+TpaGPTaXYja6KfDf2ggB6Zv4/kghzePJCH/Ee8TvZxatvaj1UTS54q+aC4Hz4J Qc7HWB8iwFY71cJJn6vaCK/VjggM0Ysl9ybcnc6xQNMsltJ4PybMfo+OMVgmquFW4HLM Wk/O13ffra2cFVgxdTJ2GT1b7zav4OvfH7+UJbsmFXkzoHSXfrWIcL88wqRkEJe6ZnRk uwXw== 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=IeSbIE6Yhwj933N2gATvMsXL7j2skogSfJkh+xcvz5c=; b=Zh8ayQrOPeBSLKKG9VQeDjA7qbJRxNVSWWHP3h/T/xleg9V7qY/TrqeVN2XNfCAJkF dq+57c4M5cyXT6zI3UUT4vkUYgmrXrO2Ll4qhEp+ai/BM+eXsvXMaDg0u5q0dt37uMjQ 6aqTVQm9e7/6J6IIRhFqmnrzKAYuh3JoHo1ZMe3FdzafS3F3+/m7+b9ycc9JhhZ9YVTt 7beShpr4W4td3GW+tdnpNNnHNP7PjHOHeZqPo3DWPu8G+tMeGcGhrB1w270KW5EUTYb2 ry2DaKL9Ih1jBTcsn4LHtFuyMaWeaHlXv329j4oJgOh1ap/i+P/RfB/vudqgu5udVRj6 +JOw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=gEj1ShBQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id gj23si12098068ejb.21.2020.07.14.11.51.34; Tue, 14 Jul 2020 11:51:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=gEj1ShBQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729975AbgGNSsf (ORCPT + 99 others); Tue, 14 Jul 2020 14:48:35 -0400 Received: from mail.kernel.org ([198.145.29.99]:44086 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729970AbgGNSse (ORCPT ); Tue, 14 Jul 2020 14:48:34 -0400 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 D6C3922B2B; Tue, 14 Jul 2020 18:48:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1594752513; bh=XQBL9NrEUkiI8wtjcCl9dHlXNWIE2G3UKZK2k4ezkRE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gEj1ShBQpUttUONpGEDKU0vJzRGXCq/sKbbklHDGFRxgzncuq59AjGJAjhdq2F9PT DxqMtD1wqJYTBYocN2ZNy/ghDhZK6X5SOcM8/UP+VvxQrx/61L7YLpjpVsXPMOf8y1 ac55u9VHCNh/RI+f6ABN0ZGIvT3VANhoCXAxwvro= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jens Thoms Toerring , Mark Brown , Sasha Levin Subject: [PATCH 5.4 004/109] regmap: fix alignment issue Date: Tue, 14 Jul 2020 20:42:58 +0200 Message-Id: <20200714184105.719730471@linuxfoundation.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714184105.507384017@linuxfoundation.org> References: <20200714184105.507384017@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: Jens Thoms Toerring [ Upstream commit 53d860952c8215cf9ae1ea33409c8cb71ad6ad3d ] The assembly and disassembly of data to be sent to or received from a device invoke functions regmap_format_XX() and regmap_parse_XX() that extract or insert data items from or into a buffer, using assignments. In some cases the functions are called with a buffer pointer with an odd address. On architectures with strict alignment requirements this can result in a kernel crash. The assignments have been replaced by functions that take alignment into account. Signed-off-by: Jens Thoms Toerring Link: https://lore.kernel.org/r/20200531095300.GA27570@toerring.de Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/base/regmap/regmap.c | 100 ++++++++++++++++------------------- 1 file changed, 46 insertions(+), 54 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 508bbd6ea4396..320d23de02c29 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -17,6 +17,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include "trace.h" @@ -249,22 +250,20 @@ static void regmap_format_8(void *buf, unsigned int val, unsigned int shift) static void regmap_format_16_be(void *buf, unsigned int val, unsigned int shift) { - __be16 *b = buf; - - b[0] = cpu_to_be16(val << shift); + put_unaligned_be16(val << shift, buf); } static void regmap_format_16_le(void *buf, unsigned int val, unsigned int shift) { - __le16 *b = buf; - - b[0] = cpu_to_le16(val << shift); + put_unaligned_le16(val << shift, buf); } static void regmap_format_16_native(void *buf, unsigned int val, unsigned int shift) { - *(u16 *)buf = val << shift; + u16 v = val << shift; + + memcpy(buf, &v, sizeof(v)); } static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) @@ -280,43 +279,39 @@ static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) static void regmap_format_32_be(void *buf, unsigned int val, unsigned int shift) { - __be32 *b = buf; - - b[0] = cpu_to_be32(val << shift); + put_unaligned_be32(val << shift, buf); } static void regmap_format_32_le(void *buf, unsigned int val, unsigned int shift) { - __le32 *b = buf; - - b[0] = cpu_to_le32(val << shift); + put_unaligned_le32(val << shift, buf); } static void regmap_format_32_native(void *buf, unsigned int val, unsigned int shift) { - *(u32 *)buf = val << shift; + u32 v = val << shift; + + memcpy(buf, &v, sizeof(v)); } #ifdef CONFIG_64BIT static void regmap_format_64_be(void *buf, unsigned int val, unsigned int shift) { - __be64 *b = buf; - - b[0] = cpu_to_be64((u64)val << shift); + put_unaligned_be64((u64) val << shift, buf); } static void regmap_format_64_le(void *buf, unsigned int val, unsigned int shift) { - __le64 *b = buf; - - b[0] = cpu_to_le64((u64)val << shift); + put_unaligned_le64((u64) val << shift, buf); } static void regmap_format_64_native(void *buf, unsigned int val, unsigned int shift) { - *(u64 *)buf = (u64)val << shift; + u64 v = (u64) val << shift; + + memcpy(buf, &v, sizeof(v)); } #endif @@ -333,35 +328,34 @@ static unsigned int regmap_parse_8(const void *buf) static unsigned int regmap_parse_16_be(const void *buf) { - const __be16 *b = buf; - - return be16_to_cpu(b[0]); + return get_unaligned_be16(buf); } static unsigned int regmap_parse_16_le(const void *buf) { - const __le16 *b = buf; - - return le16_to_cpu(b[0]); + return get_unaligned_le16(buf); } static void regmap_parse_16_be_inplace(void *buf) { - __be16 *b = buf; + u16 v = get_unaligned_be16(buf); - b[0] = be16_to_cpu(b[0]); + memcpy(buf, &v, sizeof(v)); } static void regmap_parse_16_le_inplace(void *buf) { - __le16 *b = buf; + u16 v = get_unaligned_le16(buf); - b[0] = le16_to_cpu(b[0]); + memcpy(buf, &v, sizeof(v)); } static unsigned int regmap_parse_16_native(const void *buf) { - return *(u16 *)buf; + u16 v; + + memcpy(&v, buf, sizeof(v)); + return v; } static unsigned int regmap_parse_24(const void *buf) @@ -376,69 +370,67 @@ static unsigned int regmap_parse_24(const void *buf) static unsigned int regmap_parse_32_be(const void *buf) { - const __be32 *b = buf; - - return be32_to_cpu(b[0]); + return get_unaligned_be32(buf); } static unsigned int regmap_parse_32_le(const void *buf) { - const __le32 *b = buf; - - return le32_to_cpu(b[0]); + return get_unaligned_le32(buf); } static void regmap_parse_32_be_inplace(void *buf) { - __be32 *b = buf; + u32 v = get_unaligned_be32(buf); - b[0] = be32_to_cpu(b[0]); + memcpy(buf, &v, sizeof(v)); } static void regmap_parse_32_le_inplace(void *buf) { - __le32 *b = buf; + u32 v = get_unaligned_le32(buf); - b[0] = le32_to_cpu(b[0]); + memcpy(buf, &v, sizeof(v)); } static unsigned int regmap_parse_32_native(const void *buf) { - return *(u32 *)buf; + u32 v; + + memcpy(&v, buf, sizeof(v)); + return v; } #ifdef CONFIG_64BIT static unsigned int regmap_parse_64_be(const void *buf) { - const __be64 *b = buf; - - return be64_to_cpu(b[0]); + return get_unaligned_be64(buf); } static unsigned int regmap_parse_64_le(const void *buf) { - const __le64 *b = buf; - - return le64_to_cpu(b[0]); + return get_unaligned_le64(buf); } static void regmap_parse_64_be_inplace(void *buf) { - __be64 *b = buf; + u64 v = get_unaligned_be64(buf); - b[0] = be64_to_cpu(b[0]); + memcpy(buf, &v, sizeof(v)); } static void regmap_parse_64_le_inplace(void *buf) { - __le64 *b = buf; + u64 v = get_unaligned_le64(buf); - b[0] = le64_to_cpu(b[0]); + memcpy(buf, &v, sizeof(v)); } static unsigned int regmap_parse_64_native(const void *buf) { - return *(u64 *)buf; + u64 v; + + memcpy(&v, buf, sizeof(v)); + return v; } #endif -- 2.25.1