* [PATCH 01/10] resource: add flags parameter to __request_region
2022-08-15 15:31 [PATCH 00/10] ARM: mmu: inhibit speculation into secure memory Ahmad Fatoum
@ 2022-08-15 15:32 ` Ahmad Fatoum
2022-08-15 15:32 ` [PATCH 02/10] common: allow requesting SDRAM regions with custom flags Ahmad Fatoum
` (8 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-15 15:32 UTC (permalink / raw)
To: barebox; +Cc: rcz, Ahmad Fatoum
__request_region allocates a child resource within the parent resource,
which so far always had a flags field of zero. Later commits will
use the flags field to mark reserved SDRAM regions, so MMU init code can
take that into consideration and ensure that CPU doesn't speculate into
these regions and risk aborts. Prepare for this by giving
__request_region a flags parameter.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/memory.c | 4 ++--
common/resource.c | 13 +++++++------
include/linux/ioport.h | 4 ++--
3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/common/memory.c b/common/memory.c
index fd782c7f24f6..03fec1f1eb0e 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -208,8 +208,8 @@ struct resource *request_sdram_region(const char *name, resource_size_t start,
for_each_memory_bank(bank) {
struct resource *res;
- res = __request_region(bank->res, name, start,
- start + size - 1);
+ res = __request_region(bank->res, start, start + size - 1,
+ name, 0);
if (!IS_ERR(res))
return res;
}
diff --git a/common/resource.c b/common/resource.c
index f96cb94b5074..81f337668ef1 100644
--- a/common/resource.c
+++ b/common/resource.c
@@ -28,8 +28,8 @@ static int init_resource(struct resource *res, const char *name)
* resources.
*/
struct resource *__request_region(struct resource *parent,
- const char *name, resource_size_t start,
- resource_size_t end)
+ resource_size_t start, resource_size_t end,
+ const char *name, unsigned flags)
{
struct resource *r, *new;
@@ -73,15 +73,16 @@ struct resource *__request_region(struct resource *parent,
}
ok:
- debug("%s ok: 0x%08llx:0x%08llx\n", __func__,
+ debug("%s ok: 0x%08llx:0x%08llx flags=%u\n", __func__,
(unsigned long long)start,
- (unsigned long long)end);
+ (unsigned long long)end, flags);
new = xzalloc(sizeof(*new));
init_resource(new, name);
new->start = start;
new->end = end;
new->parent = parent;
+ new->flags = flags;
list_add_tail(&new->sibling, &r->sibling);
return new;
@@ -138,7 +139,7 @@ struct resource iomem_resource = {
struct resource *request_iomem_region(const char *name,
resource_size_t start, resource_size_t end)
{
- return __request_region(&iomem_resource, name, start, end);
+ return __request_region(&iomem_resource, start, end, name, 0);
}
/* The root resource for the whole io-mapped io space */
@@ -157,7 +158,7 @@ struct resource *request_ioport_region(const char *name,
{
struct resource *res;
- res = __request_region(&ioport_resource, name, start, end);
+ res = __request_region(&ioport_resource, start, end, name, 0);
if (IS_ERR(res))
return ERR_CAST(res);
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index ee9587ba0feb..c6328e9a7fc2 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -155,8 +155,8 @@ struct resource *request_ioport_region(const char *name,
resource_size_t start, resource_size_t end);
struct resource *__request_region(struct resource *parent,
- const char *name, resource_size_t end,
- resource_size_t size);
+ resource_size_t start, resource_size_t end,
+ const char *name, unsigned flags);
int __merge_regions(const char *name,
struct resource *resa, struct resource *resb);
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 02/10] common: allow requesting SDRAM regions with custom flags
2022-08-15 15:31 [PATCH 00/10] ARM: mmu: inhibit speculation into secure memory Ahmad Fatoum
2022-08-15 15:32 ` [PATCH 01/10] resource: add flags parameter to __request_region Ahmad Fatoum
@ 2022-08-15 15:32 ` Ahmad Fatoum
2022-08-16 7:35 ` Ulrich Ölmann
2022-08-15 15:32 ` [PATCH 03/10] memory: define reserve_sdram_region helper Ahmad Fatoum
` (7 subsequent siblings)
9 siblings, 1 reply; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-15 15:32 UTC (permalink / raw)
To: barebox; +Cc: rcz, Ahmad Fatoum
Now that __request_region accepts a flag parameter, define
__request_sdram_region, which also accepts a flag parameter and passes
it through. The default flags for request_sdram_region() will be
IORESOURCE_MEM as that ensures resource_contains behaves correctly when
comparing against another memory resource.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/memory.c | 8 +++++---
common/resource.c | 2 +-
include/memory.h | 13 +++++++++++--
3 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/common/memory.c b/common/memory.c
index 03fec1f1eb0e..347f83fd4cf8 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -200,16 +200,18 @@ mmu_initcall(add_mem_devices);
/*
* Request a region from the registered sdram
*/
-struct resource *request_sdram_region(const char *name, resource_size_t start,
- resource_size_t size)
+struct resource *__request_sdram_region(const char *name, unsigned flags,
+ resource_size_t start, resource_size_t size)
{
struct memory_bank *bank;
+ flags |= IORESOURCE_MEM;
+
for_each_memory_bank(bank) {
struct resource *res;
res = __request_region(bank->res, start, start + size - 1,
- name, 0);
+ name, flags);
if (!IS_ERR(res))
return res;
}
diff --git a/common/resource.c b/common/resource.c
index 81f337668ef1..8678609229ab 100644
--- a/common/resource.c
+++ b/common/resource.c
@@ -73,7 +73,7 @@ struct resource *__request_region(struct resource *parent,
}
ok:
- debug("%s ok: 0x%08llx:0x%08llx flags=%u\n", __func__,
+ debug("%s ok: 0x%08llx:0x%08llx flags=0x%x\n", __func__,
(unsigned long long)start,
(unsigned long long)end, flags);
diff --git a/include/memory.h b/include/memory.h
index c793bb51ed77..31da5d74d568 100644
--- a/include/memory.h
+++ b/include/memory.h
@@ -23,8 +23,17 @@ int barebox_add_memory_bank(const char *name, resource_size_t start,
#define for_each_memory_bank(mem) list_for_each_entry(mem, &memory_banks, list)
-struct resource *request_sdram_region(const char *name, resource_size_t start,
- resource_size_t size);
+struct resource *__request_sdram_region(const char *name, unsigned flags,
+ resource_size_t start, resource_size_t size);
+
+static inline struct resource *request_sdram_region(const char *name,
+ resource_size_t start,
+ resource_size_t size)
+{
+ /* IORESOURCE_MEM is implicit for all SDRAM regions */
+ return __request_sdram_region(name, 0, start, size);
+}
+
int release_sdram_region(struct resource *res);
void memory_bank_find_space(struct memory_bank *bank, resource_size_t *retstart,
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 02/10] common: allow requesting SDRAM regions with custom flags
2022-08-15 15:32 ` [PATCH 02/10] common: allow requesting SDRAM regions with custom flags Ahmad Fatoum
@ 2022-08-16 7:35 ` Ulrich Ölmann
0 siblings, 0 replies; 13+ messages in thread
From: Ulrich Ölmann @ 2022-08-16 7:35 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: rcz, barebox
Hi Ahmad,
On Mon, Aug 15 2022 at 17:32 +0200, Ahmad Fatoum <a.fatoum@pengutronix.de> wrote:
> Now that __request_region accepts a flag parameter, define
> __request_sdram_region, which also accepts a flag parameter and passes
> it through. The default flags for request_sdram_region() will be
> IORESOURCE_MEM as that ensures resource_contains behaves correctly when
> comparing against another memory resource.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> common/memory.c | 8 +++++---
> common/resource.c | 2 +-
> include/memory.h | 13 +++++++++++--
> 3 files changed, 17 insertions(+), 6 deletions(-)
>
> diff --git a/common/memory.c b/common/memory.c
> index 03fec1f1eb0e..347f83fd4cf8 100644
> --- a/common/memory.c
> +++ b/common/memory.c
> @@ -200,16 +200,18 @@ mmu_initcall(add_mem_devices);
> /*
> * Request a region from the registered sdram
> */
> -struct resource *request_sdram_region(const char *name, resource_size_t start,
> - resource_size_t size)
> +struct resource *__request_sdram_region(const char *name, unsigned flags,
> + resource_size_t start, resource_size_t size)
> {
> struct memory_bank *bank;
>
> + flags |= IORESOURCE_MEM;
> +
> for_each_memory_bank(bank) {
> struct resource *res;
>
> res = __request_region(bank->res, start, start + size - 1,
> - name, 0);
> + name, flags);
> if (!IS_ERR(res))
> return res;
> }
> diff --git a/common/resource.c b/common/resource.c
> index 81f337668ef1..8678609229ab 100644
> --- a/common/resource.c
> +++ b/common/resource.c
> @@ -73,7 +73,7 @@ struct resource *__request_region(struct resource *parent,
> }
>
> ok:
> - debug("%s ok: 0x%08llx:0x%08llx flags=%u\n", __func__,
> + debug("%s ok: 0x%08llx:0x%08llx flags=0x%x\n", __func__,
this hunk should be squashed/amended into patch 01/10 where the flags
parameter has originally been introduced into this debug message.
Best regards
Ulrich
> (unsigned long long)start,
> (unsigned long long)end, flags);
>
> diff --git a/include/memory.h b/include/memory.h
> index c793bb51ed77..31da5d74d568 100644
> --- a/include/memory.h
> +++ b/include/memory.h
> @@ -23,8 +23,17 @@ int barebox_add_memory_bank(const char *name, resource_size_t start,
>
> #define for_each_memory_bank(mem) list_for_each_entry(mem, &memory_banks, list)
>
> -struct resource *request_sdram_region(const char *name, resource_size_t start,
> - resource_size_t size);
> +struct resource *__request_sdram_region(const char *name, unsigned flags,
> + resource_size_t start, resource_size_t size);
> +
> +static inline struct resource *request_sdram_region(const char *name,
> + resource_size_t start,
> + resource_size_t size)
> +{
> + /* IORESOURCE_MEM is implicit for all SDRAM regions */
> + return __request_sdram_region(name, 0, start, size);
> +}
> +
> int release_sdram_region(struct resource *res);
>
> void memory_bank_find_space(struct memory_bank *bank, resource_size_t *retstart,
--
Pengutronix e.K. | Ulrich Ölmann |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 03/10] memory: define reserve_sdram_region helper
2022-08-15 15:31 [PATCH 00/10] ARM: mmu: inhibit speculation into secure memory Ahmad Fatoum
2022-08-15 15:32 ` [PATCH 01/10] resource: add flags parameter to __request_region Ahmad Fatoum
2022-08-15 15:32 ` [PATCH 02/10] common: allow requesting SDRAM regions with custom flags Ahmad Fatoum
@ 2022-08-15 15:32 ` Ahmad Fatoum
2022-08-16 8:46 ` Sascha Hauer
2022-08-15 15:32 ` [PATCH 04/10] init: define new postmem_initcall() Ahmad Fatoum
` (6 subsequent siblings)
9 siblings, 1 reply; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-15 15:32 UTC (permalink / raw)
To: barebox; +Cc: rcz, Ahmad Fatoum
We use request_sdram_regions both for code that barebox wants to use for
itself (e.g. barebox stack or initrd) and to reserve regions for secure
firmware that barebox shouldn't overwrite. We need to differentiate
between them, so we can apply difference caching flags depending on
region, so add a new reserve_sdram_region helper that may be used and
also add an for_each_reserved_region iterator for use in the MMU code
that applied the different caching flags later on.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
include/memory.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/include/memory.h b/include/memory.h
index 31da5d74d568..ffd66db02ba0 100644
--- a/include/memory.h
+++ b/include/memory.h
@@ -4,6 +4,7 @@
#include <linux/types.h>
#include <linux/list.h>
+#include <linux/ioport.h>
void mem_malloc_init(void *start, void *end);
ulong mem_malloc_start(void);
@@ -22,6 +23,9 @@ int barebox_add_memory_bank(const char *name, resource_size_t start,
resource_size_t size);
#define for_each_memory_bank(mem) list_for_each_entry(mem, &memory_banks, list)
+#define for_each_reserved_region(mem, rsv) \
+ list_for_each_entry(rsv, &(mem)->res->children, sibling) \
+ if (((rsv)->flags & IORESOURCE_BUSY))
struct resource *__request_sdram_region(const char *name, unsigned flags,
resource_size_t start, resource_size_t size);
@@ -34,6 +38,14 @@ static inline struct resource *request_sdram_region(const char *name,
return __request_sdram_region(name, 0, start, size);
}
+/* use for secure firmware to inhibit speculation */
+static inline struct resource *reserve_sdram_region(const char *name,
+ resource_size_t start,
+ resource_size_t size)
+{
+ return __request_sdram_region(name, IORESOURCE_BUSY, start, size);
+}
+
int release_sdram_region(struct resource *res);
void memory_bank_find_space(struct memory_bank *bank, resource_size_t *retstart,
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 03/10] memory: define reserve_sdram_region helper
2022-08-15 15:32 ` [PATCH 03/10] memory: define reserve_sdram_region helper Ahmad Fatoum
@ 2022-08-16 8:46 ` Sascha Hauer
0 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2022-08-16 8:46 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox, rcz
On Mon, Aug 15, 2022 at 05:32:02PM +0200, Ahmad Fatoum wrote:
> We use request_sdram_regions both for code that barebox wants to use for
> itself (e.g. barebox stack or initrd) and to reserve regions for secure
> firmware that barebox shouldn't overwrite. We need to differentiate
> between them, so we can apply difference caching flags depending on
s/difference/different/
Sascha
> region, so add a new reserve_sdram_region helper that may be used and
> also add an for_each_reserved_region iterator for use in the MMU code
> that applied the different caching flags later on.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> include/memory.h | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/include/memory.h b/include/memory.h
> index 31da5d74d568..ffd66db02ba0 100644
> --- a/include/memory.h
> +++ b/include/memory.h
> @@ -4,6 +4,7 @@
>
> #include <linux/types.h>
> #include <linux/list.h>
> +#include <linux/ioport.h>
>
> void mem_malloc_init(void *start, void *end);
> ulong mem_malloc_start(void);
> @@ -22,6 +23,9 @@ int barebox_add_memory_bank(const char *name, resource_size_t start,
> resource_size_t size);
>
> #define for_each_memory_bank(mem) list_for_each_entry(mem, &memory_banks, list)
> +#define for_each_reserved_region(mem, rsv) \
> + list_for_each_entry(rsv, &(mem)->res->children, sibling) \
> + if (((rsv)->flags & IORESOURCE_BUSY))
>
> struct resource *__request_sdram_region(const char *name, unsigned flags,
> resource_size_t start, resource_size_t size);
> @@ -34,6 +38,14 @@ static inline struct resource *request_sdram_region(const char *name,
> return __request_sdram_region(name, 0, start, size);
> }
>
> +/* use for secure firmware to inhibit speculation */
> +static inline struct resource *reserve_sdram_region(const char *name,
> + resource_size_t start,
> + resource_size_t size)
> +{
> + return __request_sdram_region(name, IORESOURCE_BUSY, start, size);
> +}
> +
> int release_sdram_region(struct resource *res);
>
> void memory_bank_find_space(struct memory_bank *bank, resource_size_t *retstart,
> --
> 2.30.2
>
>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 04/10] init: define new postmem_initcall()
2022-08-15 15:31 [PATCH 00/10] ARM: mmu: inhibit speculation into secure memory Ahmad Fatoum
` (2 preceding siblings ...)
2022-08-15 15:32 ` [PATCH 03/10] memory: define reserve_sdram_region helper Ahmad Fatoum
@ 2022-08-15 15:32 ` Ahmad Fatoum
2022-08-15 15:32 ` [PATCH 05/10] of: reserved-mem: reserve regions prior to mmu_initcall() Ahmad Fatoum
` (5 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-15 15:32 UTC (permalink / raw)
To: barebox; +Cc: rcz, Ahmad Fatoum
Memory banks are added in mem_initcall() and are used in mmu_initcall()
which directly follows it to set caching attributes for the banks.
Code that requires memory banks to be registered, thus has to use
mmu_initcall(), but this is not possible for code that reliably needs to
run before MMU init: We need to give board code and device tree parsing
code the chance to reserve_sdram_region parts of SDRAM that contain
secure firmware to avoid speculative execution into them once the MMU is
turned on. For this reason, define a new postmem_initcall() level and
already use it for add_mem_devices, which has nothing to do with
mmu_initcall. Another user that can't be mmu_initcall() will follow in a
later commit.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/memory.c | 2 +-
include/asm-generic/barebox.lds.h | 1 +
include/init.h | 21 +++++++++++----------
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/common/memory.c b/common/memory.c
index 347f83fd4cf8..40c795d2cde1 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -195,7 +195,7 @@ static int add_mem_devices(void)
return 0;
}
-mmu_initcall(add_mem_devices);
+postmem_initcall(add_mem_devices);
/*
* Request a region from the registered sdram
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index a22e251c9d64..48c10b173852 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -35,6 +35,7 @@
KEEP(*(.initcall.13)) \
KEEP(*(.initcall.14)) \
KEEP(*(.initcall.15)) \
+ KEEP(*(.initcall.16)) \
__barebox_initcalls_end = .;
#define BAREBOX_EXITCALLS \
diff --git a/include/init.h b/include/init.h
index c695f99867ff..d0343fdf05cc 100644
--- a/include/init.h
+++ b/include/init.h
@@ -58,16 +58,17 @@ typedef void (*exitcall_t)(void);
#define console_initcall(fn) __define_initcall("3",fn,3)
#define postconsole_initcall(fn) __define_initcall("4",fn,4)
#define mem_initcall(fn) __define_initcall("5",fn,5)
-#define mmu_initcall(fn) __define_initcall("6",fn,6)
-#define postmmu_initcall(fn) __define_initcall("7",fn,7)
-#define coredevice_initcall(fn) __define_initcall("8",fn,8)
-#define fs_initcall(fn) __define_initcall("9",fn,9)
-#define device_initcall(fn) __define_initcall("10",fn,10)
-#define crypto_initcall(fn) __define_initcall("11",fn,11)
-#define of_populate_initcall(fn) __define_initcall("12",fn,12)
-#define late_initcall(fn) __define_initcall("13",fn,13)
-#define environment_initcall(fn) __define_initcall("14",fn,14)
-#define postenvironment_initcall(fn) __define_initcall("15",fn,15)
+#define postmem_initcall(fn) __define_initcall("6",fn,6)
+#define mmu_initcall(fn) __define_initcall("7",fn,7)
+#define postmmu_initcall(fn) __define_initcall("8",fn,8)
+#define coredevice_initcall(fn) __define_initcall("9",fn,9)
+#define fs_initcall(fn) __define_initcall("10",fn,10)
+#define device_initcall(fn) __define_initcall("11",fn,11)
+#define crypto_initcall(fn) __define_initcall("12",fn,12)
+#define of_populate_initcall(fn) __define_initcall("13",fn,13)
+#define late_initcall(fn) __define_initcall("14",fn,14)
+#define environment_initcall(fn) __define_initcall("15",fn,15)
+#define postenvironment_initcall(fn) __define_initcall("16",fn,16)
#define early_exitcall(fn) __define_exitcall("0",fn,0)
#define predevshutdown_exitcall(fn) __define_exitcall("1",fn,1)
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 05/10] of: reserved-mem: reserve regions prior to mmu_initcall()
2022-08-15 15:31 [PATCH 00/10] ARM: mmu: inhibit speculation into secure memory Ahmad Fatoum
` (3 preceding siblings ...)
2022-08-15 15:32 ` [PATCH 04/10] init: define new postmem_initcall() Ahmad Fatoum
@ 2022-08-15 15:32 ` Ahmad Fatoum
2022-08-15 15:32 ` [PATCH 06/10] ARM: mmu64: map reserved regions uncached Ahmad Fatoum
` (4 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-15 15:32 UTC (permalink / raw)
To: barebox; +Cc: rcz, Ahmad Fatoum
Now that we both have a way to mark SDRAM regions requested as reserved
and an postmem_initcall() to do this add, change device tree memory
reservation parsing code to use them instead of requesting them as
normal memory at coredevice_initcall() level. This allows us to
reuse this information for MMU setup in the follow-up commit.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/memory.c | 15 +++------------
drivers/of/reserved-mem.c | 34 +++++++++++++++++++++++-----------
include/of.h | 7 -------
3 files changed, 26 insertions(+), 30 deletions(-)
diff --git a/common/memory.c b/common/memory.c
index 40c795d2cde1..7e24ecb2bd03 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -56,17 +56,6 @@ void mem_malloc_init(void *start, void *end)
mem_malloc_initialized = 1;
}
-static int request_reservation(const struct resource *res)
-{
- if (!(res->flags & IORESOURCE_EXCLUSIVE))
- return 0;
-
- pr_debug("region %s %pa-%pa\n", res->name, &res->start, &res->end);
-
- request_sdram_region(res->name, res->start, resource_size(res));
- return 0;
-}
-
static int mem_malloc_resource(void)
{
#if !defined __SANDBOX__
@@ -96,7 +85,7 @@ static int mem_malloc_resource(void)
request_sdram_region("stack", STACK_BASE, STACK_SIZE);
#endif
- return of_reserved_mem_walk(request_reservation);
+ return 0;
}
coredevice_initcall(mem_malloc_resource);
@@ -173,6 +162,8 @@ int barebox_add_memory_bank(const char *name, resource_size_t start,
if (IS_ERR(res))
return PTR_ERR(res);
+ res->flags = IORESOURCE_MEM;
+
bank = xzalloc(sizeof(*bank));
bank->res = res;
diff --git a/drivers/of/reserved-mem.c b/drivers/of/reserved-mem.c
index 34e61dfea343..f50a0bd8374d 100644
--- a/drivers/of/reserved-mem.c
+++ b/drivers/of/reserved-mem.c
@@ -4,16 +4,31 @@
#include <stdio.h>
#include <of.h>
#include <of_address.h>
+#include <memory.h>
+#include <linux/ioport.h>
#define MEMRESERVE_NCELLS 2
-#define MEMRESERVE_FLAGS (IORESOURCE_MEM | IORESOURCE_EXCLUSIVE)
-int of_reserved_mem_walk(int (*handler)(const struct resource *res))
+static void request_region(struct resource *r)
+{
+ struct memory_bank *bank;
+
+ for_each_memory_bank(bank) {
+ if (!resource_contains(bank->res, r))
+ continue;
+
+ if (!reserve_sdram_region(r->name, r->start, resource_size(r)))
+ pr_warn("couldn't request reserved sdram region %pa-%pa\n",
+ &r->start, &r->end);
+ break;
+ }
+}
+
+static int of_reserved_mem_walk(void)
{
struct device_node *node, *child;
int ncells = 0;
const __be32 *reg;
- int ret;
node = of_find_node_by_path("/reserved-memory");
if (node) {
@@ -27,11 +42,9 @@ int of_reserved_mem_walk(int (*handler)(const struct resource *res))
of_address_to_resource(child, 0, &resource);
resource.name = child->name;
- resource.flags = MEMRESERVE_FLAGS;
+ resource.flags = IORESOURCE_MEM;
- ret = handler(&resource);
- if (ret)
- return ret;
+ request_region(&resource);
}
}
@@ -48,7 +61,7 @@ int of_reserved_mem_walk(int (*handler)(const struct resource *res))
snprintf(name, sizeof(name), "fdt-memreserve-%u", n++);
resource.name = name;
- resource.flags = MEMRESERVE_FLAGS;
+ resource.flags = IORESOURCE_MEM;
resource.start = of_read_number(reg + i, MEMRESERVE_NCELLS);
i += MEMRESERVE_NCELLS;
@@ -61,11 +74,10 @@ int of_reserved_mem_walk(int (*handler)(const struct resource *res))
resource.end = resource.start + size - 1;
- ret = handler(&resource);
- if (ret)
- return ret;
+ request_region(&resource);
}
}
return 0;
}
+postmem_initcall(of_reserved_mem_walk);
diff --git a/include/of.h b/include/of.h
index 223c634bc88a..91c3766992aa 100644
--- a/include/of.h
+++ b/include/of.h
@@ -325,8 +325,6 @@ int of_autoenable_device_by_path(char *path);
int of_autoenable_i2c_by_component(char *path);
int of_prepend_machine_compatible(struct device_node *root, const char *compat);
-int of_reserved_mem_walk(int (*handler)(const struct resource *res));
-
#else
static inline struct of_reserve_map *of_get_reserve_map(void)
{
@@ -868,11 +866,6 @@ static inline int of_prepend_machine_compatible(struct device_node *root,
return -ENODEV;
}
-static inline int of_reserved_mem_walk(int (*handler)(const struct resource *res))
-{
- return 0;
-}
-
#endif
#define for_each_property_of_node(dn, pp) \
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 06/10] ARM: mmu64: map reserved regions uncached
2022-08-15 15:31 [PATCH 00/10] ARM: mmu: inhibit speculation into secure memory Ahmad Fatoum
` (4 preceding siblings ...)
2022-08-15 15:32 ` [PATCH 05/10] of: reserved-mem: reserve regions prior to mmu_initcall() Ahmad Fatoum
@ 2022-08-15 15:32 ` Ahmad Fatoum
2022-08-15 15:32 ` [PATCH 07/10] ARM: mmu: define attrs_uncached_mem() helper Ahmad Fatoum
` (3 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-15 15:32 UTC (permalink / raw)
To: barebox; +Cc: rcz, Ahmad Fatoum
Now that we have reserved memory regions specially marked in the SDRAM
bank requests, we can use this information to map these regions
uncached and eXecute Never to avoid speculative access into these
regions from causing hard-to-debug data aborts.
The sequence used here is safe because __mmu_init turns off the MMU if
enabled, so even if we overwrite early MMU uncached entries they are
without effect until the MMU is turned on again, by which time the
for_each_reserved_region should have disabled caching for them again
(e.g. because they were listed in DT as /reserve-memory).
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/cpu/mmu-common.h | 15 +++++++++++++++
arch/arm/cpu/mmu_64.c | 10 +++++++++-
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/arch/arm/cpu/mmu-common.h b/arch/arm/cpu/mmu-common.h
index ed7d5bc3168f..c9ea2c122857 100644
--- a/arch/arm/cpu/mmu-common.h
+++ b/arch/arm/cpu/mmu-common.h
@@ -3,6 +3,11 @@
#ifndef __ARM_MMU_COMMON_H
#define __ARM_MMU_COMMON_H
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/sizes.h>
+
void dma_inv_range(void *ptr, size_t size);
void dma_flush_range(void *ptr, size_t size);
void *dma_alloc_map(size_t size, dma_addr_t *dma_handle, unsigned flags);
@@ -19,4 +24,14 @@ static inline void arm_mmu_not_initialized_error(void)
panic("MMU not initialized\n");
}
+static inline size_t resource_first_page(const struct resource *res)
+{
+ return ALIGN_DOWN(res->start, SZ_4K);
+}
+
+static inline size_t resource_count_pages(const struct resource *res)
+{
+ return ALIGN(resource_size(res), SZ_4K);
+}
+
#endif
diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c
index 06049e000375..f43ac9a12186 100644
--- a/arch/arm/cpu/mmu_64.c
+++ b/arch/arm/cpu/mmu_64.c
@@ -201,9 +201,17 @@ void __mmu_init(bool mmu_on)
create_sections(0, 0, 1UL << (BITS_PER_VA - 1), attrs_uncached_mem());
/* Map sdram cached. */
- for_each_memory_bank(bank)
+ for_each_memory_bank(bank) {
+ struct resource *rsv;
+
create_sections(bank->start, bank->start, bank->size, CACHED_MEM);
+ for_each_reserved_region(bank, rsv) {
+ create_sections(resource_first_page(rsv), resource_first_page(rsv),
+ resource_count_pages(rsv), attrs_uncached_mem());
+ }
+ }
+
/* Make zero page faulting to catch NULL pointer derefs */
zero_page_faulting();
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 07/10] ARM: mmu: define attrs_uncached_mem() helper
2022-08-15 15:31 [PATCH 00/10] ARM: mmu: inhibit speculation into secure memory Ahmad Fatoum
` (5 preceding siblings ...)
2022-08-15 15:32 ` [PATCH 06/10] ARM: mmu64: map reserved regions uncached Ahmad Fatoum
@ 2022-08-15 15:32 ` Ahmad Fatoum
2022-08-15 15:32 ` [PATCH 08/10] ARM: mmu: use reserve mem entries to modify maps Ahmad Fatoum
` (2 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-15 15:32 UTC (permalink / raw)
To: barebox; +Cc: rcz, Ahmad Fatoum
We already have a helper with the same name for ARMv8, so define it here
for reuse in the follow-up commit.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/cpu/mmu.h | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/mmu.h b/arch/arm/cpu/mmu.h
index d48522d166f7..1499b70dd649 100644
--- a/arch/arm/cpu/mmu.h
+++ b/arch/arm/cpu/mmu.h
@@ -73,15 +73,20 @@ create_sections(uint32_t *ttb, unsigned long first,
#define PMD_SECT_DEF_UNCACHED (PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT)
#define PMD_SECT_DEF_CACHED (PMD_SECT_WB | PMD_SECT_DEF_UNCACHED)
-static inline void create_flat_mapping(uint32_t *ttb)
+static inline unsigned long attrs_uncached_mem(void)
{
unsigned int flags = PMD_SECT_DEF_UNCACHED;
if (cpu_architecture() >= CPU_ARCH_ARMv7)
flags |= PMD_SECT_XN;
+ return flags;
+}
+
+static inline void create_flat_mapping(uint32_t *ttb)
+{
/* create a flat mapping using 1MiB sections */
- create_sections(ttb, 0, 0xffffffff, flags);
+ create_sections(ttb, 0, 0xffffffff, attrs_uncached_mem());
}
#endif /* __ARM_MMU_H */
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 08/10] ARM: mmu: use reserve mem entries to modify maps
2022-08-15 15:31 [PATCH 00/10] ARM: mmu: inhibit speculation into secure memory Ahmad Fatoum
` (6 preceding siblings ...)
2022-08-15 15:32 ` [PATCH 07/10] ARM: mmu: define attrs_uncached_mem() helper Ahmad Fatoum
@ 2022-08-15 15:32 ` Ahmad Fatoum
2022-08-15 15:32 ` [PATCH 09/10] ARM: early-mmu: don't cache/prefetch OPTEE_SIZE bytes from end of memory Ahmad Fatoum
2022-08-15 15:32 ` [PATCH 10/10] commands: iomem: point out [R]eserved regions Ahmad Fatoum
9 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-15 15:32 UTC (permalink / raw)
To: barebox; +Cc: rcz, Ahmad Fatoum
From: Rouven Czerwinski <r.czerwinski@pengutronix.de>
Like done for ARM64, use the reserved memory regions marked in the SDRAM
bank to map these regions uncached and eXecute Never to avoid speculative
access into these regions from causing hard-to-debug data aborts.
Unlike with mmu_64, for CONFIG_MMU_EARLY systems, the MMU isn't turned
off before changing the page table. So what we do instead is allocating
a 16K shadow buffer and modifying that and afterwards overwriting the
active TTB with it.
We could instead use set_ttbr() to move the page table, but in interest
of minimizing chance of breaking older ARM platforms, we keep the online
changing of the entries for now.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
[afa: use SDRAM regions instead of FDT reserve entries]
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/cpu/mmu.c | 40 +++++++++++++++++++++++++++++-----------
1 file changed, 29 insertions(+), 11 deletions(-)
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 6388e1bf14f6..f9c629c0f19d 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -413,6 +413,7 @@ static void vectors_init(void)
void __mmu_init(bool mmu_on)
{
struct memory_bank *bank;
+ void *oldttb = NULL;
arm_set_cache_functions();
@@ -430,15 +431,17 @@ void __mmu_init(bool mmu_on)
pte_flags_uncached = PTE_FLAGS_UNCACHED_V4;
}
+ ttb = xmemalign(ARM_TTB_SIZE, ARM_TTB_SIZE);
+
+ /*
+ * Early MMU code may have already enabled the MMU. We assume a
+ * flat 1:1 section mapping in this case.
+ */
if (mmu_on) {
- /*
- * Early MMU code has already enabled the MMU. We assume a
- * flat 1:1 section mapping in this case.
- */
- /* Clear unpredictable bits [13:0] */
- ttb = (uint32_t *)(get_ttbr() & ~0x3fff);
+ oldttb = (uint32_t *)(get_ttbr() & ~0x3fff);
+ memcpy(ttb, oldttb, ARM_TTB_SIZE);
- if (!request_sdram_region("ttb", (unsigned long)ttb, SZ_16K))
+ if (!request_sdram_region("ttb", (unsigned long)oldttb, SZ_16K))
/*
* This can mean that:
* - the early MMU code has put the ttb into a place
@@ -447,10 +450,8 @@ void __mmu_init(bool mmu_on)
* the ttb will get corrupted.
*/
pr_crit("Critical Error: Can't request SDRAM region for ttb at %p\n",
- ttb);
+ oldttb);
} else {
- ttb = xmemalign(ARM_TTB_SIZE, ARM_TTB_SIZE);
-
set_ttbr(ttb);
/* For the XN bit to take effect, we can't be using DOMAIN_MANAGER. */
@@ -468,11 +469,28 @@ void __mmu_init(bool mmu_on)
vectors_init();
for_each_memory_bank(bank) {
+ struct resource *rsv;
+
create_sections(ttb, bank->start, bank->start + bank->size - 1,
PMD_SECT_DEF_CACHED);
- __mmu_cache_flush();
+
+ for_each_reserved_region(bank, rsv) {
+ create_sections(ttb, resource_first_page(rsv),
+ resource_count_pages(rsv),
+ attrs_uncached_mem());
+ }
}
+ /*
+ * We could set_ttbr(ttb) here instead and save on the copy, but
+ * for now we play it safe, so we don't mess with the older ARMs.
+ */
+ if (oldttb) {
+ memcpy(oldttb, ttb, ARM_TTB_SIZE);
+ free(ttb);
+ }
+
+ __mmu_cache_flush();
__mmu_cache_on();
}
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 09/10] ARM: early-mmu: don't cache/prefetch OPTEE_SIZE bytes from end of memory
2022-08-15 15:31 [PATCH 00/10] ARM: mmu: inhibit speculation into secure memory Ahmad Fatoum
` (7 preceding siblings ...)
2022-08-15 15:32 ` [PATCH 08/10] ARM: mmu: use reserve mem entries to modify maps Ahmad Fatoum
@ 2022-08-15 15:32 ` Ahmad Fatoum
2022-08-15 15:32 ` [PATCH 10/10] commands: iomem: point out [R]eserved regions Ahmad Fatoum
9 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-15 15:32 UTC (permalink / raw)
To: barebox; +Cc: rcz, Ahmad Fatoum
OPTEE_SIZE is always defined in <asm-generic/memory_layout.h> either as
as CONFIG_OPTEE_SIZE or as 0 if the option is undefined.
There is never a reason to map the last OPTEE_SIZE bytes in the initial
memory as cached and executable:
- OPTEE_SIZE == 0: no change
- OPTEE_SIZE != 0 && CONFIG_PBL_OPTEE=y: cache must not be enabled for
the region to avoid speculation
- OPTEE_SIZE != 0 && CONFIG_BOOTM_OPTEE=y: we won't use this region
for anything between MMU early init and normal init, so no harm
in disabling caches.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/cpu/start.c | 2 +-
arch/arm/cpu/uncompress.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 5861c15d43df..672f26e0063c 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -171,7 +171,7 @@ __noreturn __no_sanitize_address void barebox_non_pbl_start(unsigned long membas
} else {
pr_debug("enabling MMU, ttb @ 0x%08lx\n", ttb);
arm_early_mmu_cache_invalidate();
- mmu_early_enable(membase, memsize, ttb);
+ mmu_early_enable(membase, memsize - OPTEE_SIZE, ttb);
}
}
diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
index 2250b8ccd375..537ee63229d7 100644
--- a/arch/arm/cpu/uncompress.c
+++ b/arch/arm/cpu/uncompress.c
@@ -84,7 +84,7 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
if (IS_ENABLED(CONFIG_MMU_EARLY)) {
unsigned long ttb = arm_mem_ttb(membase, endmem);
pr_debug("enabling MMU, ttb @ 0x%08lx\n", ttb);
- mmu_early_enable(membase, memsize, ttb);
+ mmu_early_enable(membase, memsize - OPTEE_SIZE, ttb);
}
free_mem_ptr = arm_mem_early_malloc(membase, endmem);
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 10/10] commands: iomem: point out [R]eserved regions
2022-08-15 15:31 [PATCH 00/10] ARM: mmu: inhibit speculation into secure memory Ahmad Fatoum
` (8 preceding siblings ...)
2022-08-15 15:32 ` [PATCH 09/10] ARM: early-mmu: don't cache/prefetch OPTEE_SIZE bytes from end of memory Ahmad Fatoum
@ 2022-08-15 15:32 ` Ahmad Fatoum
9 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-15 15:32 UTC (permalink / raw)
To: barebox; +Cc: rcz, Ahmad Fatoum
Now that we define IORESOURCE_BUSY as meaning that a region possibly
contains secure firmware, it's useful to have this information in the
iomem output as well, so add it.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
commands/iomemport.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/commands/iomemport.c b/commands/iomemport.c
index d0cfc413c262..f2baa0e29397 100644
--- a/commands/iomemport.c
+++ b/commands/iomemport.c
@@ -16,11 +16,14 @@ static void __print_resources(struct resource *res, int indent)
for (i = 0; i < indent; i++)
printf(" ");
- printf("%pa - %pa (size %pa) %s\n",
- &res->start, &res->end, &size, res->name);
+ printf("%pa - %pa (size %pa) %s%s\n",
+ &res->start, &res->end, &size,
+ res->flags & IORESOURCE_BUSY ? "[R] " : "",
+ res->name);
- list_for_each_entry(r, &res->children, sibling)
+ list_for_each_entry(r, &res->children, sibling) {
__print_resources(r, indent + 1);
+ }
}
static void print_resources(struct resource *res)
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread