Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp1081660ybt; Wed, 1 Jul 2020 18:23:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzwDryMPALQ4WAXIvVPAUn2QtXrWKS3/Hv/cKAcnrXv4BgD4Kev0otGEkUJluKaCL5ObauY X-Received: by 2002:a17:906:1356:: with SMTP id x22mr26484831ejb.429.1593652994213; Wed, 01 Jul 2020 18:23:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593652994; cv=none; d=google.com; s=arc-20160816; b=tok2gtlHWvKWPCG/jZOVuEJ8lvVwe04KppBdoggGZwh1Uluaesn+e7v02+uA4ElZe/ LM7MeTSa3RtfpVGuf88q266GprjlgobG9s30/wd2MOyIxQyd6hZ8QacUh/ojmXTBFHSH 8klyi8pZtWD8uSxH6c4ufkgroFVQ6y5Lf1oh9wBoMO/3sXyOHLStxw/uHnJck1flXTUG nMOkl9cXtttVp3mB9gYad4yTdYZf4MKe7sVfurHTg9n2oc20Q1gi0ZIWwJNbf0LWMg0N OvEf1KnVLjZ/AxK9aEqJwjHYNvCSkDPQnCt6kJEQQCjZenTQBa7ast4cawW53r3fzh94 ak5Q== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=4r5Hoxy3Oa08kZjOkTwsGvH9Jkmn0tRExzRQrgIMR8k=; b=ebiEl9jk6bieGueduA3IAu0Ki5aB/9cpdAa4yITehyDieTFBVIxlhgnfuZx+GM6QBO ycEAVd8X6GwG/10/UXU5HvYRlnY8fmSIfNtxW4rqCHETh+lPljXiedZxf1x5xwdP13DV 27ef/X7/EH1oy2zf3YRLvypvV5XY5vyPuXdxjoqizjqxpV9ElXXcwC5nyCdqf2RhTeys uigqgdKKQQgDkTw0I+/aokHL/sq2hFFJs9hZUdjVKEBuFU2U5QoI1MD1hwHryvnbH+lD GlL1w6HYniFFfIOQ56Yd/zjxMROxFvQwPDquv40c9WJ68d0OsHlAfUrjDCkoGFgPZTmx L6Cw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=gMwCgoLE; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bx8si4728221edb.170.2020.07.01.18.22.51; Wed, 01 Jul 2020 18:23:14 -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=gMwCgoLE; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728128AbgGBBWI (ORCPT + 99 others); Wed, 1 Jul 2020 21:22:08 -0400 Received: from mail.kernel.org ([198.145.29.99]:53018 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726028AbgGBBWG (ORCPT ); Wed, 1 Jul 2020 21:22:06 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id B1C8B2083E; Thu, 2 Jul 2020 01:22:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1593652925; bh=eEmDcz5D+lQVVqHTUN/23pAD+joc3MzUTOTrSXN4g1I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gMwCgoLEWIWyF+1+TyEfspnnmEWgazQ/Fyd3JHhiiRv6opB8FEKKYT1QS1h1cOWiW MwUH482fMsQx6JZ+JdZrWic6fj0PkkUgW1+P2e09HEHbcK69386MzI1twm4yBBM/UB cDnp/QH4ZbWURYi4bp+uVCt4+PXfruYPn67bjdyg= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Jens Thoms Toerring , Mark Brown , Sasha Levin Subject: [PATCH AUTOSEL 5.7 02/53] regmap: fix alignment issue Date: Wed, 1 Jul 2020 21:21:11 -0400 Message-Id: <20200702012202.2700645-2-sashal@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200702012202.2700645-1-sashal@kernel.org> References: <20200702012202.2700645-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore 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 59f911e577192..d3112665c7d08 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