linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/5] Read-only memremap()
@ 2019-09-10 16:08 Stephen Boyd
  2019-09-10 16:08 ` [PATCH v3 1/5] reserved_mem: Add a devm_memremap_reserved_mem() API Stephen Boyd
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Stephen Boyd @ 2019-09-10 16:08 UTC (permalink / raw)
  To: Dan Williams
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, devicetree,
	Evan Green, Rob Herring, Bjorn Andersson, Andy Gross,
	Will Deacon, Catalin Marinas

This patch series implements a read-only version of memremap() via
a new MEMREMAP_RO flag. If this is passed in the mapping call, we'll
try to map the memory region as read-only if it doesn't intersect
with an existing mapping. Otherwise, we'll try to fallback to other
flags to try to map the memory that way.

The main use case I have is to map the command-db memory region on
Qualcomm devices with a read-only mapping. It's already a const marked
pointer and the API returns const pointers as well, so this series makes
sure that even stray writes can't modify the memory. To get there we
introduce a devm version of memremap() for a reserved memory region, add
a memremap() flag, and implement support for that flag on arm64.

Changes from v2 (https://lkml.kernel.org/r/20190614203717.75479-1-swboyd@chromium.org):
 * Added a comment to kerneldoc for the new MEMREMAP_RO flag
 * Rebased to v5.3-rc1

Changes from v1:
 * Picked up tags and rebased to v5.2-rc3

Stephen Boyd (5):
  reserved_mem: Add a devm_memremap_reserved_mem() API
  soc: qcom: cmd-db: Migrate to devm_memremap_reserved_mem()
  memremap: Add support for read-only memory mappings
  arm64: Add support for arch_memremap_ro()
  soc: qcom: cmd-db: Map with read-only mappings

Cc: Evan Green <evgreen@chromium.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Andy Gross <agross@kernel.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>

 arch/arm64/include/asm/io.h     |  1 +
 drivers/of/of_reserved_mem.c    | 45 +++++++++++++++++++++++++++++++++
 drivers/soc/qcom/cmd-db.c       | 14 +++-------
 include/linux/io.h              |  1 +
 include/linux/of_reserved_mem.h |  6 +++++
 kernel/iomem.c                  | 20 ++++++++++++---
 6 files changed, 74 insertions(+), 13 deletions(-)


base-commit: 5f9e832c137075045d15cd6899ab0505cfb2ca4b
-- 
Sent by a computer through tubes


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v3 1/5] reserved_mem: Add a devm_memremap_reserved_mem() API
  2019-09-10 16:08 [PATCH v3 0/5] Read-only memremap() Stephen Boyd
@ 2019-09-10 16:08 ` Stephen Boyd
  2019-09-10 16:09 ` [PATCH v3 2/5] soc: qcom: cmd-db: Migrate to devm_memremap_reserved_mem() Stephen Boyd
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Stephen Boyd @ 2019-09-10 16:08 UTC (permalink / raw)
  To: Dan Williams
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, devicetree,
	Evan Green, Rob Herring, Bjorn Andersson, Andy Gross,
	Will Deacon, Catalin Marinas, Rob Herring

We have a few drivers that need to get a reserved memory region, request
the region, and map the reserved memory with memremap(). Add an API to
do this all in one function call.

Cc: Evan Green <evgreen@chromium.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Andy Gross <agross@kernel.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 drivers/of/of_reserved_mem.c    | 45 +++++++++++++++++++++++++++++++++
 include/linux/of_reserved_mem.h |  6 +++++
 2 files changed, 51 insertions(+)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 7989703b883c..b3899a2c74c4 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -12,6 +12,7 @@
 #define pr_fmt(fmt)	"OF: reserved mem: " fmt
 
 #include <linux/err.h>
+#include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
@@ -410,3 +411,47 @@ struct reserved_mem *of_reserved_mem_lookup(struct device_node *np)
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(of_reserved_mem_lookup);
+
+/**
+ * devm_memremap_reserved_mem() - acquire reserved_mem from a device node,
+ *                                request and memremap it
+ * @dev: device with node pointer of the desired reserved-memory region
+ * @flags: flags to pass to memremap()
+ *
+ * This function allows drivers to acquire a reference to the reserved_mem
+ * struct based on the device's device_node handle, request it and then
+ * memremap() it.
+ *
+ * Returns: A remapped reserved memory region, or an error pointer on failure.
+ */
+void *devm_memremap_reserved_mem(struct device *dev, unsigned long flags)
+{
+	void *dest_ptr;
+	struct reserved_mem *rmem;
+	struct resource *res;
+	const char *name;
+
+	rmem = of_reserved_mem_lookup(dev->of_node);
+	if (!rmem) {
+		dev_err(dev, "failed to acquire memory region\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	name = rmem->name ? : dev_name(dev);
+
+	res = devm_request_mem_region(dev, rmem->base, rmem->size, name);
+	if (!res) {
+		dev_err(dev, "can't request region for reserved memory\n");
+		return ERR_PTR(-EBUSY);
+	}
+
+	dest_ptr = devm_memremap(dev, rmem->base, rmem->size, flags);
+	if (!dest_ptr) {
+		dev_err(dev, "memremap failed for reserved memory\n");
+		devm_release_mem_region(dev, rmem->base, rmem->size);
+		dest_ptr = ERR_PTR(-ENOMEM);
+	}
+
+	return dest_ptr;
+}
+EXPORT_SYMBOL_GPL(devm_memremap_reserved_mem);
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index 60f541912ccf..a36be60ef67c 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -39,6 +39,7 @@ void fdt_init_reserved_mem(void);
 void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
 			       phys_addr_t base, phys_addr_t size);
 struct reserved_mem *of_reserved_mem_lookup(struct device_node *np);
+void *devm_memremap_reserved_mem(struct device *dev, unsigned long flags);
 #else
 static inline int of_reserved_mem_device_init_by_idx(struct device *dev,
 					struct device_node *np, int idx)
@@ -54,6 +55,11 @@ static inline struct reserved_mem *of_reserved_mem_lookup(struct device_node *np
 {
 	return NULL;
 }
+static inline void *devm_memremap_reserved_mem(struct device *dev,
+					       unsigned long flags)
+{
+	return NULL;
+}
 #endif
 
 /**
-- 
Sent by a computer through tubes


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v3 2/5] soc: qcom: cmd-db: Migrate to devm_memremap_reserved_mem()
  2019-09-10 16:08 [PATCH v3 0/5] Read-only memremap() Stephen Boyd
  2019-09-10 16:08 ` [PATCH v3 1/5] reserved_mem: Add a devm_memremap_reserved_mem() API Stephen Boyd
@ 2019-09-10 16:09 ` Stephen Boyd
  2019-09-10 16:09 ` [PATCH v3 3/5] memremap: Add support for read-only memory mappings Stephen Boyd
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Stephen Boyd @ 2019-09-10 16:09 UTC (permalink / raw)
  To: Dan Williams
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, devicetree,
	Evan Green, Rob Herring, Bjorn Andersson, Andy Gross,
	Will Deacon, Catalin Marinas

This gets rid of some duplicate code, and also makes the reserved memory
region show up as 'cmd-db' memory in /proc/iomem.

Cc: Evan Green <evgreen@chromium.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Andy Gross <agross@kernel.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 drivers/soc/qcom/cmd-db.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c
index f6c3d17b05c7..10a34d26b753 100644
--- a/drivers/soc/qcom/cmd-db.c
+++ b/drivers/soc/qcom/cmd-db.c
@@ -238,18 +238,11 @@ EXPORT_SYMBOL(cmd_db_read_slave_id);
 
 static int cmd_db_dev_probe(struct platform_device *pdev)
 {
-	struct reserved_mem *rmem;
 	int ret = 0;
 
-	rmem = of_reserved_mem_lookup(pdev->dev.of_node);
-	if (!rmem) {
-		dev_err(&pdev->dev, "failed to acquire memory region\n");
-		return -EINVAL;
-	}
-
-	cmd_db_header = memremap(rmem->base, rmem->size, MEMREMAP_WB);
-	if (!cmd_db_header) {
-		ret = -ENOMEM;
+	cmd_db_header = devm_memremap_reserved_mem(&pdev->dev, MEMREMAP_WB);
+	if (IS_ERR(cmd_db_header)) {
+		ret = PTR_ERR(cmd_db_header);
 		cmd_db_header = NULL;
 		return ret;
 	}
-- 
Sent by a computer through tubes


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v3 3/5] memremap: Add support for read-only memory mappings
  2019-09-10 16:08 [PATCH v3 0/5] Read-only memremap() Stephen Boyd
  2019-09-10 16:08 ` [PATCH v3 1/5] reserved_mem: Add a devm_memremap_reserved_mem() API Stephen Boyd
  2019-09-10 16:09 ` [PATCH v3 2/5] soc: qcom: cmd-db: Migrate to devm_memremap_reserved_mem() Stephen Boyd
@ 2019-09-10 16:09 ` Stephen Boyd
  2019-09-18 19:37   ` Evan Green
  2019-09-10 16:09 ` [PATCH v3 4/5] arm64: Add support for arch_memremap_ro() Stephen Boyd
  2019-09-10 16:09 ` [PATCH v3 5/5] soc: qcom: cmd-db: Map with read-only mappings Stephen Boyd
  4 siblings, 1 reply; 11+ messages in thread
From: Stephen Boyd @ 2019-09-10 16:09 UTC (permalink / raw)
  To: Dan Williams
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, devicetree,
	Evan Green, Rob Herring, Bjorn Andersson, Andy Gross,
	Will Deacon, Catalin Marinas

Sometimes we have memories that are supposed to be read-only, but when
we map these regions the best we can do is map them as write-back with
MEMREMAP_WB. Introduce a read-only memory mapping (MEMREMAP_RO) that
allows us to map reserved memory regions as read-only. This way, we're
less likely to see these special memory regions become corrupted by
stray writes to them.

Cc: Evan Green <evgreen@chromium.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Andy Gross <agross@kernel.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 include/linux/io.h |  1 +
 kernel/iomem.c     | 20 +++++++++++++++++---
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/include/linux/io.h b/include/linux/io.h
index accac822336a..15a63efcd153 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -148,6 +148,7 @@ enum {
 	MEMREMAP_WC = 1 << 2,
 	MEMREMAP_ENC = 1 << 3,
 	MEMREMAP_DEC = 1 << 4,
+	MEMREMAP_RO = 1 << 5,
 };
 
 void *memremap(resource_size_t offset, size_t size, unsigned long flags);
diff --git a/kernel/iomem.c b/kernel/iomem.c
index 62c92e43aa0d..6d76b7398714 100644
--- a/kernel/iomem.c
+++ b/kernel/iomem.c
@@ -19,6 +19,13 @@ static void *arch_memremap_wb(resource_size_t offset, unsigned long size)
 }
 #endif
 
