Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp551190pxb; Mon, 8 Nov 2021 18:27:34 -0800 (PST) X-Google-Smtp-Source: ABdhPJyyIMd84Zrkx316hx4JrXHYluQ39UgdPNHNhtd/INHzYihZMzSSzjU/vLgP+pb8wD7Jf6LA X-Received: by 2002:a92:db02:: with SMTP id b2mr2673097iln.95.1636424854402; Mon, 08 Nov 2021 18:27:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1636424854; cv=none; d=google.com; s=arc-20160816; b=B5g3RnExIg5qxqx3d5mlYHAvAURT6Q1tTbLUz9BJ+KQSHH/pzrtoTNbyMKPgEjroNw zT+7YaZCFdzT5tPVIrAlEybvW23o2N6JHDTAruG8uCDCjrgI2IuU3SChk+g+/CL2f7f7 v8Dk5soCXJePwcNzCRU0IRAiPCGcGyvV+qmRAPmDliud0o2VBGa8INS+eG62zDx/23VR UhUx4vt9uDoj/lW3CSIEfbonCC0rlWp28m+eR1ALYEWzVyVGnv0EHzI8jWFEkG/ZPLdy 5gLbJtBp93mHaz30qC6GjhLhJaTGGpV1jT6KzWRak0Wh7UvxhXX9XdI2OB7KZT7AFnCi S0Hg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ZpTqRwsl5N8HDJPao89PDMQwyOdkk8Pyj5oDHvhtU8Q=; b=Jl/GUzLoYSIPR90iXa4wtbX7JGllmelnLdi5W6hVUm5bw0vqu+CgHF5xAHZxO2i0D2 0j/dySU08AbUApaD4QosOrKpXu61UaRI+XTnh9nz2JFY6CofenhjvdPu6lNiqFMh3xv7 2JtOEbxRWtMzt89BNfpUtDTWn/kv4tw2e3nalkp9+5D8373+eoPfDblFu0mSniB6CbvB +aUwxfMLkkgAZkHQQAnbIgSt6Mj0REBbJzZqaqZnz68yib+OWm/6CyQO2KSPtf8lmpqo efIs21g6ra5x06sRsQUGfgLfYxF3peOX4vBzEJazKBhHGN3JMp1neasBk2EZLL2NX+Ua bFkw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=v61NbS6v; 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=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y6si37518809ilu.49.2021.11.08.18.27.21; Mon, 08 Nov 2021 18:27:34 -0800 (PST) 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=@linaro.org header.s=google header.b=v61NbS6v; 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=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235219AbhKHSTW (ORCPT + 99 others); Mon, 8 Nov 2021 13:19:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36692 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235105AbhKHSTU (ORCPT ); Mon, 8 Nov 2021 13:19:20 -0500 Received: from mail-qt1-x82c.google.com (mail-qt1-x82c.google.com [IPv6:2607:f8b0:4864:20::82c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 742C0C061570 for ; Mon, 8 Nov 2021 10:16:35 -0800 (PST) Received: by mail-qt1-x82c.google.com with SMTP id o17so1581991qtk.1 for ; Mon, 08 Nov 2021 10:16:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZpTqRwsl5N8HDJPao89PDMQwyOdkk8Pyj5oDHvhtU8Q=; b=v61NbS6vGIzMCmff/XzXFnMfa8gO7JyIJBYAtOE0I1jpTiFcIniZv5tf4r+VHOOcBk cdZba46PzU3v1F8FDEQrNszOWI9ipttIT+T10TvJPX3ramxmzFYDJsqDp3+WwqBL0ELp 7IRm4vfyAXYX42GMdqkO4TaI7lkaZ50rwfvund9Je/ZOAbdFL1SYzN1TWBDyiRpmIamc /PHnW34kJnCnyZyOPi0h8SSvf4hOJooepAg2nBXMGIbXhdL1dynA7Gt4ZhCQanhwj2v5 zX3DM9v+FOP42RtpxBEBsQ/bDp+V6CkeUw6DvhQbDx+cb9JCqI9DlVSywPxw95c8F+je tw8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZpTqRwsl5N8HDJPao89PDMQwyOdkk8Pyj5oDHvhtU8Q=; b=W1IlmqjUpV0Ar38/RYexxcalWyCE8i2ndunOR1U/zKNwg4KgU/WPyR0JzZ6qJiEoGo gL1ORcNZcgV/xKshEBUqNyDDsoAZhYOa+kfeo39xg1kRYoQtjHxQkbjdl0R6/45RLcG2 BLP8cPujm6ImlPS1Kaut4hMkcRUfxX1kTcwFGwpffH0UFERpb3FAwin0ce3PR09Qsi3x 4/muX3nJSIlCEvT3L4GGkbYaBBWfGb5/fJFAuwV9yS4bbeErTiVkbfJrUF3KcNhQSvZY gco5nxmsv59YKGa8d1urouVcUcSQKOoULiP+6PX9eje7SckoD8CDZYrxiL7IJreymnXI Ehlw== X-Gm-Message-State: AOAM533QIR9l5KQv3JsE70OxnJiKZNh2rJDvy7yCjs1KfMwtn+MuclXX ClsNaFAIDp23MHxWwwVq3BnLBw== X-Received: by 2002:a05:622a:1d5:: with SMTP id t21mr1622135qtw.382.1636395393007; Mon, 08 Nov 2021 10:16:33 -0800 (PST) Received: from maple.netwinder.org (rfs.netwinder.org. [206.248.184.2]) by smtp.gmail.com with ESMTPSA id m7sm6454244qkn.93.2021.11.08.10.16.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Nov 2021 10:16:32 -0800 (PST) From: Ralph Siemsen To: arnd@arndb.de, gregkh@linuxfoundation.org, jiri.prchal@aksignal.cz, broonie@kernel.org Cc: linux-kernel@vger.kernel.org, Ralph Siemsen Subject: [PATCH v2] nvmem: eeprom: at25: fix FRAM byte_len Date: Mon, 8 Nov 2021 13:16:27 -0500 Message-Id: <20211108181627.645638-1-ralph.siemsen@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211028134922.3965612-1-ralph.siemsen@linaro.org> References: <20211028134922.3965612-1-ralph.siemsen@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit fd307a4ad332 ("nvmem: prepare basics for FRAM support") added support for FRAM devices such as the Cypress FM25V. During testing, it was found that the FRAM detects properly, however reads and writes fail. Upon further investigation, two problem were found in at25_probe() routine. 1) In the case of an FRAM device without platform data, eg. fram == true && spi->dev.platform_data == NULL the stack local variable "struct spi_eeprom chip" is not initialized fully, prior to being copied into at25->chip. The chip.flags field in particular can cause problems. 2) The byte_len of FRAM is computed from its ID register, and is stored into the stack local "struct spi_eeprom chip" structure. This happens after the same structure has been copied into at25->chip. As a result, at25->chip.byte_len does not contain the correct length of the device. In turn this can cause checks at beginning of at25_ee_read() to fail (or equally, it could allow reads beyond the end of the device length). Fix both of these issues by eliminating the on-stack struct spi_eeprom. Instead use the one inside at25_data structure, which starts of zeroed. Fixes: fd307a4ad332 ("nvmem: prepare basics for FRAM support") Signed-off-by: Ralph Siemsen --- V1 -> V2: refactor to eliminate on-stack copy of "chip" structure drivers/misc/eeprom/at25.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 632325474233..b38978a3b3ff 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -376,7 +376,6 @@ MODULE_DEVICE_TABLE(spi, at25_spi_ids); static int at25_probe(struct spi_device *spi) { struct at25_data *at25 = NULL; - struct spi_eeprom chip; int err; int sr; u8 id[FM25_ID_LEN]; @@ -389,15 +388,18 @@ static int at25_probe(struct spi_device *spi) if (match && !strcmp(match->compatible, "cypress,fm25")) is_fram = 1; + at25 = devm_kzalloc(&spi->dev, sizeof(struct at25_data), GFP_KERNEL); + if (!at25) + return -ENOMEM; + /* Chip description */ - if (!spi->dev.platform_data) { - if (!is_fram) { - err = at25_fw_to_chip(&spi->dev, &chip); - if (err) - return err; - } - } else - chip = *(struct spi_eeprom *)spi->dev.platform_data; + if (spi->dev.platform_data) { + memcpy(&at25->chip, spi->dev.platform_data, sizeof(at25->chip)); + } else if (!is_fram) { + err = at25_fw_to_chip(&spi->dev, &at25->chip); + if (err) + return err; + } /* Ping the chip ... the status register is pretty portable, * unlike probing manufacturer IDs. We do expect that system @@ -409,12 +411,7 @@ static int at25_probe(struct spi_device *spi) return -ENXIO; } - at25 = devm_kzalloc(&spi->dev, sizeof(struct at25_data), GFP_KERNEL); - if (!at25) - return -ENOMEM; - mutex_init(&at25->lock); - at25->chip = chip; at25->spi = spi; spi_set_drvdata(spi, at25); @@ -431,7 +428,7 @@ static int at25_probe(struct spi_device *spi) dev_err(&spi->dev, "Error: unsupported size (id %02x)\n", id[7]); return -ENODEV; } - chip.byte_len = int_pow(2, id[7] - 0x21 + 4) * 1024; + at25->chip.byte_len = int_pow(2, id[7] - 0x21 + 4) * 1024; if (at25->chip.byte_len > 64 * 1024) at25->chip.flags |= EE_ADDR3; @@ -464,7 +461,7 @@ static int at25_probe(struct spi_device *spi) at25->nvmem_config.type = is_fram ? NVMEM_TYPE_FRAM : NVMEM_TYPE_EEPROM; at25->nvmem_config.name = dev_name(&spi->dev); at25->nvmem_config.dev = &spi->dev; - at25->nvmem_config.read_only = chip.flags & EE_READONLY; + at25->nvmem_config.read_only = at25->chip.flags & EE_READONLY; at25->nvmem_config.root_only = true; at25->nvmem_config.owner = THIS_MODULE; at25->nvmem_config.compat = true; @@ -474,17 +471,18 @@ static int at25_probe(struct spi_device *spi) at25->nvmem_config.priv = at25; at25->nvmem_config.stride = 1; at25->nvmem_config.word_size = 1; - at25->nvmem_config.size = chip.byte_len; + at25->nvmem_config.size = at25->chip.byte_len; at25->nvmem = devm_nvmem_register(&spi->dev, &at25->nvmem_config); if (IS_ERR(at25->nvmem)) return PTR_ERR(at25->nvmem); dev_info(&spi->dev, "%d %s %s %s%s, pagesize %u\n", - (chip.byte_len < 1024) ? chip.byte_len : (chip.byte_len / 1024), - (chip.byte_len < 1024) ? "Byte" : "KByte", + (at25->chip.byte_len < 1024) ? + at25->chip.byte_len : (at25->chip.byte_len / 1024), + (at25->chip.byte_len < 1024) ? "Byte" : "KByte", at25->chip.name, is_fram ? "fram" : "eeprom", - (chip.flags & EE_READONLY) ? " (readonly)" : "", + (at25->chip.flags & EE_READONLY) ? " (readonly)" : "", at25->chip.page_size); return 0; } -- 2.25.1