All of lore.kernel.org
 help / color / mirror / Atom feed
From: Orgad Shaneh <orgads@gmail.com>
To: miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com,
	tsbogend@alpha.franken.de
Cc: linux-mtd@lists.infradead.org, linux-mips@vger.kernel.org,
	linux-kernel@vger.kernel.org, linusw@kernel.org,
	kaloz@openwrt.org, ulli.kroll@googlemail.com, john@phrozen.org,
	nico@fluxnic.net, dwmw2@infradead.org, corbet@lwn.net,
	linux-doc@vger.kernel.org
Subject: [PATCH 1/3] mtd: maps: only point() maps read through the simple accessors
Date: Sat, 10 Oct 2026 17:21:40 +0000	[thread overview]
Message-ID: <20261010172142.2138956-2-orgads@gmail.com> (raw)
In-Reply-To: <20261010172142.2138956-1-orgads@gmail.com>

map_is_linear() only checks that a map has a physical address. Map
drivers that install their own accessors keep one, and a pointer
bypasses whatever those accessors do:

- physmap's IXP4xx support: the expansion bus only takes 16-bit
  accesses (the reason it cannot use memcpy_fromio()), and on
  little-endian kernels every access also flips address bit 1 and
  swaps bytes;
- physmap's Gemini support enables the flash pins only inside its
  accessors;
- lantiq-flash serializes the external bus against PCI and copies byte
  by byte because the EBU cannot take a prefetching memcpy;
- cobalt-flash reads at an offset inside a PCI BAR while leaving phys 0.

cfi_cmdset_0001 hands such pointers to jffs2 today, and the IXP4xx
boards carry Intel StrataFlash. Add map_is_simple(), true when the map
reads through the simple accessors (always true without
CONFIG_MTD_COMPLEX_MAPPINGS, where the accessors are inline), and
require it before enabling point(). Maps with custom accessors fall
back to copying through them; on big-endian IXP4xx, where pointed reads
happened to work, jffs2 mounts get slower.

Fixes: 9d3b5086f6d4 ("mtd: physmap_of_gemini: Handle pin control")
Fixes: 2aba2f2a704d ("mtd: physmap_of: add a hook for Intel IXP4xx flash probing")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Orgad Shaneh <orgads@gmail.com>
Cc: Linus Walleij <linusw@kernel.org>
Cc: Imre Kaloz <kaloz@openwrt.org>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: John Crispin <john@phrozen.org>
---
 drivers/mtd/chips/cfi_cmdset_0001.c |  2 +-
 drivers/mtd/maps/map_funcs.c        | 12 ++++++++++++
 include/linux/mtd/map.h             |  2 ++
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index b73596a..3f3364c 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -299,7 +299,7 @@ static void fixup_LH28F640BF(struct mtd_info *mtd)
 static void fixup_use_point(struct mtd_info *mtd)
 {
 	struct map_info *map = mtd->priv;
-	if (!mtd->_point && map_is_linear(map)) {
+	if (!mtd->_point && map_is_linear(map) && map_is_simple(map)) {
 		mtd->_point   = cfi_intelext_point;
 		mtd->_unpoint = cfi_intelext_unpoint;
 	}
diff --git a/drivers/mtd/maps/map_funcs.c b/drivers/mtd/maps/map_funcs.c
index 1a4add9..ccf1dbf 100644
--- a/drivers/mtd/maps/map_funcs.c
+++ b/drivers/mtd/maps/map_funcs.c
@@ -41,5 +41,17 @@ void simple_map_init(struct map_info *map)
 }
 
 EXPORT_SYMBOL(simple_map_init);
+
+/*
+ * True when every access goes through the simple accessors, so a reader
+ * may use map->virt directly; a map with its own accessors (byte swaps,
+ * bus locking, address fixups) must not be pointed at.
+ */
+bool map_is_simple(struct map_info *map)
+{
+	return map->read == simple_map_read &&
+	       map->copy_from == simple_map_copy_from;
+}
+EXPORT_SYMBOL(map_is_simple);
 MODULE_DESCRIPTION("Out-of-line map I/O");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 75b0b2a..ebee3fe 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -449,6 +449,7 @@ static inline void inline_map_copy_to(struct map_info *map, unsigned long to, co
 #define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)
 
 extern void simple_map_init(struct map_info *);
+bool map_is_simple(struct map_info *map);
 #define map_is_linear(map) (map->phys != NO_XIP)
 
 #else
@@ -460,6 +461,7 @@ extern void simple_map_init(struct map_info *);
 
 #define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth))
 #define map_is_linear(map) ({ (void)(map); 1; })
+#define map_is_simple(map) ({ (void)(map); 1; })
 
 #endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */
 
-- 
2.53.0


WARNING: multiple messages have this Message-ID (diff)
From: Orgad Shaneh <orgads@gmail.com>
To: miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com,
	tsbogend@alpha.franken.de
Cc: linux-mtd@lists.infradead.org, linux-mips@vger.kernel.org,
	linux-kernel@vger.kernel.org, linusw@kernel.org,
	kaloz@openwrt.org, ulli.kroll@googlemail.com, john@phrozen.org,
	nico@fluxnic.net, dwmw2@infradead.org, corbet@lwn.net,
	linux-doc@vger.kernel.org
Subject: [PATCH 1/3] mtd: maps: only point() maps read through the simple accessors
Date: Sat, 10 Oct 2026 17:21:40 +0000	[thread overview]
Message-ID: <20261010172142.2138956-2-orgads@gmail.com> (raw)
In-Reply-To: <20261010172142.2138956-1-orgads@gmail.com>

map_is_linear() only checks that a map has a physical address. Map
drivers that install their own accessors keep one, and a pointer
bypasses whatever those accessors do:

- physmap's IXP4xx support: the expansion bus only takes 16-bit
  accesses (the reason it cannot use memcpy_fromio()), and on
  little-endian kernels every access also flips address bit 1 and
  swaps bytes;
- physmap's Gemini support enables the flash pins only inside its
  accessors;
- lantiq-flash serializes the external bus against PCI and copies byte
  by byte because the EBU cannot take a prefetching memcpy;
- cobalt-flash reads at an offset inside a PCI BAR while leaving phys 0.

cfi_cmdset_0001 hands such pointers to jffs2 today, and the IXP4xx
boards carry Intel StrataFlash. Add map_is_simple(), true when the map
reads through the simple accessors (always true without
CONFIG_MTD_COMPLEX_MAPPINGS, where the accessors are inline), and
require it before enabling point(). Maps with custom accessors fall
back to copying through them; on big-endian IXP4xx, where pointed reads
happened to work, jffs2 mounts get slower.

Fixes: 9d3b5086f6d4 ("mtd: physmap_of_gemini: Handle pin control")
Fixes: 2aba2f2a704d ("mtd: physmap_of: add a hook for Intel IXP4xx flash probing")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Orgad Shaneh <orgads@gmail.com>
Cc: Linus Walleij <linusw@kernel.org>
Cc: Imre Kaloz <kaloz@openwrt.org>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: John Crispin <john@phrozen.org>
---
 drivers/mtd/chips/cfi_cmdset_0001.c |  2 +-
 drivers/mtd/maps/map_funcs.c        | 12 ++++++++++++
 include/linux/mtd/map.h             |  2 ++
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index b73596a..3f3364c 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -299,7 +299,7 @@ static void fixup_LH28F640BF(struct mtd_info *mtd)
 static void fixup_use_point(struct mtd_info *mtd)
 {
 	struct map_info *map = mtd->priv;
-	if (!mtd->_point && map_is_linear(map)) {
+	if (!mtd->_point && map_is_linear(map) && map_is_simple(map)) {
 		mtd->_point   = cfi_intelext_point;
 		mtd->_unpoint = cfi_intelext_unpoint;
 	}
diff --git a/drivers/mtd/maps/map_funcs.c b/drivers/mtd/maps/map_funcs.c
index 1a4add9..ccf1dbf 100644
--- a/drivers/mtd/maps/map_funcs.c
+++ b/drivers/mtd/maps/map_funcs.c
@@ -41,5 +41,17 @@ void simple_map_init(struct map_info *map)
 }
 
 EXPORT_SYMBOL(simple_map_init);
+
+/*
+ * True when every access goes through the simple accessors, so a reader
+ * may use map->virt directly; a map with its own accessors (byte swaps,
+ * bus locking, address fixups) must not be pointed at.
+ */
+bool map_is_simple(struct map_info *map)
+{
+	return map->read == simple_map_read &&
+	       map->copy_from == simple_map_copy_from;
+}
+EXPORT_SYMBOL(map_is_simple);
 MODULE_DESCRIPTION("Out-of-line map I/O");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 75b0b2a..ebee3fe 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -449,6 +449,7 @@ static inline void inline_map_copy_to(struct map_info *map, unsigned long to, co
 #define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)
 
 extern void simple_map_init(struct map_info *);
+bool map_is_simple(struct map_info *map);
 #define map_is_linear(map) (map->phys != NO_XIP)
 
 #else
@@ -460,6 +461,7 @@ extern void simple_map_init(struct map_info *);
 
 #define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth))
 #define map_is_linear(map) ({ (void)(map); 1; })
+#define map_is_simple(map) ({ (void)(map); 1; })
 
 #endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */
 
-- 
2.53.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

  reply	other threads:[~2026-10-10 17:21 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-10 17:21 [PATCH 0/3] mtd: point() for cfi_cmdset_0002, on simple maps only Orgad Shaneh
2026-10-10 17:21 ` Orgad Shaneh
2026-10-10 17:21 ` Orgad Shaneh [this message]
2026-10-10 17:21   ` [PATCH 1/3] mtd: maps: only point() maps read through the simple accessors Orgad Shaneh
2026-10-10 17:21 ` [PATCH 2/3] mtd: cfi_cmdset_0002: implement point() for simple linear maps Orgad Shaneh
2026-10-10 17:21   ` Orgad Shaneh
2026-10-10 17:31   ` sashiko-bot
2026-10-10 17:31     ` sashiko-bot
2026-10-10 17:21 ` [PATCH 3/3] MIPS: Octeon: flash: use the simple map accessors without a shared eMMC Orgad Shaneh
2026-10-10 17:21   ` Orgad Shaneh
2026-10-10 17:32   ` sashiko-bot
2026-10-10 17:32     ` sashiko-bot
2026-10-10 18:08 ` [PATCH v2 0/3] mtd: point() for cfi_cmdset_0002, on simple maps only Orgad Shaneh
2026-10-10 18:08   ` Orgad Shaneh
2026-10-10 18:08   ` [PATCH v2 1/3] mtd: maps: only point() maps read through the simple accessors Orgad Shaneh
2026-10-10 18:08     ` Orgad Shaneh
2026-10-10 18:08   ` [PATCH v2 2/3] mtd: cfi_cmdset_0002: implement point() for simple linear maps Orgad Shaneh
2026-10-10 18:08     ` Orgad Shaneh
2026-10-10 18:18     ` sashiko-bot
2026-10-10 18:18       ` sashiko-bot
2026-10-10 18:08   ` [PATCH v2 3/3] MIPS: Octeon: flash: use the simple map accessors without a shared eMMC Orgad Shaneh
2026-10-10 18:08     ` Orgad Shaneh
2026-10-10 18:18     ` sashiko-bot
2026-10-10 18:18       ` sashiko-bot
2026-10-11  6:29 ` [PATCH v3 0/3] mtd: point() for cfi_cmdset_0002, on simple maps only Orgad Shaneh
2026-10-11  6:29   ` Orgad Shaneh
2026-10-11  6:29   ` [PATCH v3 1/3] mtd: maps: only point() maps read through the simple accessors Orgad Shaneh
2026-10-11  6:29     ` Orgad Shaneh
2026-10-11  6:29   ` [PATCH v3 2/3] mtd: cfi_cmdset_0002: implement point() for simple linear maps Orgad Shaneh
2026-10-11  6:29     ` Orgad Shaneh
2026-10-11  6:29   ` [PATCH v3 3/3] MIPS: Octeon: flash: use the simple map accessors without a shared eMMC Orgad Shaneh
2026-10-11  6:29     ` Orgad Shaneh
2026-10-11  6:39     ` sashiko-bot
2026-10-11  6:39       ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261010172142.2138956-2-orgads@gmail.com \
    --to=orgads@gmail.com \
    --cc=corbet@lwn.net \
    --cc=dwmw2@infradead.org \
    --cc=john@phrozen.org \
    --cc=kaloz@openwrt.org \
    --cc=linusw@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=miquel.raynal@bootlin.com \
    --cc=nico@fluxnic.net \
    --cc=richard@nod.at \
    --cc=tsbogend@alpha.franken.de \
    --cc=ulli.kroll@googlemail.com \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.