Message ID | 20240206042408.224138-1-joychakr@google.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-54296-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:168b:b0:106:860b:bbdd with SMTP id ma11csp1313852dyb; Mon, 5 Feb 2024 20:24:31 -0800 (PST) X-Google-Smtp-Source: AGHT+IHDGyCto5LGlRMCI7cn6pk9HZQOcEEkXB2Q7UfukYjW++eXfHagepbKQoN5CUaVz9ZRbiGe X-Received: by 2002:a17:903:2348:b0:1d7:41c0:59cf with SMTP id c8-20020a170903234800b001d741c059cfmr542280plh.30.1707193470866; Mon, 05 Feb 2024 20:24:30 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707193470; cv=pass; d=google.com; s=arc-20160816; b=lRfXkIDVDNlr2tMa5n/3MEkuurMSFyxJKwr+Bb0yYjL5XfyyNkuZdtsYRlpbF4ng8k HAhDlX0u71FXnhCwTvdzi6jMdW3+doZT/8IjnwsMzh4uoPQtqPOQx08h/LmBS3Vt0RhW 80cEaBSl9IIeNP7XOcaagli4WEx9S0vFjrsOpOGn1boR8YA5hW5f/uG4/gUh08n9mBYM 7ApXhgfeQmtKf/2ARY9Ix0BPsJIHjbOGzDfTaiAW5uTE3rCF0Bww4y0UPMLOXQo+lr00 0BAUqa/8q5y6NAq7NE7XS0rFLFHvpqILfN92caZ7y/9t3jd+botT8z2lOwXahkvZDLZB hbLw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:from:subject:message-id:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:date:dkim-signature; bh=LzWbdYel3aT7imRL2l+83QFH5wg8/SRc2R/DFZ/44Sg=; fh=sTxrGqzhQ+uemUtm1wqxGSTaqKiLl10b01r42e4vyhE=; b=Qv0YqdrfwYWAIAiuZZoZwwB8kFASSytZ3e3/SHHhKq6k2+cIm95sgpao2uNywhl5XU v4T15fbKjb7Xv1zzxhpfYZsOueaAhCTyB1EAIfVFAWUwQ7KnyIPh/+CEdKnqVbbIO2fy KX2PEnKVU0gA40lQA9yRqOfFCWgXeiUXdecoTiE5+5X2jaFGWM9mnGkqvr7p4K4snjNR sHXRyPPf3iP+kO8VdP+Eho79ZsVF4PioDs+TonOUYhCCreybDbIdR+yDo7wy9vd8Uwqt cttrq6bI+SVir+5nOTSYRHG/1jurzzMJi2bt4qdpT3VhcXrUF1XdDQIGASELaSn0mdsi vLEQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=DYOPkg05; arc=pass (i=1 spf=pass spfdomain=flex--joychakr.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-54296-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-54296-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCVU1nchYf8zwmz6d9OfwMVOrhnA/Htd4uICD4xWeTyD00v41svU3trP/FFGLFDRB9WEpzJYXA3f2vi7+BRev7rPbkpf7Q== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id ju2-20020a170903428200b001d6f7b3f65csi978713plb.43.2024.02.05.20.24.30 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 20:24:30 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-54296-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=DYOPkg05; arc=pass (i=1 spf=pass spfdomain=flex--joychakr.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-54296-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-54296-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 257EF286597 for <ouuuleilei@gmail.com>; Tue, 6 Feb 2024 04:24:30 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 04C6774E11; Tue, 6 Feb 2024 04:24:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="DYOPkg05" Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D0A27745FA for <linux-kernel@vger.kernel.org>; Tue, 6 Feb 2024 04:24:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707193457; cv=none; b=T1yCJ+pjh52nXyualbUuFBfRSUNi6ZvKy8D8gLg6bHtoDHoBALMkFnUdCRzK6Q2tcMqW+Y8B1SV7IyKDJsnbrTER21Dyg/OowF92w3CWjfkHFvjAV86d4LNX08sNeIDXBsf8Z3RYs+CASyUoItSRvJWWUKIXTs8ucKHi7X0YRq8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707193457; c=relaxed/simple; bh=BBcuUm0bjeZDYFp/nFXayMV+2jioo7Z2SXcSObhkE/0=; h=Date:Mime-Version:Message-ID:Subject:From:To:Cc:Content-Type; b=uCRlELXFAa+sanAo5P2md7ZcqIZ8HEV/3uKcbNeqBetEpNY33G5KTMD60Y9IVsqeG6h0l/5M6ho1Tigr2ru1hVwxWbqJFXu1uXneM6Rmns3dRihfCVLB0rctLn/k7kNbBdNPFqm3x51GPId4dzKL6a6uchFkNVqUwW0mKc9BuwI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--joychakr.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=DYOPkg05; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--joychakr.bounces.google.com Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dc6b9f4a513so8489644276.3 for <linux-kernel@vger.kernel.org>; Mon, 05 Feb 2024 20:24:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1707193455; x=1707798255; darn=vger.kernel.org; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=LzWbdYel3aT7imRL2l+83QFH5wg8/SRc2R/DFZ/44Sg=; b=DYOPkg05PyWTDjrw2ceopkyrpCRBIr3yqoXhyFVrCIeW4x4U7h3MEJ/Zf0e2Z3pyIV 2nYAhUGGyApnGZ1oeFsSSzfOiURFOF5Payq7kNWxlC5gpuOm79V4JF7LaEbHj7vHMQZ7 JmM4/ZWyW/J5IpjoK/AOue0Br8/IpR6FRzUEkI3ZpHby/QazfmROxCGnVR9xPa+JzXiV e0UXLEl4oyVrMk9kBn5HEw5eYFgAHnPFOPCNzLAMLFB5GfptyDlScUaC6F1fzJD54+Hi S474GT2f11D1dJIGZF0qGzD67hxY96RmRvRkNHbiBz4N0wP+FWDu9ZZwVC+Ny32RTH9R jChw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707193455; x=1707798255; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=LzWbdYel3aT7imRL2l+83QFH5wg8/SRc2R/DFZ/44Sg=; b=W2KZx13o/U8+ZzCLxi6Bm0Raxhx5vbUYaJqo3fnA8tEhE4eb7qXSDnQJQbL6ScPDzU 1EokBKf8oimojwdFuUJOVseTdLc4/f+z2QHbtnQ9ZsXwuDHwHbjKoJqNXEAm+rh9Bx/b 7+WTuvicz8Io2NqKbyAFyTw0gRC0WfCjOigCQ0E6siDPT+RTCAz3t5cISWlzho14CzVg Pr+pCvZEf4JgOeYpJzt3g5BTNqZdS2HFXijIiPb7G3UZ5bGffUrhyDRjmhMOzRqpUhWy vXeAXOBBqDPLy/nDBCgjlD+IM4aKikhv0/nN2ZKiXDfbFmoOI6PC4XJEoYEWoKTPjS8X EBfA== X-Gm-Message-State: AOJu0YzTI+rlvm27XA6BYv0MgzvVVu24CrRMX2WKy732Iu4yssCruNuw 4SyNrtT/9QMUSk7riGI02WfbfVxqPs0QluEx5d5rbYts0nArFAC06L+SsAc7Q/mkNznYTYAqCGC L3e0t4vMToA== X-Received: from joychakr.c.googlers.com ([fda3:e722:ac3:cc00:4f:4b78:c0a8:6ea]) (user=joychakr job=sendgmr) by 2002:a05:6902:2485:b0:dc2:550b:a4f4 with SMTP id ds5-20020a056902248500b00dc2550ba4f4mr162784ybb.1.1707193454844; Mon, 05 Feb 2024 20:24:14 -0800 (PST) Date: Tue, 6 Feb 2024 04:24:08 +0000 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> Mime-Version: 1.0 X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Message-ID: <20240206042408.224138-1-joychakr@google.com> Subject: [PATCH v2] nvmem: rmem: Fix return value of rmem_read() From: Joy Chakraborty <joychakr@google.com> To: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Rob Herring <robh@kernel.org>, Nicolas Saenz Julienne <nsaenz@kernel.org> Cc: linux-kernel@vger.kernel.org, manugautam@google.com, Joy Chakraborty <joychakr@google.com>, stable@vger.kernel.org Content-Type: text/plain; charset="UTF-8" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790122100538600871 X-GMAIL-MSGID: 1790122100538600871 |
Series |
[v2] nvmem: rmem: Fix return value of rmem_read()
|
|
Commit Message
Joy Chakraborty
Feb. 6, 2024, 4:24 a.m. UTC
reg_read() callback registered with nvmem core expects an integer error
as a return value but rmem_read() returns the number of bytes read, as a
result error checks in nvmem core fail even when they shouldn't.
Return 0 on success where number of bytes read match the number of bytes
requested and a negative error -EINVAL on all other cases.
Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem")
Cc: stable@vger.kernel.org
Signed-off-by: Joy Chakraborty <joychakr@google.com>
---
drivers/nvmem/rmem.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
Comments
On Tue, Feb 06, 2024 at 04:24:08AM +0000, Joy Chakraborty wrote: > reg_read() callback registered with nvmem core expects an integer error > as a return value but rmem_read() returns the number of bytes read, as a > result error checks in nvmem core fail even when they shouldn't. > > Return 0 on success where number of bytes read match the number of bytes > requested and a negative error -EINVAL on all other cases. > > Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem") > Cc: stable@vger.kernel.org > Signed-off-by: Joy Chakraborty <joychakr@google.com> > --- > drivers/nvmem/rmem.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c > index 752d0bf4445e..a74dfa279ff4 100644 > --- a/drivers/nvmem/rmem.c > +++ b/drivers/nvmem/rmem.c > @@ -46,7 +46,12 @@ static int rmem_read(void *context, unsigned int offset, > > memunmap(addr); > > - return count; > + if (count != bytes) { > + dev_err(priv->dev, "Failed read memory (%d)\n", count); > + return -EINVAL; Why is a "short read" somehow illegal here? What internal changes need to be made now that this has changed? And what will userspace do with this error message in the kernel log? thanks, greg k-h
On Tue, Feb 6, 2024 at 3:00 PM Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote: > > On Tue, Feb 06, 2024 at 04:24:08AM +0000, Joy Chakraborty wrote: > > reg_read() callback registered with nvmem core expects an integer error > > as a return value but rmem_read() returns the number of bytes read, as a > > result error checks in nvmem core fail even when they shouldn't. > > > > Return 0 on success where number of bytes read match the number of bytes > > requested and a negative error -EINVAL on all other cases. > > > > Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem") > > Cc: stable@vger.kernel.org > > Signed-off-by: Joy Chakraborty <joychakr@google.com> > > --- > > drivers/nvmem/rmem.c | 7 ++++++- > > 1 file changed, 6 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c > > index 752d0bf4445e..a74dfa279ff4 100644 > > --- a/drivers/nvmem/rmem.c > > +++ b/drivers/nvmem/rmem.c > > @@ -46,7 +46,12 @@ static int rmem_read(void *context, unsigned int offset, > > > > memunmap(addr); > > > > - return count; > > + if (count != bytes) { > > + dev_err(priv->dev, "Failed read memory (%d)\n", count); > > + return -EINVAL; > > Why is a "short read" somehow illegal here? What internal changes need > to be made now that this has changed? In my opinion "short read" should be illegal for cases where if the nvmem core is unable to read the required size of data to fill up a nvmem cell then data returned might have truncated value. No internal changes should be made since the registered reg_read() is called from __nvmem_reg_read() which eventually passes on the error code to nvmem_reg_read() whose return code is already checked and passed to nvmem consumers. Currently rmem driver is incorrectly passing a positive value for success. > > And what will userspace do with this error message in the kernel log? User space currently is not seeing this error for nvmem device/eeprom reads due to the following code at nvmem/core.c in bin_attr_nvmem_read(): " rc = nvmem_reg_read(nvmem, pos, buf, count); if (rc) return rc; return count; " since it expects to return the number of bytes. Userspace will see a false error with nvmem cell reads from nvmem_cell_attr_read() in current code, which should be fixed on returning 0 for success. > thanks, > > greg k-h Thanks Joy
On Tue, Feb 06, 2024 at 04:01:02PM +0530, Joy Chakraborty wrote: > On Tue, Feb 6, 2024 at 3:00 PM Greg Kroah-Hartman > <gregkh@linuxfoundation.org> wrote: > > > > On Tue, Feb 06, 2024 at 04:24:08AM +0000, Joy Chakraborty wrote: > > > reg_read() callback registered with nvmem core expects an integer error > > > as a return value but rmem_read() returns the number of bytes read, as a > > > result error checks in nvmem core fail even when they shouldn't. > > > > > > Return 0 on success where number of bytes read match the number of bytes > > > requested and a negative error -EINVAL on all other cases. > > > > > > Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem") > > > Cc: stable@vger.kernel.org > > > Signed-off-by: Joy Chakraborty <joychakr@google.com> > > > --- > > > drivers/nvmem/rmem.c | 7 ++++++- > > > 1 file changed, 6 insertions(+), 1 deletion(-) > > > > > > diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c > > > index 752d0bf4445e..a74dfa279ff4 100644 > > > --- a/drivers/nvmem/rmem.c > > > +++ b/drivers/nvmem/rmem.c > > > @@ -46,7 +46,12 @@ static int rmem_read(void *context, unsigned int offset, > > > > > > memunmap(addr); > > > > > > - return count; > > > + if (count != bytes) { > > > + dev_err(priv->dev, "Failed read memory (%d)\n", count); > > > + return -EINVAL; > > > > Why is a "short read" somehow illegal here? What internal changes need > > to be made now that this has changed? > > In my opinion "short read" should be illegal for cases where if the > nvmem core is unable to read the required size of data to fill up a > nvmem cell then data returned might have truncated value. But that's kind of against what a read() call normally expects. > No internal changes should be made since the registered reg_read() is > called from __nvmem_reg_read() which eventually passes on the error > code to nvmem_reg_read() whose return code is already checked and > passed to nvmem consumers. > Currently rmem driver is incorrectly passing a positive value for success. So this is an internal api issue and not a general issue? Unwinding the read callbacks here is hard. Also, in looking at the code, how can this ever be a short read? You are using memory_read_from_buffer() which unless the values passed into it are incorrect, will always return the expected read amount. > > And what will userspace do with this error message in the kernel log? > > User space currently is not seeing this error for nvmem device/eeprom > reads due to the following code at nvmem/core.c in > bin_attr_nvmem_read(): > " > rc = nvmem_reg_read(nvmem, pos, buf, count); > > if (rc) > return rc; > > return count; > " > since it expects to return the number of bytes. > > Userspace will see a false error with nvmem cell reads from > nvmem_cell_attr_read() in current code, which should be fixed on > returning 0 for success. So maybe fix this all up to allow the read to return the actual amount read? That feels more "correct" to me. thanks, greg k-h
On Tue, Feb 6, 2024 at 4:27 PM Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote: > > On Tue, Feb 06, 2024 at 04:01:02PM +0530, Joy Chakraborty wrote: > > On Tue, Feb 6, 2024 at 3:00 PM Greg Kroah-Hartman > > <gregkh@linuxfoundation.org> wrote: > > > > > > On Tue, Feb 06, 2024 at 04:24:08AM +0000, Joy Chakraborty wrote: > > > > reg_read() callback registered with nvmem core expects an integer error > > > > as a return value but rmem_read() returns the number of bytes read, as a > > > > result error checks in nvmem core fail even when they shouldn't. > > > > > > > > Return 0 on success where number of bytes read match the number of bytes > > > > requested and a negative error -EINVAL on all other cases. > > > > > > > > Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem") > > > > Cc: stable@vger.kernel.org > > > > Signed-off-by: Joy Chakraborty <joychakr@google.com> > > > > --- > > > > drivers/nvmem/rmem.c | 7 ++++++- > > > > 1 file changed, 6 insertions(+), 1 deletion(-) > > > > > > > > diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c > > > > index 752d0bf4445e..a74dfa279ff4 100644 > > > > --- a/drivers/nvmem/rmem.c > > > > +++ b/drivers/nvmem/rmem.c > > > > @@ -46,7 +46,12 @@ static int rmem_read(void *context, unsigned int offset, > > > > > > > > memunmap(addr); > > > > > > > > - return count; > > > > + if (count != bytes) { > > > > + dev_err(priv->dev, "Failed read memory (%d)\n", count); > > > > + return -EINVAL; > > > > > > Why is a "short read" somehow illegal here? What internal changes need > > > to be made now that this has changed? > > > > In my opinion "short read" should be illegal for cases where if the > > nvmem core is unable to read the required size of data to fill up a > > nvmem cell then data returned might have truncated value. > > But that's kind of against what a read() call normally expects. That is fair, maybe the size check should be there at the nvmem core layer to catch any truncations but the actual size read is not passed from provider to the core layer. > > > No internal changes should be made since the registered reg_read() is > > called from __nvmem_reg_read() which eventually passes on the error > > code to nvmem_reg_read() whose return code is already checked and > > passed to nvmem consumers. > > Currently rmem driver is incorrectly passing a positive value for success. > > So this is an internal api issue and not a general issue? Unwinding the > read callbacks here is hard. Yes, this is an internal API issue with how the return type of the reg_read() function pointer passed to nvmem_register() is handled. The function prototype in nvmem-provider.h does not define how the return value is treated in nvmem core. " typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset, void *val, size_t bytes); " Currently it is always checked against 0 for success in nvmem/core.c which all nvmem-providers adhere to i.e. return 0 on success. Actual size read from the provider is considered to be equal to the requested size from core as the provider does not relay that information. > > Also, in looking at the code, how can this ever be a short read? You > are using memory_read_from_buffer() which unless the values passed into > it are incorrect, will always return the expected read amount. > Correct, we will have an error only if the returned value from memory_read_from_buffer() is negative. So to work with the current nvmem core implementation, I can return the value as is if negative and 0 for positive. > > > And what will userspace do with this error message in the kernel log? > > > > User space currently is not seeing this error for nvmem device/eeprom > > reads due to the following code at nvmem/core.c in > > bin_attr_nvmem_read(): > > " > > rc = nvmem_reg_read(nvmem, pos, buf, count); > > > > if (rc) > > return rc; > > > > return count; > > " > > since it expects to return the number of bytes. > > > > Userspace will see a false error with nvmem cell reads from > > nvmem_cell_attr_read() in current code, which should be fixed on > > returning 0 for success. > > So maybe fix this all up to allow the read to return the actual amount > read? That feels more "correct" to me. > If I change the behavior of the nvmem_reg_read_t callback to negative for error and number of bytes actually read for success then, other than the core driver I would also have to change all the nvmem-provider drivers. Is it okay to do so ? > thanks, > > greg k-h Thanks Joy
On 06/02/2024 04:24, Joy Chakraborty wrote: > reg_read() callback registered with nvmem core expects an integer error > as a return value but rmem_read() returns the number of bytes read, as a > result error checks in nvmem core fail even when they shouldn't. > > Return 0 on success where number of bytes read match the number of bytes > requested and a negative error -EINVAL on all other cases. > > Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem") > Cc: stable@vger.kernel.org > Signed-off-by: Joy Chakraborty <joychakr@google.com> > --- > drivers/nvmem/rmem.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c > index 752d0bf4445e..a74dfa279ff4 100644 > --- a/drivers/nvmem/rmem.c > +++ b/drivers/nvmem/rmem.c > @@ -46,7 +46,12 @@ static int rmem_read(void *context, unsigned int offset, > > memunmap(addr); > > - return count; > + if (count != bytes) { How can this fail unless the values set in priv->mem->size is incorrect Only case I see this failing with short reads is when offset cross the boundary of priv->mem->size. can you provide more details on the failure usecase, may be with actual values of offsets, bytes and priv->mem->size? > + dev_err(priv->dev, "Failed read memory (%d)\n", count); > + return -EINVAL; > + } > + > + return 0; thanks, srini > } > > static int rmem_probe(struct platform_device *pdev)
On Wed, Feb 7, 2024 at 4:06 AM Srinivas Kandagatla <srinivas.kandagatla@linaro.org> wrote: > > > > On 06/02/2024 04:24, Joy Chakraborty wrote: > > reg_read() callback registered with nvmem core expects an integer error > > as a return value but rmem_read() returns the number of bytes read, as a > > result error checks in nvmem core fail even when they shouldn't. > > > > Return 0 on success where number of bytes read match the number of bytes > > requested and a negative error -EINVAL on all other cases. > > > > Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem") > > Cc: stable@vger.kernel.org > > Signed-off-by: Joy Chakraborty <joychakr@google.com> > > --- > > drivers/nvmem/rmem.c | 7 ++++++- > > 1 file changed, 6 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c > > index 752d0bf4445e..a74dfa279ff4 100644 > > --- a/drivers/nvmem/rmem.c > > +++ b/drivers/nvmem/rmem.c > > @@ -46,7 +46,12 @@ static int rmem_read(void *context, unsigned int offset, > > > > memunmap(addr); > > > > - return count; > > + if (count != bytes) { > > How can this fail unless the values set in priv->mem->size is incorrect > That should be correct since it would be fetched from the reserved memory definition in the device tree. > Only case I see this failing with short reads is when offset cross the > boundary of priv->mem->size. > > > can you provide more details on the failure usecase, may be with actual > values of offsets, bytes and priv->mem->size? > This could very well happen if a fixed-layout defined for the reserved memory has a cell which defines an offset and size greater than the actual size of the reserved mem. For E.g. if the device tree node is as follows reserved-memory { #address-cells = <1>; #size-cells = <1>; ranges; nvmem@1000 { compatible = "nvmem-rmem"; reg = <0x1000 0x400>; no-map; nvmem-layout { compatible = "fixed-layout"; #address-cells = <1>; #size-cells = <1>; calibration@13ff { reg = <0x13ff 0x2>; }; }; }; }; If we try to read the cell "calibration" which crosses the boundary of the reserved memory then it will lead to a short read. Though, one might argue that the protection against such cell definition should be there during fixed-layout parsing in core itself but that is not there now and would not be a fix. What I am trying to fix here is not exactly short reads but how the return value of rmem_read() is treated by the nvmem core, where it treats a non-zero return from read as an error currently. Hence returning the number of bytes read leads to false failures if we try to read a cell. > > > + dev_err(priv->dev, "Failed read memory (%d)\n", count); > > + return -EINVAL; > > + } > > + > > > + return 0; > > thanks, > srini > > > } > > > > static int rmem_probe(struct platform_device *pdev)
On 07/02/2024 06:35, Joy Chakraborty wrote: > On Wed, Feb 7, 2024 at 4:06 AM Srinivas Kandagatla > <srinivas.kandagatla@linaro.org> wrote: >> >> >> >> On 06/02/2024 04:24, Joy Chakraborty wrote: >>> reg_read() callback registered with nvmem core expects an integer error >>> as a return value but rmem_read() returns the number of bytes read, as a >>> result error checks in nvmem core fail even when they shouldn't. >>> >>> Return 0 on success where number of bytes read match the number of bytes >>> requested and a negative error -EINVAL on all other cases. >>> >>> Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem") >>> Cc: stable@vger.kernel.org >>> Signed-off-by: Joy Chakraborty <joychakr@google.com> >>> --- >>> drivers/nvmem/rmem.c | 7 ++++++- >>> 1 file changed, 6 insertions(+), 1 deletion(-) >>> >>> diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c >>> index 752d0bf4445e..a74dfa279ff4 100644 >>> --- a/drivers/nvmem/rmem.c >>> +++ b/drivers/nvmem/rmem.c >>> @@ -46,7 +46,12 @@ static int rmem_read(void *context, unsigned int offset, >>> >>> memunmap(addr); >>> >>> - return count; >>> + if (count != bytes) { >> >> How can this fail unless the values set in priv->mem->size is incorrect >> > > That should be correct since it would be fetched from the reserved > memory definition in the device tree. > >> Only case I see this failing with short reads is when offset cross the >> boundary of priv->mem->size. >> >> >> can you provide more details on the failure usecase, may be with actual >> values of offsets, bytes and priv->mem->size? >> > > This could very well happen if a fixed-layout defined for the reserved > memory has a cell which defines an offset and size greater than the > actual size of the reserved mem. No that should just be blocked from core layer, atleast which is what is checked bin_attr_nvmem_read(), if checks are missing in other places then that needs fixing. > For E.g. if the device tree node is as follows > reserved-memory { > #address-cells = <1>; > #size-cells = <1>; > ranges; > nvmem@1000 { > compatible = "nvmem-rmem"; > reg = <0x1000 0x400>; > no-map; > nvmem-layout { > compatible = "fixed-layout"; > #address-cells = <1>; > #size-cells = <1>; > calibration@13ff { > reg = <0x13ff 0x2>; this is out of range, core should just err out. --srini > }; > }; > }; > }; > If we try to read the cell "calibration" which crosses the boundary of > the reserved memory then it will lead to a short read. > Though, one might argue that the protection against such cell > definition should be there during fixed-layout parsing in core itself > but that is not there now and would not be a fix. > > What I am trying to fix here is not exactly short reads but how the > return value of rmem_read() is treated by the nvmem core, where it > treats a non-zero return from read as an error currently. Hence > returning the number of bytes read leads to false failures if we try > to read a cell. > > >> >>> + dev_err(priv->dev, "Failed read memory (%d)\n", count); >>> + return -EINVAL; >>> + } >>> + >> >>> + return 0; >> >> thanks, >> srini >> >>> } >>> >>> static int rmem_probe(struct platform_device *pdev)
On Tue, Feb 06, 2024 at 05:22:15PM +0530, Joy Chakraborty wrote: > > > Userspace will see a false error with nvmem cell reads from > > > nvmem_cell_attr_read() in current code, which should be fixed on > > > returning 0 for success. > > > > So maybe fix this all up to allow the read to return the actual amount > > read? That feels more "correct" to me. > > > > If I change the behavior of the nvmem_reg_read_t callback to negative > for error and number of bytes actually read for success then, other > than the core driver I would also have to change all the > nvmem-provider drivers. > Is it okay to do so ? Sure, why not? That seems like the correct fix to me, right? thanks, greg k-h
On Wed, Feb 7, 2024 at 3:00 PM Srinivas Kandagatla <srinivas.kandagatla@linaro.org> wrote: > > > > On 07/02/2024 06:35, Joy Chakraborty wrote: > > On Wed, Feb 7, 2024 at 4:06 AM Srinivas Kandagatla > > <srinivas.kandagatla@linaro.org> wrote: > >> > >> > >> > >> On 06/02/2024 04:24, Joy Chakraborty wrote: > >>> reg_read() callback registered with nvmem core expects an integer error > >>> as a return value but rmem_read() returns the number of bytes read, as a > >>> result error checks in nvmem core fail even when they shouldn't. > >>> > >>> Return 0 on success where number of bytes read match the number of bytes > >>> requested and a negative error -EINVAL on all other cases. > >>> > >>> Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem") > >>> Cc: stable@vger.kernel.org > >>> Signed-off-by: Joy Chakraborty <joychakr@google.com> > >>> --- > >>> drivers/nvmem/rmem.c | 7 ++++++- > >>> 1 file changed, 6 insertions(+), 1 deletion(-) > >>> > >>> diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c > >>> index 752d0bf4445e..a74dfa279ff4 100644 > >>> --- a/drivers/nvmem/rmem.c > >>> +++ b/drivers/nvmem/rmem.c > >>> @@ -46,7 +46,12 @@ static int rmem_read(void *context, unsigned int offset, > >>> > >>> memunmap(addr); > >>> > >>> - return count; > >>> + if (count != bytes) { > >> > >> How can this fail unless the values set in priv->mem->size is incorrect > >> > > > > That should be correct since it would be fetched from the reserved > > memory definition in the device tree. > > > >> Only case I see this failing with short reads is when offset cross the > >> boundary of priv->mem->size. > >> > >> > >> can you provide more details on the failure usecase, may be with actual > >> values of offsets, bytes and priv->mem->size? > >> > > > > This could very well happen if a fixed-layout defined for the reserved > > memory has a cell which defines an offset and size greater than the > > actual size of the reserved mem. > > No that should just be blocked from core layer, atleast which is what is > checked bin_attr_nvmem_read(), if checks are missing in other places > then that needs fixing. > Sure. > > > For E.g. if the device tree node is as follows > > reserved-memory { > > #address-cells = <1>; > > #size-cells = <1>; > > ranges; > > nvmem@1000 { > > compatible = "nvmem-rmem"; > > reg = <0x1000 0x400>; > > no-map; > > nvmem-layout { > > compatible = "fixed-layout"; > > #address-cells = <1>; > > #size-cells = <1>; > > calibration@13ff { > > reg = <0x13ff 0x2>; > > this is out of range, core should just err out. > Cells are currently unchecked, I can fix that in a different patch. > --srini > > > }; > > }; > > }; > > }; > > If we try to read the cell "calibration" which crosses the boundary of > > the reserved memory then it will lead to a short read. > > Though, one might argue that the protection against such cell > > definition should be there during fixed-layout parsing in core itself > > but that is not there now and would not be a fix. > > > > What I am trying to fix here is not exactly short reads but how the > > return value of rmem_read() is treated by the nvmem core, where it > > treats a non-zero return from read as an error currently. Hence > > returning the number of bytes read leads to false failures if we try > > to read a cell. > > > > > >> > >>> + dev_err(priv->dev, "Failed read memory (%d)\n", count); > >>> + return -EINVAL; > >>> + } > >>> + > >> > >>> + return 0; > >> > >> thanks, > >> srini > >> > >>> } > >>> > >>> static int rmem_probe(struct platform_device *pdev) Thanks Joy
On Wed, Feb 7, 2024 at 3:04 PM Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote: > > On Tue, Feb 06, 2024 at 05:22:15PM +0530, Joy Chakraborty wrote: > > > > Userspace will see a false error with nvmem cell reads from > > > > nvmem_cell_attr_read() in current code, which should be fixed on > > > > returning 0 for success. > > > > > > So maybe fix this all up to allow the read to return the actual amount > > > read? That feels more "correct" to me. > > > > > > > If I change the behavior of the nvmem_reg_read_t callback to negative > > for error and number of bytes actually read for success then, other > > than the core driver I would also have to change all the > > nvmem-provider drivers. > > Is it okay to do so ? > > Sure, why not? That seems like the correct fix to me, right? Sure, I can do that. Is it okay to change the if checks on the return code to "if (rc < 0)" instead of "if (rc)" as a fix for the immediate issue with how return value from rmem is handled which can be applied to older kernels. In a separate patch I can change the definition of nvmem_reg_read_t() to return ssize_t instead of int and make corresponding changes to nvmem-provider drivers. Does that sound okay ? > > thanks, > > greg k-h Thanks Joy
On Wed, Feb 7, 2024 at 8:33 PM Joy Chakraborty <joychakr@google.com> wrote: > > On Wed, Feb 7, 2024 at 3:04 PM Greg Kroah-Hartman > <gregkh@linuxfoundation.org> wrote: > > > > On Tue, Feb 06, 2024 at 05:22:15PM +0530, Joy Chakraborty wrote: > > > > > Userspace will see a false error with nvmem cell reads from > > > > > nvmem_cell_attr_read() in current code, which should be fixed on > > > > > returning 0 for success. > > > > > > > > So maybe fix this all up to allow the read to return the actual amount > > > > read? That feels more "correct" to me. > > > > > > > > > > If I change the behavior of the nvmem_reg_read_t callback to negative > > > for error and number of bytes actually read for success then, other > > > than the core driver I would also have to change all the > > > nvmem-provider drivers. > > > Is it okay to do so ? > > > > Sure, why not? That seems like the correct fix to me, right? > > Sure, I can do that. > > Is it okay to change the if checks on the return code to "if (rc < 0)" > instead of "if (rc)" as a fix for the immediate issue with how return > value from rmem is handled which can be applied to older kernels. > In a separate patch I can change the definition of nvmem_reg_read_t() > to return ssize_t instead of int and make corresponding changes to > nvmem-provider drivers. > > Does that sound okay ? Hi Greg, Sent a patch https://lore.kernel.org/all/20240219113149.2437990-2-joychakr@google.com/ to change the return type for read/write callbacks. Do I mark that with the "Fixes:" tag as well ? It affects a lot of files so might not be able to easily pick to an older kernel when needed. Thanks Joy > > > > thanks, > > > > greg k-h > > Thanks > Joy
On Tue, Feb 27, 2024 at 12:27:09PM +0530, Joy Chakraborty wrote: > On Wed, Feb 7, 2024 at 8:33 PM Joy Chakraborty <joychakr@google.com> wrote: > > > > On Wed, Feb 7, 2024 at 3:04 PM Greg Kroah-Hartman > > <gregkh@linuxfoundation.org> wrote: > > > > > > On Tue, Feb 06, 2024 at 05:22:15PM +0530, Joy Chakraborty wrote: > > > > > > Userspace will see a false error with nvmem cell reads from > > > > > > nvmem_cell_attr_read() in current code, which should be fixed on > > > > > > returning 0 for success. > > > > > > > > > > So maybe fix this all up to allow the read to return the actual amount > > > > > read? That feels more "correct" to me. > > > > > > > > > > > > > If I change the behavior of the nvmem_reg_read_t callback to negative > > > > for error and number of bytes actually read for success then, other > > > > than the core driver I would also have to change all the > > > > nvmem-provider drivers. > > > > Is it okay to do so ? > > > > > > Sure, why not? That seems like the correct fix to me, right? > > > > Sure, I can do that. > > > > Is it okay to change the if checks on the return code to "if (rc < 0)" > > instead of "if (rc)" as a fix for the immediate issue with how return > > value from rmem is handled which can be applied to older kernels. > > In a separate patch I can change the definition of nvmem_reg_read_t() > > to return ssize_t instead of int and make corresponding changes to > > nvmem-provider drivers. > > > > Does that sound okay ? > > Hi Greg, > > Sent a patch https://lore.kernel.org/all/20240219113149.2437990-2-joychakr@google.com/ > to change the return type for read/write callbacks. > Do I mark that with the "Fixes:" tag as well ? Is it actually fixing a bug? Or just evolving the api to be more correct over time? I think the latter. > It affects a lot of files so might not be able to easily pick to an > older kernel when needed. What is it fixing that older kernels need? And do not worry about stable kernels while doing development, only take that into consideration after your changes are accepted. thanks, greg k-h
diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c index 752d0bf4445e..a74dfa279ff4 100644 --- a/drivers/nvmem/rmem.c +++ b/drivers/nvmem/rmem.c @@ -46,7 +46,12 @@ static int rmem_read(void *context, unsigned int offset, memunmap(addr); - return count; + if (count != bytes) { + dev_err(priv->dev, "Failed read memory (%d)\n", count); + return -EINVAL; + } + + return 0; } static int rmem_probe(struct platform_device *pdev)