+#ifndef arch_memremap_ro
+static void *arch_memremap_ro(resource_size_t offset, unsigned long size)
+{
+	return NULL;
+}
+#endif
+
 #ifndef arch_memremap_can_ram_remap
 static bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size,
 					unsigned long flags)
@@ -45,7 +52,7 @@ static void *try_ram_remap(resource_size_t offset, size_t size,
  * @offset: iomem resource start address
  * @size: size of remap
  * @flags: any of MEMREMAP_WB, MEMREMAP_WT, MEMREMAP_WC,
- *		  MEMREMAP_ENC, MEMREMAP_DEC
+ *		  MEMREMAP_ENC, MEMREMAP_DEC, MEMREMAP_RO
  *
  * memremap() is "ioremap" for cases where it is known that the resource
  * being mapped does not have i/o side effects and the __iomem
@@ -53,6 +60,9 @@ static void *try_ram_remap(resource_size_t offset, size_t size,
  * mapping types will be attempted in the order listed below until one of
  * them succeeds.
  *
+ * MEMREMAP_RO - establish a mapping whereby writes are ignored/rejected.
+ * Attempts to map System RAM with this mapping type will fail.
+ *
  * MEMREMAP_WB - matches the default mapping for System RAM on
  * the architecture.  This is usually a read-allocate write-back cache.
  * Moreover, if MEMREMAP_WB is specified and the requested remap region is RAM
@@ -84,7 +94,10 @@ void *memremap(resource_size_t offset, size_t size, unsigned long flags)
 	}
 
 	/* Try all mapping types requested until one returns non-NULL */
-	if (flags & MEMREMAP_WB) {
+	if ((flags & MEMREMAP_RO) && is_ram != REGION_INTERSECTS)
+		addr = arch_memremap_ro(offset, size);
+
+	if (!addr && (flags & MEMREMAP_WB)) {
 		/*
 		 * MEMREMAP_WB is special in that it can be satisfied
 		 * from the direct map.  Some archs depend on the
@@ -103,7 +116,8 @@ void *memremap(resource_size_t offset, size_t size, unsigned long flags)
 	 * address mapping.  Enforce that this mapping is not aliasing
 	 * System RAM.
 	 */
-	if (!addr && is_ram == REGION_INTERSECTS && flags != MEMREMAP_WB) {
+	if (!addr && is_ram == REGION_INTERSECTS &&
+	    (flags != MEMREMAP_WB || flags != MEMREMAP_RO)) {
 		WARN_ONCE(1, "memremap attempted on ram %pa size: %#lx\n",
 				&offset, (unsigned long) size);
 		return NULL;
-- 
Sent by a computer through tubes


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v3 4/5] arm64: Add support for arch_memremap_ro()
  2019-09-10 16:08 [PATCH v3 0/5] Read-only memremap() Stephen Boyd
                   ` (2 preceding siblings ...)
  2019-09-10 16:09 ` [PATCH v3 3/5] memremap: Add support for read-only memory mappings Stephen Boyd
@ 2019-09-10 16:09 ` Stephen Boyd
  2019-09-10 16:09 ` [PATCH v3 5/5] soc: qcom: cmd-db: Map with read-only mappings Stephen Boyd
  4 siblings, 0 replies; 11+ messages in thread
From: Stephen Boyd @ 2019-09-10 16:09 UTC (permalink / raw)
  To: Dan Williams
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, devicetree,
	Evan Green, Rob Herring, Bjorn Andersson, Andy Gross,
	Will Deacon, Catalin Marinas

Pass in PAGE_KERNEL_RO to the underlying IO mapping mechanism to get a
read-only mapping for the MEMREMAP_RO type of memory mappings that
memremap() supports.

Cc: Evan Green <evgreen@chromium.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Andy Gross <agross@kernel.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 arch/arm64/include/asm/io.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 7ed92626949d..c623e75d9152 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -172,6 +172,7 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
 #define ioremap_nocache(addr, size)	__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
 #define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
 #define ioremap_wt(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
+#define arch_memremap_ro(addr, size)	__ioremap((addr), (size), PAGE_KERNEL_RO)
 #define iounmap				__iounmap
 
 /*
-- 
Sent by a computer through tubes


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v3 5/5] soc: qcom: cmd-db: Map with read-only mappings
  2019-09-10 16:08 [PATCH v3 0/5] Read-only memremap() Stephen Boyd
                   ` (3 preceding siblings ...)
  2019-09-10 16:09 ` [PATCH v3 4/5] arm64: Add support for arch_memremap_ro() Stephen Boyd
@ 2019-09-10 16:09 ` Stephen Boyd
  2019-09-18 19:40   ` Evan Green
  4 siblings, 1 reply; 11+ messages in thread
From: Stephen Boyd @ 2019-09-10 16:09 UTC (permalink / raw)
  To: Dan Williams
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, devicetree,
	Evan Green, Rob Herring, Bjorn Andersson, Andy Gross,
	Will Deacon, Catalin Marinas

The command DB is read-only already to the kernel because everything is
const marked once we map it. Let's go one step further and try to map
the memory as read-only in the page tables. This should make it harder
for random code to corrupt the database and change the contents.

Cc: Evan Green <evgreen@chromium.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Andy Gross <agross@kernel.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
---
 drivers/soc/qcom/cmd-db.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c
index 10a34d26b753..6365e8260282 100644
--- a/drivers/soc/qcom/cmd-db.c
+++ b/drivers/soc/qcom/cmd-db.c
@@ -240,7 +240,8 @@ static int cmd_db_dev_probe(struct platform_device *pdev)
 {
 	int ret = 0;
 
-	cmd_db_header = devm_memremap_reserved_mem(&pdev->dev, MEMREMAP_WB);
+	cmd_db_header = devm_memremap_reserved_mem(&pdev->dev,
+						   MEMREMAP_RO | MEMREMAP_WB);
 	if (IS_ERR(cmd_db_header)) {
 		ret = PTR_ERR(cmd_db_header);
 		cmd_db_header = NULL;
-- 
Sent by a computer through tubes


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 3/5] memremap: Add support for read-only memory mappings
  2019-09-10 16:09 ` [PATCH v3 3/5] memremap: Add support for read-only memory mappings Stephen Boyd
@ 2019-09-18 19:37   ` Evan Green
  2019-10-03 18:56     ` Stephen Boyd
  0 siblings, 1 reply; 11+ messages in thread
From: Evan Green @ 2019-09-18 19:37 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Dan Williams, LKML, linux-arm-msm, linux-arm Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Rob Herring, Bjorn Andersson, Andy Gross, Will Deacon,
	Catalin Marinas

On Tue, Sep 10, 2019 at 9:09 AM Stephen Boyd <swboyd@chromium.org> wrote:
>
> Sometimes we have memories that are supposed to be read-only, but when
> we map these regions the best we can do is map them as write-back with
> MEMREMAP_WB. Introduce a read-only memory mapping (MEMREMAP_RO) that
> allows us to map reserved memory regions as read-only. This way, we're
> less likely to see these special memory regions become corrupted by
> stray writes to them.
>
> Cc: Evan Green <evgreen@chromium.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
> Cc: Andy Gross <agross@kernel.org>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Signed-off-by: Stephen Boyd <swboyd@chromium.org>
> ---
>  include/linux/io.h |  1 +
>  kernel/iomem.c     | 20 +++++++++++++++++---
>  2 files changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/include/linux/io.h b/include/linux/io.h
> index accac822336a..15a63efcd153 100644
> --- a/include/linux/io.h
> +++ b/include/linux/io.h
> @@ -148,6 +148,7 @@ enum {
>         MEMREMAP_WC = 1 << 2,
>         MEMREMAP_ENC = 1 << 3,
>         MEMREMAP_DEC = 1 << 4,
> +       MEMREMAP_RO = 1 << 5,
>  };
>
>  void *memremap(resource_size_t offset, size_t size, unsigned long flags);
> diff --git a/kernel/iomem.c b/kernel/iomem.c
> index 62c92e43aa0d..6d76b7398714 100644
> --- a/kernel/iomem.c
> +++ b/kernel/iomem.c
> @@ -19,6 +19,13 @@ static void *arch_memremap_wb(resource_size_t offset, unsigned long size)
>  }
>  #endif
>
> +#ifndef arch_memremap_ro
> +static void *arch_memremap_ro(resource_size_t offset, unsigned long size)
> +{
> +       return NULL;
> +}
> +#endif
> +
>  #ifndef arch_memremap_can_ram_remap
>  static bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size,
>                                         unsigned long flags)
> @@ -45,7 +52,7 @@ static void *try_ram_remap(resource_size_t offset, size_t size,
>   * @offset: iomem resource start address
>   * @size: size of remap
>   * @flags: any of MEMREMAP_WB, MEMREMAP_WT, MEMREMAP_WC,
> - *               MEMREMAP_ENC, MEMREMAP_DEC
> + *               MEMREMAP_ENC, MEMREMAP_DEC, MEMREMAP_RO
>   *
>   * memremap() is "ioremap" for cases where it is known that the resource
>   * being mapped does not have i/o side effects and the __iomem
> @@ -53,6 +60,9 @@ static void *try_ram_remap(resource_size_t offset, size_t size,
>   * mapping types will be attempted in the order listed below until one of
>   * them succeeds.
>   *
> + * MEMREMAP_RO - establish a mapping whereby writes are ignored/rejected.
> + * Attempts to map System RAM with this mapping type will fail.

Why should attempts to map RAM with this flag fail? MEMREMAP_WB will
allow RAM and quietly give you back the direct mapping, so it seems
like at least some values in this function allow RAM.

Oh, I see a comment below about "Enforce that this mapping is not
aliasing System RAM". I guess this is worried about cache coloring?
But is that a problem with RO mappings? I guess the RO mappings could
get partially stale, so if the memory were being updated out from
under you, you might see some updates but not others. Was that the
rationale?

> + *
>   * MEMREMAP_WB - matches the default mapping for System RAM on
>   * the architecture.  This is usually a read-allocate write-back cache.
>   * Moreover, if MEMREMAP_WB is specified and the requested remap region is RAM
> @@ -84,7 +94,10 @@ void *memremap(resource_size_t offset, size_t size, unsigned long flags)
>         }
>
>         /* Try all mapping types requested until one returns non-NULL */
> -       if (flags & MEMREMAP_WB) {
> +       if ((flags & MEMREMAP_RO) && is_ram != REGION_INTERSECTS)
> +               addr = arch_memremap_ro(offset, size);
> +
> +       if (!addr && (flags & MEMREMAP_WB)) {
>                 /*
>                  * MEMREMAP_WB is special in that it can be satisfied
>                  * from the direct map.  Some archs depend on the
> @@ -103,7 +116,8 @@ void *memremap(resource_size_t offset, size_t size, unsigned long flags)
>          * address mapping.  Enforce that this mapping is not aliasing
>          * System RAM.
>          */
> -       if (!addr && is_ram == REGION_INTERSECTS && flags != MEMREMAP_WB) {
> +       if (!addr && is_ram == REGION_INTERSECTS &&
> +           (flags != MEMREMAP_WB || flags != MEMREMAP_RO)) {

Isn't this condition always true? Did you mean flags != MEM_REMAP_WB
&& flags != MEMREMAP_RO?

>                 WARN_ONCE(1, "memremap attempted on ram %pa size: %#lx\n",
>                                 &offset, (unsigned long) size);
>                 return NULL;
> --
> Sent by a computer through tubes
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 5/5] soc: qcom: cmd-db: Map with read-only mappings
  2019-09-10 16:09 ` [PATCH v3 5/5] soc: qcom: cmd-db: Map with read-only mappings Stephen Boyd
@ 2019-09-18 19:40   ` Evan Green
  0 siblings, 0 replies; 11+ messages in thread
From: Evan Green @ 2019-09-18 19:40 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Dan Williams, LKML, linux-arm-msm, linux-arm Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Rob Herring, Bjorn Andersson, Andy Gross, Will Deacon,
	Catalin Marinas

On Tue, Sep 10, 2019 at 9:09 AM Stephen Boyd <swboyd@chromium.org> wrote:
>
> The command DB is read-only already to the kernel because everything is
> const marked once we map it. Let's go one step further and try to map
> the memory as read-only in the page tables. This should make it harder
> for random code to corrupt the database and change the contents.
>
> Cc: Evan Green <evgreen@chromium.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
> Cc: Andy Gross <agross@kernel.org>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Signed-off-by: Stephen Boyd <swboyd@chromium.org>
> ---
>  drivers/soc/qcom/cmd-db.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c
> index 10a34d26b753..6365e8260282 100644
> --- a/drivers/soc/qcom/cmd-db.c
> +++ b/drivers/soc/qcom/cmd-db.c
> @@ -240,7 +240,8 @@ static int cmd_db_dev_probe(struct platform_device *pdev)
>  {
>         int ret = 0;
>
> -       cmd_db_header = devm_memremap_reserved_mem(&pdev->dev, MEMREMAP_WB);
> +       cmd_db_header = devm_memremap_reserved_mem(&pdev->dev,
> +                                                  MEMREMAP_RO | MEMREMAP_WB);

It seems weird to have both flags, like: "It's read-only, but if it
ever did get written to somehow, make it writeback".

>         if (IS_ERR(cmd_db_header)) {
>                 ret = PTR_ERR(cmd_db_header);
>                 cmd_db_header = NULL;
> --
> Sent by a computer through tubes
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 3/5] memremap: Add support for read-only memory mappings
  2019-09-18 19:37   ` Evan Green
@ 2019-10-03 18:56     ` Stephen Boyd
  2019-10-03 20:05       ` Evan Green
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Boyd @ 2019-10-03 18:56 UTC (permalink / raw)
  To: Evan Green
  Cc: Dan Williams, LKML, linux-arm-msm, linux-arm Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Rob Herring, Bjorn Andersson, Andy Gross, Will Deacon,
	Catalin Marinas

Quoting Evan Green (2019-09-18 12:37:34)
> On Tue, Sep 10, 2019 at 9:09 AM Stephen Boyd <swboyd@chromium.org> wrote:
> >
> > @@ -53,6 +60,9 @@ static void *try_ram_remap(resource_size_t offset, size_t size,
> >   * mapping types will be attempted in the order listed below until one of
> >   * them succeeds.
> >   *
> > + * MEMREMAP_RO - establish a mapping whereby writes are ignored/rejected.
> > + * Attempts to map System RAM with this mapping type will fail.
> 
> Why should attempts to map RAM with this flag fail? MEMREMAP_WB will
> allow RAM and quietly give you back the direct mapping, so it seems
> like at least some values in this function allow RAM.
> 
> Oh, I see a comment below about "Enforce that this mapping is not
> aliasing System RAM". I guess this is worried about cache coloring?
> But is that a problem with RO mappings? I guess the RO mappings could
> get partially stale, so if the memory were being updated out from
> under you, you might see some updates but not others. Was that the
> rationale?

Will Deacon, Dan Williams, and I talked about this RO flag at LPC and I
believe we decided to mostly get rid of the flags argument to this
function. The vast majority of callers pass MEMREMAP_WB, so I'll just
make that be the implementation default and support the flags for
encrpytion (MEMREMAP_ENC and MEMREMAP_DEC). There are a few callers that
pass MEMREMAP_WC or MEMREMAP_WT (and one that passes all of them), but I
believe those can be changed to MEMREMAP_WB and not care. There's also
the efi framebuffer code that matches the memory attributes in the EFI
memory map. I'm not sure what to do with that one to be quite honest.
Maybe EFI shouldn't care and just use whatever is already there in the
mapping?

Either way, I'll introduce a memremap_ro() API that maps memory as read
only if possible and return a const void pointer as well. I'm debating
making that API fallback to memremap() if RO isn't supported for some
reason or can't work because we're remapping system memory but that
seems a little too nice when the caller could just as well decide to
fail if memory can't be mapped as read only.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 3/5] memremap: Add support for read-only memory mappings
  2019-10-03 18:56     ` Stephen Boyd
@ 2019-10-03 20:05       ` Evan Green
  2019-10-04 10:36         ` Brian Starkey
  0 siblings, 1 reply; 11+ messages in thread
From: Evan Green @ 2019-10-03 20:05 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Dan Williams, LKML, linux-arm-msm, linux-arm Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Rob Herring, Bjorn Andersson, Andy Gross, Will Deacon,
	Catalin Marinas

On Thu, Oct 3, 2019 at 11:56 AM Stephen Boyd <swboyd@chromium.org> wrote:
>
> Quoting Evan Green (2019-09-18 12:37:34)
> > On Tue, Sep 10, 2019 at 9:09 AM Stephen Boyd <swboyd@chromium.org> wrote:
> > >
> > > @@ -53,6 +60,9 @@ static void *try_ram_remap(resource_size_t offset, size_t size,
> > >   * mapping types will be attempted in the order listed below until one of
> > >   * them succeeds.
> > >   *
> > > + * MEMREMAP_RO - establish a mapping whereby writes are ignored/rejected.
> > > + * Attempts to map System RAM with this mapping type will fail.
> >
> > Why should attempts to map RAM with this flag fail? MEMREMAP_WB will
> > allow RAM and quietly give you back the direct mapping, so it seems
> > like at least some values in this function allow RAM.
> >
> > Oh, I see a comment below about "Enforce that this mapping is not
> > aliasing System RAM". I guess this is worried about cache coloring?
> > But is that a problem with RO mappings? I guess the RO mappings could
> > get partially stale, so if the memory were being updated out from
> > under you, you might see some updates but not others. Was that the
> > rationale?
>
> Will Deacon, Dan Williams, and I talked about this RO flag at LPC and I
> believe we decided to mostly get rid of the flags argument to this
> function. The vast majority of callers pass MEMREMAP_WB, so I'll just
> make that be the implementation default and support the flags for
> encrpytion (MEMREMAP_ENC and MEMREMAP_DEC). There are a few callers that
> pass MEMREMAP_WC or MEMREMAP_WT (and one that passes all of them), but I
> believe those can be changed to MEMREMAP_WB and not care. There's also
> the efi framebuffer code that matches the memory attributes in the EFI
> memory map. I'm not sure what to do with that one to be quite honest.
> Maybe EFI shouldn't care and just use whatever is already there in the
> mapping?

I would guess that the folks mapping things like framebuffers would
care if their write-combined memory were changed to writeback. But I
suppose the better authorities on that are already here, so if they
think it's fine, I guess it's all good.

Whatever logic is used to defend that would likely apply equally well
to the EFI mappings.

>
> Either way, I'll introduce a memremap_ro() API that maps memory as read
> only if possible and return a const void pointer as well. I'm debating
> making that API fallback to memremap() if RO isn't supported for some
> reason or can't work because we're remapping system memory but that
> seems a little too nice when the caller could just as well decide to
> fail if memory can't be mapped as read only.

Sounds good. My small vote would be for the nicer fallback to
memremap(). I can't think of a case where someone would rather not
have their memory mapped at all than have it mapped writeable.
-Evan

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 3/5] memremap: Add support for read-only memory mappings
  2019-10-03 20:05       ` Evan Green
@ 2019-10-04 10:36         ` Brian Starkey
  0 siblings, 0 replies; 11+ messages in thread
From: Brian Starkey @ 2019-10-04 10:36 UTC (permalink / raw)
  To: Evan Green
  Cc: Stephen Boyd,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-arm-msm, Will Deacon, LKML, Bjorn Andersson, Rob Herring,
	Andy Gross, Catalin Marinas, Dan Williams,
	linux-arm Mailing List, nd

Hi,

On Thu, Oct 03, 2019 at 01:05:53PM -0700, Evan Green wrote:
> On Thu, Oct 3, 2019 at 11:56 AM Stephen Boyd <swboyd@chromium.org> wrote:
> >
> > Quoting Evan Green (2019-09-18 12:37:34)
> > > On Tue, Sep 10, 2019 at 9:09 AM Stephen Boyd <swboyd@chromium.org> wrote:
> > > >
> > > > @@ -53,6 +60,9 @@ static void *try_ram_remap(resource_size_t offset, size_t size,
> > > >   * mapping types will be attempted in the order listed below until one of
> > > >   * them succeeds.
> > > >   *
> > > > + * MEMREMAP_RO - establish a mapping whereby writes are ignored/rejected.
> > > > + * Attempts to map System RAM with this mapping type will fail.
> > >
> > > Why should attempts to map RAM with this flag fail? MEMREMAP_WB will
> > > allow RAM and quietly give you back the direct mapping, so it seems
> > > like at least some values in this function allow RAM.
> > >
> > > Oh, I see a comment below about "Enforce that this mapping is not
> > > aliasing System RAM". I guess this is worried about cache coloring?
> > > But is that a problem with RO mappings? I guess the RO mappings could
> > > get partially stale, so if the memory were being updated out from
> > > under you, you might see some updates but not others. Was that the
> > > rationale?
> >
> > Will Deacon, Dan Williams, and I talked about this RO flag at LPC and I
> > believe we decided to mostly get rid of the flags argument to this
> > function. The vast majority of callers pass MEMREMAP_WB, so I'll just
> > make that be the implementation default and support the flags for
> > encrpytion (MEMREMAP_ENC and MEMREMAP_DEC). There are a few callers that
> > pass MEMREMAP_WC or MEMREMAP_WT (and one that passes all of them), but I
> > believe those can be changed to MEMREMAP_WB and not care. There's also
> > the efi framebuffer code that matches the memory attributes in the EFI
> > memory map. I'm not sure what to do with that one to be quite honest.
> > Maybe EFI shouldn't care and just use whatever is already there in the
> > mapping?
> 
> I would guess that the folks mapping things like framebuffers would
> care if their write-combined memory were changed to writeback. But I
> suppose the better authorities on that are already here, so if they
> think it's fine, I guess it's all good.

Drive-by comment as this happened to hit one of my hotword filters:

dma_init_coherent_memory() uses MEMREMAP_WC, and I think MEMREMAP_WB
would be quite unsuitable there. As you say, we use that for
framebuffers.

Thanks,
-Brian

> 
> Whatever logic is used to defend that would likely apply equally well
> to the EFI mappings.
> 
> >
> > Either way, I'll introduce a memremap_ro() API that maps memory as read
> > only if possible and return a const void pointer as well. I'm debating
> > making that API fallback to memremap() if RO isn't supported for some
> > reason or can't work because we're remapping system memory but that
> > seems a little too nice when the caller could just as well decide to
> > fail if memory can't be mapped as read only.
> 
> Sounds good. My small vote would be for the nicer fallback to
> memremap(). I can't think of a case where someone would rather not
> have their memory mapped at all than have it mapped writeable.
> -Evan
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-10-04 10:36 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-10 16:08 [PATCH v3 0/5] Read-only memremap() Stephen Boyd
2019-09-10 16:08 ` [PATCH v3 1/5] reserved_mem: Add a devm_memremap_reserved_mem() API Stephen Boyd
2019-09-10 16:09 ` [PATCH v3 2/5] soc: qcom: cmd-db: Migrate to devm_memremap_reserved_mem() Stephen Boyd
2019-09-10 16:09 ` [PATCH v3 3/5] memremap: Add support for read-only memory mappings Stephen Boyd
2019-09-18 19:37   ` Evan Green
2019-10-03 18:56     ` Stephen Boyd
2019-10-03 20:05       ` Evan Green
2019-10-04 10:36         ` Brian Starkey
2019-09-10 16:09 ` [PATCH v3 4/5] arm64: Add support for arch_memremap_ro() Stephen Boyd
2019-09-10 16:09 ` [PATCH v3 5/5] soc: qcom: cmd-db: Map with read-only mappings Stephen Boyd
2019-09-18 19:40   ` Evan Green

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).