* [PATCH v2 0/6] resource: record memory type/attrs on all SDRAM
@ 2025-05-26 14:19 Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 1/6] memory: export inside_barebox_area Ahmad Fatoum
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2025-05-26 14:19 UTC (permalink / raw)
To: barebox
When running as EFI loader, barebox is expected to provide a virtual
memory map that describes the memory regions known to barebox as well as
attributes like whether regions are write-back cached (usable as normal
memory) or reserved (e.g., for OP-TEE).
>From a security point of view, it's useful to have this information
always to inform MMU attributes, so let's make it mandatory.
v1 -> v2:
- replace !IS_ERR check with !NULL check for __request_sdram_region
Ahmad Fatoum (6):
memory: export inside_barebox_area
resource: record EFI memory type and attributes
resource: add MEMATTRS_ definitions for common attribute sets
drivers: tee: optee: separate local variables for each resource
resource: supply memory type/attrs on all SDRAM requests
resource: retire IORESOURCE_BUSY in favor of resource::type
arch/arm/cpu/armv7r-mpu.c | 5 ++-
arch/arm/cpu/bootm-fip.c | 3 +-
arch/arm/cpu/cpu.c | 3 +-
arch/arm/cpu/mmu_32.c | 13 ++++--
arch/arm/cpu/mmu_64.c | 7 ++-
arch/arm/cpu/start.c | 3 +-
arch/arm/lib32/bootm.c | 18 +++++---
arch/arm/lib32/bootz.c | 4 +-
arch/mips/lib/cpu-probe.c | 3 +-
arch/powerpc/mach-mpc5xxx/cpu.c | 3 +-
arch/powerpc/mach-mpc85xx/cpu.c | 2 +-
arch/riscv/boot/start.c | 2 +-
arch/riscv/cpu/core.c | 2 +-
commands/iomemport.c | 2 +-
common/bootm.c | 9 ++--
common/elf.c | 3 +-
common/memory.c | 57 +++++++++++++++++-------
common/memtest.c | 4 +-
common/oftree.c | 2 +-
common/pe.c | 4 +-
common/uimage.c | 6 ++-
drivers/tee/optee/of_fixup.c | 33 +++++++-------
fs/pstore/ram_core.c | 6 ++-
include/efi.h | 37 +--------------
include/efi/memtype.h | 79 +++++++++++++++++++++++++++++++++
include/linux/ioport.h | 67 +++++++++++++++++++++++++++-
include/memory.h | 33 +++++++++++---
lib/Kconfig.hardening | 7 +++
lib/libfile.c | 13 +++++-
pbl/handoff-data.c | 3 +-
30 files changed, 320 insertions(+), 113 deletions(-)
create mode 100644 include/efi/memtype.h
--
2.39.5
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/6] memory: export inside_barebox_area
2025-05-26 14:19 [PATCH v2 0/6] resource: record memory type/attrs on all SDRAM Ahmad Fatoum
@ 2025-05-26 14:19 ` Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 2/6] resource: record EFI memory type and attributes Ahmad Fatoum
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2025-05-26 14:19 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Knowing whether some object lies with barebox memory area can be useful
beyond the memory resource code, so export the function for general use.
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
common/memory.c | 9 +++++++--
include/memory.h | 6 ++++++
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/common/memory.c b/common/memory.c
index a5b081be2c70..4e3cb1571e93 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -72,14 +72,19 @@ static int mem_register_barebox(void)
}
postmem_initcall(mem_register_barebox);
+bool inside_barebox_area(resource_size_t start, resource_size_t end)
+{
+ return barebox_res && barebox_res->start <= start &&
+ end <= barebox_res->end;
+}
+
struct resource *request_barebox_region(const char *name,
resource_size_t start,
resource_size_t size)
{
resource_size_t end = start + size - 1;
- if (barebox_res && barebox_res->start <= start &&
- end <= barebox_res->end) {
+ if (inside_barebox_area(start, end)) {
struct resource *iores;
iores = __request_region(barebox_res, start, end,
name, IORESOURCE_MEM);
diff --git a/include/memory.h b/include/memory.h
index 09c10b773fac..707c0f13130d 100644
--- a/include/memory.h
+++ b/include/memory.h
@@ -64,6 +64,7 @@ static inline u64 memory_sdram_size(unsigned int cols,
void register_barebox_area(resource_size_t start, resource_size_t size);
#if IN_PROPER
+bool inside_barebox_area(resource_size_t start, resource_size_t end);
struct resource *request_barebox_region(const char *name,
resource_size_t start,
resource_size_t size);
@@ -75,6 +76,11 @@ static inline struct resource *request_barebox_region(const char *name,
return NULL;
}
+
+static inline bool inside_barebox_area(resource_size_t start, resource_size_t end)
+{
+ return false;
+}
#endif
#endif
--
2.39.5
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/6] resource: record EFI memory type and attributes
2025-05-26 14:19 [PATCH v2 0/6] resource: record memory type/attrs on all SDRAM Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 1/6] memory: export inside_barebox_area Ahmad Fatoum
@ 2025-05-26 14:19 ` Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 3/6] resource: add MEMATTRS_ definitions for common attribute sets Ahmad Fatoum
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2025-05-26 14:19 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
While struct resource has some defines for attributes like
IORESOURCE_MEM_CACHEABLE, there are not enough bits to cover all
memory attributes and types specified by EFI.
As the upper 32-bit of the existing struct resource::flags member on
64-bit systems is unused, let's repurpose it to hold the memory type and
attributes. As we want to make use of this information even without EFI,
we add generic sounding constants that happen to be identical to the EFI
constant values.
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
include/efi.h | 37 +-------------------
include/efi/memtype.h | 79 ++++++++++++++++++++++++++++++++++++++++++
include/linux/ioport.h | 40 ++++++++++++++++++++-
3 files changed, 119 insertions(+), 37 deletions(-)
create mode 100644 include/efi/memtype.h
diff --git a/include/efi.h b/include/efi.h
index 217e3d9f56ff..82d3380a31a9 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -15,6 +15,7 @@
#include <linux/string.h>
#include <linux/types.h>
#include <efi/types.h>
+#include <efi/memtype.h>
/* Bit mask for EFI status code with error */
#define EFI_ERROR_MASK (1UL << (BITS_PER_LONG-1))
@@ -86,42 +87,6 @@ struct efi_memory_desc {
u64 attrs;
};
-/* Memory types: */
-enum efi_memory_type {
- EFI_RESERVED_TYPE,
- EFI_LOADER_CODE,
- EFI_LOADER_DATA,
- EFI_BOOT_SERVICES_CODE,
- EFI_BOOT_SERVICES_DATA,
- EFI_RUNTIME_SERVICES_CODE,
- EFI_RUNTIME_SERVICES_DATA,
- EFI_CONVENTIONAL_MEMORY,
- EFI_UNUSABLE_MEMORY,
- EFI_ACPI_RECLAIM_MEMORY,
- EFI_ACPI_MEMORY_NVS,
- EFI_MEMORY_MAPPED_IO,
- EFI_MEMORY_MAPPED_IO_PORT_SPACE,
- EFI_PAL_CODE,
- EFI_MAX_MEMORY_TYPE
-};
-
-/* Attribute values: */
-#define EFI_MEMORY_UC ((u64)0x0000000000000001ULL) /* uncached */
-#define EFI_MEMORY_WC ((u64)0x0000000000000002ULL) /* write-coalescing */
-#define EFI_MEMORY_WT ((u64)0x0000000000000004ULL) /* write-through */
-#define EFI_MEMORY_WB ((u64)0x0000000000000008ULL) /* write-back */
-#define EFI_MEMORY_UCE ((u64)0x0000000000000010ULL) /* uncached, exported */
-#define EFI_MEMORY_WP ((u64)0x0000000000001000ULL) /* write-protect */
-#define EFI_MEMORY_RP ((u64)0x0000000000002000ULL) /* read-protect */
-#define EFI_MEMORY_XP ((u64)0x0000000000004000ULL) /* execute-protect */
-#define EFI_MEMORY_NV ((u64)0x0000000000008000ULL) /* non-volatile */
-#define EFI_MEMORY_RUNTIME ((u64)0x8000000000000000ULL) /* range requires runtime mapping */
-#define EFI_MEMORY_MORE_RELIABLE \
- ((u64)0x0000000000010000ULL) /* higher reliability */
-#define EFI_MEMORY_RO ((u64)0x0000000000020000ULL) /* read-only */
-#define EFI_MEMORY_SP ((u64)0x0000000000040000ULL) /* specific-purpose memory (SPM) */
-#define EFI_MEMORY_DESCRIPTOR_VERSION 1
-
#define EFI_PAGE_SHIFT 12
#define EFI_PAGE_SIZE (1ULL << EFI_PAGE_SHIFT)
#define EFI_PAGE_MASK (EFI_PAGE_SIZE - 1)
diff --git a/include/efi/memtype.h b/include/efi/memtype.h
new file mode 100644
index 000000000000..3f33b911a545
--- /dev/null
+++ b/include/efi/memtype.h
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _EFI_MEMTYPE_H_
+#define _EFI_MEMTYPE_H_
+
+#include <linux/ioport.h>
+#include <efi/types.h>
+
+/* Memory types: */
+enum efi_memory_type {
+ EFI_RESERVED_TYPE = MEMTYPE_RESERVED,
+ EFI_LOADER_CODE = MEMTYPE_LOADER_CODE,
+ EFI_LOADER_DATA = MEMTYPE_LOADER_DATA,
+ EFI_BOOT_SERVICES_CODE = MEMTYPE_BOOT_SERVICES_CODE,
+ EFI_BOOT_SERVICES_DATA = MEMTYPE_BOOT_SERVICES_DATA,
+ EFI_RUNTIME_SERVICES_CODE = MEMTYPE_RUNTIME_SERVICES_CODE,
+ EFI_RUNTIME_SERVICES_DATA = MEMTYPE_RUNTIME_SERVICES_DATA,
+ EFI_CONVENTIONAL_MEMORY = MEMTYPE_CONVENTIONAL,
+ EFI_UNUSABLE_MEMORY = MEMTYPE_UNUSABLE,
+ EFI_ACPI_RECLAIM_MEMORY = MEMTYPE_ACPI_RECLAIM,
+ EFI_ACPI_MEMORY_NVS = MEMTYPE_ACPI_NVS,
+ EFI_MEMORY_MAPPED_IO = MEMTYPE_MMIO,
+ EFI_MEMORY_MAPPED_IO_PORT_SPACE = MEMTYPE_MMIO_PORT,
+ EFI_PAL_CODE = MEMTYPE_PAL_CODE,
+ EFI_PERSISTENT_MEMORY_TYPE = MEMTYPE_PERSISTENT,
+ EFI_UNACCEPTED_MEMORY_TYPE = MEMTYPE_UNACCEPTED,
+ EFI_MAX_MEMORY_TYPE = MEMTYPE_MAX,
+};
+
+/* Attribute values: */
+#define EFI_MEMORY_UC ((u64)MEMATTR_UC) /* uncached */
+#define EFI_MEMORY_WC ((u64)MEMATTR_WC) /* write-coalescing */
+#define EFI_MEMORY_WT ((u64)MEMATTR_WT) /* write-through */
+#define EFI_MEMORY_WB ((u64)MEMATTR_WB) /* write-back */
+#define EFI_MEMORY_UCE ((u64)MEMATTR_UCE) /* uncached, exported */
+#define EFI_MEMORY_WP ((u64)MEMATTR_WP) /* write-protect */
+#define EFI_MEMORY_RP ((u64)MEMATTR_RP) /* read-protect */
+#define EFI_MEMORY_XP ((u64)MEMATTR_XP) /* execute-protect */
+#define EFI_MEMORY_NV ((u64)MEMATTR_NV) /* non-volatile */
+#define EFI_MEMORY_RUNTIME ((u64)0x8000000000000000) /* range requires runtime mapping */
+
+#define EFI_MEMORY_MORE_RELIABLE ((u64)MEMATTR_MORE_RELIABLE) /* higher reliability */
+#define EFI_MEMORY_RO ((u64)MEMATTR_RO) /* read-only */
+#define EFI_MEMORY_SP ((u64)MEMATTR_SP) /* specific-purpose memory (SPM) */
+
+static inline enum efi_memory_type resource_type_to_efi_memory_type(unsigned type)
+{
+ return type;
+}
+
+static inline unsigned efi_memory_type_to_resource_type(enum efi_memory_type type)
+{
+ return type;
+}
+
+static inline enum efi_memory_type resource_get_efi_memory_type(const struct resource *res)
+{
+ if (res->flags & IORESOURCE_TYPE_VALID)
+ return resource_type_to_efi_memory_type(res->type);
+ return EFI_CONVENTIONAL_MEMORY;
+}
+
+static inline u64 resource_get_efi_memory_attrs(const struct resource *res)
+{
+ if (res->flags & IORESOURCE_TYPE_VALID)
+ return res->attrs | (res->runtime ? EFI_MEMORY_RUNTIME : 0);
+ return 0;
+}
+
+static inline void resource_set_efi_memory_type_attrs(struct resource *res,
+ enum efi_memory_type type,
+ u64 attrs)
+{
+ res->type = type;
+ res->runtime = attrs & EFI_MEMORY_RUNTIME;
+ res->attrs = attrs & ~EFI_MEMORY_RUNTIME;
+ res->flags |= IORESOURCE_TYPE_VALID;
+}
+
+#endif
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index c6328e9a7fc2..1e266185651f 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -22,7 +22,10 @@ struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
- unsigned long flags;
+ unsigned int flags;
+ unsigned int type:4;
+ unsigned int attrs:27;
+ unsigned int runtime:1;
struct resource *parent;
struct list_head children;
struct list_head sibling;
@@ -53,6 +56,8 @@ struct resource {
#define IORESOURCE_WINDOW 0x00200000 /* forwarded by bridge */
#define IORESOURCE_MUXED 0x00400000 /* Resource is software muxed */
+#define IORESOURCE_TYPE_VALID 0x00800000 /* type & attrs are valid */
+
#define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */
#define IORESOURCE_DISABLED 0x10000000
#define IORESOURCE_UNSET 0x20000000
@@ -95,6 +100,39 @@ struct resource {
#define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */
#define IORESOURCE_MEM_EXPANSIONROM (1<<6)
+enum resource_memtype {
+ MEMTYPE_RESERVED,
+ MEMTYPE_LOADER_CODE,
+ MEMTYPE_LOADER_DATA,
+ MEMTYPE_BOOT_SERVICES_CODE,
+ MEMTYPE_BOOT_SERVICES_DATA,
+ MEMTYPE_RUNTIME_SERVICES_CODE,
+ MEMTYPE_RUNTIME_SERVICES_DATA,
+ MEMTYPE_CONVENTIONAL,
+ MEMTYPE_UNUSABLE,
+ MEMTYPE_ACPI_RECLAIM,
+ MEMTYPE_ACPI_NVS,
+ MEMTYPE_MMIO,
+ MEMTYPE_MMIO_PORT,
+ MEMTYPE_PAL_CODE,
+ MEMTYPE_PERSISTENT,
+ MEMTYPE_UNACCEPTED,
+ MEMTYPE_MAX,
+};
+
+#define MEMATTR_UC 0x00000001 /* uncached */
+#define MEMATTR_WC 0x00000002 /* write-coalescing */
+#define MEMATTR_WT 0x00000004 /* write-through */
+#define MEMATTR_WB 0x00000008 /* write-back */
+#define MEMATTR_UCE 0x00000010 /* uncached, exported */
+#define MEMATTR_WP 0x00001000 /* write-protect */
+#define MEMATTR_RP 0x00002000 /* read-protect */
+#define MEMATTR_XP 0x00004000 /* execute-protect */
+#define MEMATTR_NV 0x00008000 /* non-volatile */
+#define MEMATTR_MORE_RELIABLE 0x00010000 /* higher reliability */
+#define MEMATTR_RO 0x00020000 /* read-only */
+#define MEMATTR_SP 0x00040000 /* specific-purpose */
+
/* PnP I/O specific bits (IORESOURCE_BITS) */
#define IORESOURCE_IO_16BIT_ADDR (1<<0)
#define IORESOURCE_IO_FIXED (1<<1)
--
2.39.5
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 3/6] resource: add MEMATTRS_ definitions for common attribute sets
2025-05-26 14:19 [PATCH v2 0/6] resource: record memory type/attrs on all SDRAM Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 1/6] memory: export inside_barebox_area Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 2/6] resource: record EFI memory type and attributes Ahmad Fatoum
@ 2025-05-26 14:19 ` Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 4/6] drivers: tee: optee: separate local variables for each resource Ahmad Fatoum
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2025-05-26 14:19 UTC (permalink / raw)
To: barebox
Most SDRAM mapped by barebox falls into one of these categories,
so add some readily usable MEMATTRS_ constants.
Anything more special can OR the individual MEMATTR_ bits together.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
include/linux/ioport.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 1e266185651f..425928df3bfe 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -133,6 +133,14 @@ enum resource_memtype {
#define MEMATTR_RO 0x00020000 /* read-only */
#define MEMATTR_SP 0x00040000 /* specific-purpose */
+#define MEMATTRS_CACHEABLE (MEMATTR_WT | MEMATTR_WC | MEMATTR_WB)
+#define MEMATTRS_RW (MEMATTRS_CACHEABLE | MEMATTR_XP)
+#define MEMATTRS_RO (MEMATTRS_CACHEABLE | MEMATTR_XP | MEMATTR_RO)
+#define MEMATTRS_RX (MEMATTRS_CACHEABLE | MEMATTR_RO)
+#define MEMATTRS_RWX (MEMATTRS_CACHEABLE) /* TODO: remove all */
+#define MEMATTRS_RW_DEVICE (MEMATTR_UC | MEMATTR_XP)
+#define MEMATTRS_FAULT (MEMATTR_UC | MEMATTR_XP | MEMATTR_RP | MEMATTR_RO)
+
/* PnP I/O specific bits (IORESOURCE_BITS) */
#define IORESOURCE_IO_16BIT_ADDR (1<<0)
#define IORESOURCE_IO_FIXED (1<<1)
@@ -204,5 +212,24 @@ int release_region(struct resource *res);
extern struct resource iomem_resource;
extern struct resource ioport_resource;
+static inline void reserve_resource(struct resource *res)
+{
+ res->type = MEMTYPE_RESERVED;
+ /* Reserved memory is used for secure memory that should
+ * be hardware-protected independently of MMU flags.
+ * We map it as device memory, so we can still test
+ * if it's indeed inaccessible
+ */
+ res->attrs = MEMATTRS_RW_DEVICE;
+ res->flags |= IORESOURCE_TYPE_VALID;
+}
+
+static inline bool is_reserved_resource(const struct resource *res)
+{
+ if (res->flags & IORESOURCE_TYPE_VALID)
+ return res->type == MEMTYPE_RESERVED;
+ return false;
+}
+
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_IOPORT_H */
--
2.39.5
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 4/6] drivers: tee: optee: separate local variables for each resource
2025-05-26 14:19 [PATCH v2 0/6] resource: record memory type/attrs on all SDRAM Ahmad Fatoum
` (2 preceding siblings ...)
2025-05-26 14:19 ` [PATCH v2 3/6] resource: add MEMATTRS_ definitions for common attribute sets Ahmad Fatoum
@ 2025-05-26 14:19 ` Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 5/6] resource: supply memory type/attrs on all SDRAM requests Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 6/6] resource: retire IORESOURCE_BUSY in favor of resource::type Ahmad Fatoum
5 siblings, 0 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2025-05-26 14:19 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Not reusing the same local variable makes the code arguably clearer and
ensures we don't inherit flags by mistake from the previous use of the
variable.
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
drivers/tee/optee/of_fixup.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/tee/optee/of_fixup.c b/drivers/tee/optee/of_fixup.c
index 045b5a0bb754..e801c4c95070 100644
--- a/drivers/tee/optee/of_fixup.c
+++ b/drivers/tee/optee/of_fixup.c
@@ -10,7 +10,7 @@ int of_optee_fixup(struct device_node *root, void *_data)
{
struct of_optee_fixup_data *fixup_data = _data;
const char *optee_of_path = "/firmware/optee";
- struct resource res = {};
+ struct resource res_core = {}, res_shm = {};
struct device_node *node;
u64 optee_membase;
int ret;
@@ -31,16 +31,16 @@ int of_optee_fixup(struct device_node *root, void *_data)
return ret;
if (!optee_get_membase(&optee_membase)) {
- res.start = optee_membase;
- res.end = optee_membase + OPTEE_SIZE - fixup_data->shm_size - 1;
+ res_core.start = optee_membase;
+ res_core.end = optee_membase + OPTEE_SIZE - fixup_data->shm_size - 1;
} else {
- res.start = arm_mem_endmem_get() - OPTEE_SIZE;
- res.end = arm_mem_endmem_get() - fixup_data->shm_size - 1;
+ res_core.start = arm_mem_endmem_get() - OPTEE_SIZE;
+ res_core.end = arm_mem_endmem_get() - fixup_data->shm_size - 1;
}
- res.flags = IORESOURCE_BUSY;
- res.name = "optee_core";
+ res_core.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ res_core.name = "optee_core";
- ret = of_fixup_reserved_memory(root, &res);
+ ret = of_fixup_reserved_memory(root, &res_core);
if (ret)
return ret;
@@ -48,14 +48,14 @@ int of_optee_fixup(struct device_node *root, void *_data)
return 0;
if (!optee_get_membase(&optee_membase)) {
- res.start = optee_membase + OPTEE_SIZE - fixup_data->shm_size;
- res.end = optee_membase + OPTEE_SIZE - 1;
+ res_shm.start = optee_membase + OPTEE_SIZE - fixup_data->shm_size;
+ res_shm.end = optee_membase + OPTEE_SIZE - 1;
} else {
- res.start = arm_mem_endmem_get() - fixup_data->shm_size;
- res.end = arm_mem_endmem_get() - 1;
+ res_shm.start = arm_mem_endmem_get() - fixup_data->shm_size;
+ res_shm.end = arm_mem_endmem_get() - 1;
}
- res.flags &= ~IORESOURCE_BUSY;
- res.name = "optee_shm";
+ res_shm.flags = IORESOURCE_MEM;
+ res_shm.name = "optee_shm";
- return of_fixup_reserved_memory(root, &res);
+ return of_fixup_reserved_memory(root, &res_shm);
}
--
2.39.5
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 5/6] resource: supply memory type/attrs on all SDRAM requests
2025-05-26 14:19 [PATCH v2 0/6] resource: record memory type/attrs on all SDRAM Ahmad Fatoum
` (3 preceding siblings ...)
2025-05-26 14:19 ` [PATCH v2 4/6] drivers: tee: optee: separate local variables for each resource Ahmad Fatoum
@ 2025-05-26 14:19 ` Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 6/6] resource: retire IORESOURCE_BUSY in favor of resource::type Ahmad Fatoum
5 siblings, 0 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2025-05-26 14:19 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
When running as EFI loader, barebox is expected to provide a virtual
memory map that describes the memory regions known to barebox as well as
attributes like whether regions are write-back cached (usable as normal
memory) or reserved (e.g., for OP-TEE).
>From a security point of view, it's useful to have this information
always to inform MMU attributes, so let's make it mandatory.
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
arch/arm/cpu/armv7r-mpu.c | 5 ++--
arch/arm/cpu/bootm-fip.c | 3 +-
arch/arm/cpu/cpu.c | 3 +-
arch/arm/cpu/mmu_32.c | 13 ++++++---
arch/arm/cpu/mmu_64.c | 7 +++--
arch/arm/cpu/start.c | 3 +-
arch/arm/lib32/bootm.c | 18 ++++++++----
arch/arm/lib32/bootz.c | 4 ++-
arch/mips/lib/cpu-probe.c | 3 +-
arch/powerpc/mach-mpc5xxx/cpu.c | 3 +-
arch/powerpc/mach-mpc85xx/cpu.c | 2 +-
arch/riscv/boot/start.c | 2 +-
arch/riscv/cpu/core.c | 2 +-
common/bootm.c | 9 +++---
common/elf.c | 3 +-
common/memory.c | 52 ++++++++++++++++++++++++++-------
common/memtest.c | 4 ++-
common/pe.c | 4 ++-
common/uimage.c | 6 ++--
drivers/tee/optee/of_fixup.c | 3 ++
fs/pstore/ram_core.c | 6 +++-
include/memory.h | 23 +++++++++++----
lib/Kconfig.hardening | 7 +++++
lib/libfile.c | 13 +++++++--
pbl/handoff-data.c | 3 +-
25 files changed, 149 insertions(+), 52 deletions(-)
diff --git a/arch/arm/cpu/armv7r-mpu.c b/arch/arm/cpu/armv7r-mpu.c
index 1de9e39cc5f5..4fb867c50a42 100644
--- a/arch/arm/cpu/armv7r-mpu.c
+++ b/arch/arm/cpu/armv7r-mpu.c
@@ -206,8 +206,9 @@ int armv7r_mpu_init_coherent(unsigned long start, enum size reg_size)
static int armv7r_request_pool(void)
{
if (dma_coherent_start && dma_coherent_size)
- request_sdram_region("DMA coherent pool", dma_coherent_start,
- dma_coherent_size);
+ request_sdram_region("DMA coherent pool",
+ dma_coherent_start, dma_coherent_size,
+ MEMTYPE_BOOT_SERVICES_DATA, MEMATTRS_RW);
return 0;
}
postmem_initcall(armv7r_request_pool);
diff --git a/arch/arm/cpu/bootm-fip.c b/arch/arm/cpu/bootm-fip.c
index 89201ade5f12..bd176f064524 100644
--- a/arch/arm/cpu/bootm-fip.c
+++ b/arch/arm/cpu/bootm-fip.c
@@ -37,7 +37,8 @@ static int desc_to_sdram(struct fip_image_desc *loadable, ulong load_address)
return 0;
res = request_sdram_region("fip", load_address,
- loadable->image->toc_e.size);
+ loadable->image->toc_e.size,
+ MEMTYPE_LOADER_CODE, MEMATTRS_RW);
if (!res)
return -EBUSY;
diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
index 800d6b3cabff..ab41da5cab50 100644
--- a/arch/arm/cpu/cpu.c
+++ b/arch/arm/cpu/cpu.c
@@ -104,7 +104,8 @@ static int arm_request_stack(void)
if (efi_is_payload())
return 0;
- if (!request_barebox_region("stack", arm_stack_top - STACK_SIZE, STACK_SIZE))
+ if (!request_barebox_region("stack", arm_stack_top - STACK_SIZE, STACK_SIZE,
+ MEMATTRS_RW))
pr_err("Error: Cannot request SDRAM region for stack\n");
return 0;
diff --git a/arch/arm/cpu/mmu_32.c b/arch/arm/cpu/mmu_32.c
index ec6bd27da4e1..3758241fa8a9 100644
--- a/arch/arm/cpu/mmu_32.c
+++ b/arch/arm/cpu/mmu_32.c
@@ -390,7 +390,8 @@ static void create_vector_table(unsigned long adr)
void *vectors;
u32 *pte;
- vectors_sdram = request_barebox_region("vector table", adr, PAGE_SIZE);
+ vectors_sdram = request_barebox_region("vector table", adr, PAGE_SIZE,
+ MEMATTRS_RWX); // FIXME
if (vectors_sdram) {
/*
* The vector table address is inside the SDRAM physical
@@ -472,7 +473,8 @@ static void create_zero_page(void)
* In case the zero page is in SDRAM request it to prevent others
* from using it
*/
- request_sdram_region("zero page", 0x0, PAGE_SIZE);
+ request_sdram_region("zero page", 0x0, PAGE_SIZE,
+ MEMTYPE_BOOT_SERVICES_DATA, MEMATTRS_FAULT);
zero_page_faulting();
pr_debug("Created zero page\n");
@@ -486,7 +488,7 @@ static void create_guard_page(void)
return;
guard_page = arm_mem_guard_page_get();
- request_barebox_region("guard page", guard_page, PAGE_SIZE);
+ request_barebox_region("guard page", guard_page, PAGE_SIZE, MEMATTRS_FAULT);
remap_range((void *)guard_page, PAGE_SIZE, MAP_FAULT);
pr_debug("Created guard page\n");
@@ -535,8 +537,11 @@ void __mmu_init(bool mmu_on)
struct memory_bank *bank;
uint32_t *ttb = get_ttb();
+ // TODO: remap writable only while remapping?
+ // TODO: What memtype for ttb when barebox is EFI loader?
if (!request_barebox_region("ttb", (unsigned long)ttb,
- ARM_EARLY_PAGETABLE_SIZE))
+ ARM_EARLY_PAGETABLE_SIZE,
+ MEMATTRS_RW))
/*
* This can mean that:
* - the early MMU code has put the ttb into a place
diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c
index bc1a44d0a7b8..210b417461c6 100644
--- a/arch/arm/cpu/mmu_64.c
+++ b/arch/arm/cpu/mmu_64.c
@@ -314,7 +314,8 @@ static void create_guard_page(void)
return;
guard_page = arm_mem_guard_page_get();
- request_barebox_region("guard page", guard_page, PAGE_SIZE);
+ request_barebox_region("guard page", guard_page, PAGE_SIZE,
+ MEMATTRS_FAULT);
remap_range((void *)guard_page, PAGE_SIZE, MAP_FAULT);
pr_debug("Created guard page\n");
@@ -328,8 +329,10 @@ void __mmu_init(bool mmu_on)
uint64_t *ttb = get_ttb();
struct memory_bank *bank;
+ // TODO: remap writable only while remapping?
+ // TODO: What memtype for ttb when barebox is EFI loader?
if (!request_barebox_region("ttb", (unsigned long)ttb,
- ARM_EARLY_PAGETABLE_SIZE))
+ ARM_EARLY_PAGETABLE_SIZE, MEMATTRS_RW))
/*
* This can mean that:
* - the early MMU code has put the ttb into a place
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index d6ab5a16b5bb..f7d4507e7158 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -120,7 +120,8 @@ static int barebox_memory_areas_init(void)
{
if (kasan_enabled())
request_sdram_region("kasan shadow", kasan_shadow_base,
- mem_malloc_start() - kasan_shadow_base);
+ mem_malloc_start() - kasan_shadow_base,
+ MEMTYPE_BOOT_SERVICES_DATA, MEMATTRS_RW);
return 0;
}
diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c
index 32af112ae8c8..6fa8ed252c31 100644
--- a/arch/arm/lib32/bootm.c
+++ b/arch/arm/lib32/bootm.c
@@ -160,7 +160,8 @@ static int optee_verify_header_request_region(struct image_data *data, struct op
return ret;
}
- data->tee_res = request_sdram_region("TEE", hdr->init_load_addr_lo, hdr->init_size);
+ data->tee_res = request_sdram_region("TEE", hdr->init_load_addr_lo, hdr->init_size,
+ MEMTYPE_RESERVED, MEMATTRS_RW_DEVICE);
if (!data->tee_res) {
pr_err("Cannot request SDRAM region 0x%08x-0x%08x: %pe\n",
hdr->init_load_addr_lo, hdr->init_load_addr_lo + hdr->init_size - 1,
@@ -502,7 +503,8 @@ static int do_bootz_linux(struct image_data *data)
if (ret)
return ret;
- data->os_res = request_sdram_region("zimage", load_address, image_size);
+ data->os_res = request_sdram_region("zimage", load_address, image_size,
+ MEMTYPE_LOADER_CODE, MEMATTRS_RWX);
if (!data->os_res) {
pr_err("bootm/zImage: failed to request memory at 0x%lx to 0x%lx (%zu).\n",
load_address, load_address + image_size, image_size);
@@ -626,13 +628,15 @@ static int do_bootm_aimage(struct image_data *data)
}
cmp = &header->kernel;
- data->os_res = request_sdram_region("akernel", cmp->load_addr, cmp->size);
+ data->os_res = request_sdram_region("akernel", cmp->load_addr, cmp->size,
+ MEMTYPE_LOADER_CODE, MEMATTRS_RWX);
if (!data->os_res) {
pr_err("Cannot request region 0x%08x - 0x%08x, using default load address\n",
cmp->load_addr, cmp->size);
data->os_address = mem_start + PAGE_ALIGN(cmp->size * 4);
- data->os_res = request_sdram_region("akernel", data->os_address, cmp->size);
+ data->os_res = request_sdram_region("akernel", data->os_address, cmp->size,
+ MEMTYPE_LOADER_CODE, MEMATTRS_RWX);
if (!data->os_res) {
pr_err("Cannot request region 0x%08x - 0x%08x\n",
cmp->load_addr, cmp->size);
@@ -653,7 +657,8 @@ static int do_bootm_aimage(struct image_data *data)
*/
cmp = &header->ramdisk;
if (cmp->size) {
- data->initrd_res = request_sdram_region("ainitrd", cmp->load_addr, cmp->size);
+ data->initrd_res = request_sdram_region("ainitrd", cmp->load_addr, cmp->size,
+ MEMTYPE_LOADER_DATA, MEMATTRS_RW);
if (!data->initrd_res) {
ret = -ENOMEM;
goto err_out;
@@ -676,7 +681,8 @@ static int do_bootm_aimage(struct image_data *data)
if (cmp->size) {
void (*second)(void);
- snd_stage_res = request_sdram_region("asecond", cmp->load_addr, cmp->size);
+ snd_stage_res = request_sdram_region("asecond", cmp->load_addr, cmp->size,
+ MEMTYPE_LOADER_CODE, MEMATTRS_RWX);
if (!snd_stage_res) {
ret = -ENOMEM;
goto err_out;
diff --git a/arch/arm/lib32/bootz.c b/arch/arm/lib32/bootz.c
index 8e8b0d225ecf..25b8827c1ab1 100644
--- a/arch/arm/lib32/bootz.c
+++ b/arch/arm/lib32/bootz.c
@@ -87,7 +87,9 @@ static int do_bootz(int argc, char *argv[])
} else {
zimage = (void *)bank->start + SZ_8M;
res = request_sdram_region("zimage",
- bank->start + SZ_8M, end);
+ bank->start + SZ_8M, end,
+ MEMTYPE_LOADER_CODE,
+ MEMATTRS_RWX);
if (!res) {
printf("can't request region for kernel\n");
goto err_out1;
diff --git a/arch/mips/lib/cpu-probe.c b/arch/mips/lib/cpu-probe.c
index ccb27a81497f..92d5c59e6610 100644
--- a/arch/mips/lib/cpu-probe.c
+++ b/arch/mips/lib/cpu-probe.c
@@ -231,7 +231,8 @@ unsigned long mips_stack_top;
static int mips_request_stack(void)
{
- if (!request_barebox_region("stack", mips_stack_top - STACK_SIZE, STACK_SIZE))
+ if (!request_barebox_region("stack", mips_stack_top - STACK_SIZE, STACK_SIZE,
+ MEMATTRS_RW))
pr_err("Error: Cannot request SDRAM region for stack\n");
return 0;
diff --git a/arch/powerpc/mach-mpc5xxx/cpu.c b/arch/powerpc/mach-mpc5xxx/cpu.c
index 80bf3ccacd03..b4e09cc80545 100644
--- a/arch/powerpc/mach-mpc5xxx/cpu.c
+++ b/arch/powerpc/mach-mpc5xxx/cpu.c
@@ -40,7 +40,8 @@ static int mpc5xxx_reserve_region(void)
struct resource *r;
/* keep this in sync with the assembler routines setting up the stack */
- r = request_barebox_region("stack", _text_base - STACK_SIZE, STACK_SIZE);
+ r = request_barebox_region("stack", _text_base - STACK_SIZE, STACK_SIZE,
+ MEMATTRS_RW);
if (r == NULL) {
pr_err("Failed to request stack region at: 0x%08lx/0x%08lx\n",
_text_base - STACK_SIZE, _text_base - 1);
diff --git a/arch/powerpc/mach-mpc85xx/cpu.c b/arch/powerpc/mach-mpc85xx/cpu.c
index b0580f774be4..23da0eac4c39 100644
--- a/arch/powerpc/mach-mpc85xx/cpu.c
+++ b/arch/powerpc/mach-mpc85xx/cpu.c
@@ -98,7 +98,7 @@ phys_size_t fsl_get_effective_memsize(void)
static int fsl_reserve_region(void)
{
request_barebox_region("stack", _text_base - STACK_SIZE,
- STACK_SIZE);
+ STACK_SIZE, MEMATTRS_RW);
return 0;
}
coredevice_initcall(fsl_reserve_region);
diff --git a/arch/riscv/boot/start.c b/arch/riscv/boot/start.c
index ab9bb6f320f9..5091340c8a37 100644
--- a/arch/riscv/boot/start.c
+++ b/arch/riscv/boot/start.c
@@ -104,7 +104,7 @@ static int barebox_memory_areas_init(void)
{
if(barebox_boarddata)
request_barebox_region("board data", (unsigned long)barebox_boarddata,
- barebox_boarddata_size);
+ barebox_boarddata_size, MEMATTRS_RO);
return 0;
}
diff --git a/arch/riscv/cpu/core.c b/arch/riscv/cpu/core.c
index 4889f774cbb3..b895a0da4311 100644
--- a/arch/riscv/cpu/core.c
+++ b/arch/riscv/cpu/core.c
@@ -30,7 +30,7 @@ static int riscv_request_stack(void)
extern unsigned long riscv_stack_top;
return request_barebox_region("stack",
riscv_stack_top - STACK_SIZE,
- STACK_SIZE) ? 0 : -EINVAL;
+ STACK_SIZE, MEMATTRS_RW) ? 0 : -EINVAL;
}
coredevice_initcall(riscv_request_stack);
diff --git a/common/bootm.c b/common/bootm.c
index 4c5913ffb95c..3ecefe8c60cf 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -187,7 +187,8 @@ int bootm_load_os(struct image_data *data, unsigned long load_address)
unsigned long kernel_size = data->fit_kernel_size;
data->os_res = request_sdram_region("kernel",
- load_address, kernel_size);
+ load_address, kernel_size,
+ MEMTYPE_LOADER_CODE, MEMATTRS_RWX);
if (!data->os_res) {
pr_err("unable to request SDRAM region for kernel at"
" 0x%08llx-0x%08llx\n",
@@ -298,8 +299,8 @@ bootm_load_initrd(struct image_data *data, unsigned long load_address)
return ERR_PTR(ret);
}
data->initrd_res = request_sdram_region("initrd",
- load_address,
- initrd_size);
+ load_address, initrd_size,
+ MEMTYPE_LOADER_DATA, MEMATTRS_RW);
if (!data->initrd_res) {
pr_err("unable to request SDRAM region for initrd at"
" 0x%08llx-0x%08llx\n",
@@ -533,7 +534,7 @@ int bootm_load_devicetree(struct image_data *data, void *fdt,
fdt_size = be32_to_cpu(((struct fdt_header *)fdt)->totalsize);
data->oftree_res = request_sdram_region("oftree", load_address,
- fdt_size);
+ fdt_size, MEMTYPE_LOADER_DATA, MEMATTRS_RW);
if (!data->oftree_res) {
pr_err("unable to request SDRAM region for device tree at"
" 0x%08llx-0x%08llx\n",
diff --git a/common/elf.c b/common/elf.c
index 3cbe63f6b2e6..8578892366c3 100644
--- a/common/elf.c
+++ b/common/elf.c
@@ -32,7 +32,8 @@ static int elf_request_region(struct elf_image *elf, resource_size_t start,
if (!r)
return -ENOMEM;
- r_new = request_sdram_region("elf_section", start, size);
+ r_new = request_sdram_region("elf_section", start, size,
+ MEMTYPE_LOADER_CODE, MEMATTRS_RWX);
if (!r_new) {
r_new = request_iomem_region("elf_section", start, size);
if (!r_new) {
diff --git a/common/memory.c b/common/memory.c
index 4e3cb1571e93..684907e8e933 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -67,7 +67,9 @@ static int mem_register_barebox(void)
{
if (barebox_start && barebox_size)
barebox_res = request_sdram_region("barebox", barebox_start,
- barebox_size);
+ barebox_size,
+ MEMTYPE_BOOT_SERVICES_CODE,
+ MEMATTRS_RWX); // FIXME
return 0;
}
postmem_initcall(mem_register_barebox);
@@ -80,18 +82,32 @@ bool inside_barebox_area(resource_size_t start, resource_size_t end)
struct resource *request_barebox_region(const char *name,
resource_size_t start,
- resource_size_t size)
+ resource_size_t size,
+ unsigned memattrs)
{
resource_size_t end = start + size - 1;
+ enum resource_memtype memtype;
+
+ if (memattrs & MEMATTR_XP)
+ memtype = MEMTYPE_BOOT_SERVICES_DATA;
+ else
+ memtype = MEMTYPE_BOOT_SERVICES_CODE;
if (inside_barebox_area(start, end)) {
struct resource *iores;
iores = __request_region(barebox_res, start, end,
name, IORESOURCE_MEM);
- return !IS_ERR(iores) ? iores : NULL;
+ if (IS_ERR(iores))
+ return NULL;
+
+ iores->type = memtype;
+ iores->attrs = memattrs;
+ iores->flags |= IORESOURCE_TYPE_VALID;
+
+ return iores;
}
- return request_sdram_region(name, start, size);
+ return request_sdram_region(name, start, size, memtype, memattrs);
}
static int mem_malloc_resource(void)
@@ -105,22 +121,27 @@ static int mem_malloc_resource(void)
*/
request_sdram_region("malloc space",
malloc_start,
- malloc_end - malloc_start + 1);
+ malloc_end - malloc_start + 1,
+ MEMTYPE_BOOT_SERVICES_DATA, MEMATTRS_RW);
request_barebox_region("barebox code",
(unsigned long)&_stext,
(unsigned long)&_etext -
- (unsigned long)&_stext);
+ (unsigned long)&_stext,
+ MEMATTRS_RX);
request_barebox_region("barebox data",
(unsigned long)&_sdata,
(unsigned long)&_edata -
- (unsigned long)&_sdata);
+ (unsigned long)&_sdata,
+ MEMATTRS_RW);
request_barebox_region("barebox bss",
(unsigned long)&__bss_start,
(unsigned long)&__bss_stop -
- (unsigned long)&__bss_start);
+ (unsigned long)&__bss_start,
+ MEMATTRS_RW);
#endif
#ifdef STACK_BASE
- request_sdram_region("stack", STACK_BASE, STACK_SIZE);
+ request_sdram_region("stack", STACK_BASE, STACK_SIZE,
+ MEMTYPE_BOOT_SERVICES_DATA, MEMATTRS_RW);
#endif
return 0;
@@ -231,7 +252,8 @@ postmem_initcall(add_mem_devices);
* Request a region from the registered sdram
*/
struct resource *__request_sdram_region(const char *name, unsigned flags,
- resource_size_t start, resource_size_t size)
+ resource_size_t start, resource_size_t size,
+ enum resource_memtype memtype, unsigned memattrs)
{
struct memory_bank *bank;
@@ -242,8 +264,12 @@ struct resource *__request_sdram_region(const char *name, unsigned flags,
res = __request_region(bank->res, start, start + size - 1,
name, flags);
- if (!IS_ERR(res))
+ if (!IS_ERR(res)) {
+ res->type = memtype;
+ res->attrs = memattrs;
+ res->flags |= IORESOURCE_TYPE_VALID;
return res;
+ }
}
return NULL;
@@ -269,6 +295,10 @@ struct resource *reserve_sdram_region(const char *name, resource_size_t start,
if (!res)
return NULL;
+ res->type = MEMTYPE_RESERVED;
+ res->attrs = MEMATTRS_RW_DEVICE;
+ res->flags |= IORESOURCE_TYPE_VALID;
+
remap_range((void *)start, size, MAP_UNCACHED);
return res;
diff --git a/common/memtest.c b/common/memtest.c
index aa16d94eeda0..00b9e90b0765 100644
--- a/common/memtest.c
+++ b/common/memtest.c
@@ -25,7 +25,9 @@ static int alloc_memtest_region(struct list_head *list,
struct mem_test_resource *r;
r = xzalloc(sizeof(struct mem_test_resource));
- r_new = request_sdram_region("memtest", start, size);
+ r_new = request_sdram_region("memtest", start, size,
+ MEMTYPE_BOOT_SERVICES_DATA,
+ MEMATTRS_RW);
if (!r_new)
return -EINVAL;
diff --git a/common/pe.c b/common/pe.c
index fd99761bddfd..0508670a5264 100644
--- a/common/pe.c
+++ b/common/pe.c
@@ -248,7 +248,9 @@ static struct resource *pe_alloc(size_t virt_size)
if (start + virt_size > end)
return NULL;
- return request_sdram_region("pe-code", start, virt_size);
+ return request_sdram_region("pe-code", start, virt_size,
+ MEMTYPE_LOADER_CODE,
+ MEMATTRS_RWX);
}
unsigned long pe_get_mem_size(struct pe_image *pe)
diff --git a/common/uimage.c b/common/uimage.c
index 06a2c05ead67..3e456e9c58ab 100644
--- a/common/uimage.c
+++ b/common/uimage.c
@@ -347,7 +347,8 @@ static long uimage_sdram_flush(void *buf, unsigned long len)
release_sdram_region(uimage_resource);
uimage_resource = request_sdram_region("uimage",
- start, size);
+ start, size, MEMTYPE_LOADER_CODE,
+ MEMATTRS_RWX);
if (!uimage_resource) {
resource_size_t prsize = start + size - 1;
printf("unable to request SDRAM %pa - %pa\n",
@@ -385,7 +386,8 @@ struct resource *uimage_load_to_sdram(struct uimage_handle *handle,
return NULL;
uimage_resource = request_sdram_region("uimage",
- start, size);
+ start, size, MEMTYPE_LOADER_CODE,
+ MEMATTRS_RWX);
if (!uimage_resource) {
printf("unable to request SDRAM 0x%08llx-0x%08llx\n",
(unsigned long long)start,
diff --git a/drivers/tee/optee/of_fixup.c b/drivers/tee/optee/of_fixup.c
index e801c4c95070..223f67e872aa 100644
--- a/drivers/tee/optee/of_fixup.c
+++ b/drivers/tee/optee/of_fixup.c
@@ -38,6 +38,7 @@ int of_optee_fixup(struct device_node *root, void *_data)
res_core.end = arm_mem_endmem_get() - fixup_data->shm_size - 1;
}
res_core.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ reserve_resource(&res_core);
res_core.name = "optee_core";
ret = of_fixup_reserved_memory(root, &res_core);
@@ -55,6 +56,8 @@ int of_optee_fixup(struct device_node *root, void *_data)
res_shm.end = arm_mem_endmem_get() - 1;
}
res_shm.flags = IORESOURCE_MEM;
+ res_shm.type = MEMTYPE_CONVENTIONAL;
+ res_shm.attrs = MEMATTRS_RW | MEMATTR_SP;
res_shm.name = "optee_shm";
return of_fixup_reserved_memory(root, &res_shm);
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index 496c803045c3..621987f1bade 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -342,10 +342,14 @@ void persistent_ram_zap(struct persistent_ram_zone *prz)
static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size,
struct persistent_ram_zone *prz, int memtype)
{
- prz->res = request_barebox_region(prz->label ?: "ramoops", start, size);
+ prz->res = request_barebox_region(prz->label ?: "ramoops", start, size,
+ MEMATTRS_RW | MEMATTR_SP);
if (!prz->res)
return -ENOMEM;
+ prz->res->type = MEMTYPE_PERSISTENT;
+ prz->res->runtime = true;
+
prz->paddr = start;
prz->size = size;
diff --git a/include/memory.h b/include/memory.h
index 707c0f13130d..7c5b133b7693 100644
--- a/include/memory.h
+++ b/include/memory.h
@@ -33,14 +33,25 @@ int barebox_add_memory_bank(const char *name, resource_size_t start,
if (((rsv)->flags & IORESOURCE_BUSY))
struct resource *__request_sdram_region(const char *name, unsigned flags,
- resource_size_t start, resource_size_t size);
+ 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)
+ resource_size_t size,
+ enum resource_memtype memtype,
+ unsigned memattrs)
{
+ struct resource *res;
+
/* IORESOURCE_MEM is implicit for all SDRAM regions */
- return __request_sdram_region(name, 0, start, size);
+ res = __request_sdram_region(name, 0, start, size);
+ if (IS_ENABLED(CONFIG_MEMORY_ATTRIBUTES) && res) {
+ res->type = memtype;
+ res->attrs = memattrs;
+ res->flags |= IORESOURCE_TYPE_VALID;
+ }
+
+ return res;
}
struct resource *reserve_sdram_region(const char *name, resource_size_t start,
@@ -67,11 +78,13 @@ void register_barebox_area(resource_size_t start, resource_size_t size);
bool inside_barebox_area(resource_size_t start, resource_size_t end);
struct resource *request_barebox_region(const char *name,
resource_size_t start,
- resource_size_t size);
+ resource_size_t size,
+ unsigned memattrs);
#else
static inline struct resource *request_barebox_region(const char *name,
resource_size_t start,
- resource_size_t size)
+ resource_size_t size,
+ unsigned memattrs)
{
return NULL;
diff --git a/lib/Kconfig.hardening b/lib/Kconfig.hardening
index 7567f3e9aaaf..ac1acefafb2c 100644
--- a/lib/Kconfig.hardening
+++ b/lib/Kconfig.hardening
@@ -243,4 +243,11 @@ config PBL_STACKPROTECTOR_ALL
endchoice
+config MEMORY_ATTRIBUTES
+ bool "record memory attributes" if EXPERIMENTAL
+ help
+ Tag all SDRAM memory region requests with type and attributes.
+ This is currently not acted upon, but protections (e.g. read-only)
+ will in future be enforced by the MMU.
+
endmenu
diff --git a/lib/libfile.c b/lib/libfile.c
index 80d4591dd6e5..15a495ff1f45 100644
--- a/lib/libfile.c
+++ b/lib/libfile.c
@@ -749,6 +749,7 @@ int cache_file(const char *path, char **newpath)
struct resource *file_to_sdram(const char *filename, unsigned long adr)
{
struct resource *res;
+ unsigned memattrs;
size_t size = BUFSIZ;
size_t ofs = 0;
ssize_t now;
@@ -758,8 +759,15 @@ struct resource *file_to_sdram(const char *filename, unsigned long adr)
if (fd < 0)
return NULL;
+ /* FIXME: EFI payloads are started with MMU enabled, so for now
+ * we keep attributes as RWX instead of remapping later on
+ */
+ memattrs = IS_ENABLED(CONFIG_EFI_LOADER) ? MEMATTRS_RWX : MEMATTRS_RW;
+
while (1) {
- res = request_sdram_region("image", adr, size);
+
+ res = request_sdram_region("image", adr, size,
+ MEMTYPE_LOADER_CODE, memattrs);
if (!res) {
printf("unable to request SDRAM 0x%08lx-0x%08lx\n",
adr, adr + size - 1);
@@ -788,7 +796,8 @@ struct resource *file_to_sdram(const char *filename, unsigned long adr)
if (now < BUFSIZ) {
release_sdram_region(res);
- res = request_sdram_region("image", adr, ofs + now);
+ res = request_sdram_region("image", adr, ofs + now,
+ MEMTYPE_LOADER_CODE, memattrs);
goto out;
}
diff --git a/pbl/handoff-data.c b/pbl/handoff-data.c
index a0a04cad0ca3..42e53f986bf1 100644
--- a/pbl/handoff-data.c
+++ b/pbl/handoff-data.c
@@ -202,7 +202,8 @@ static int handoff_data_reserve(void)
list_for_each_entry(hde, &hd->entries, list) {
const char *name = handoff_data_entry_name(hde);
- request_barebox_region(name, (resource_size_t)hde->data, hde->size);
+ request_barebox_region(name, (resource_size_t)hde->data, hde->size,
+ MEMATTRS_RO);
}
return 0;
--
2.39.5
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 6/6] resource: retire IORESOURCE_BUSY in favor of resource::type
2025-05-26 14:19 [PATCH v2 0/6] resource: record memory type/attrs on all SDRAM Ahmad Fatoum
` (4 preceding siblings ...)
2025-05-26 14:19 ` [PATCH v2 5/6] resource: supply memory type/attrs on all SDRAM requests Ahmad Fatoum
@ 2025-05-26 14:19 ` Ahmad Fatoum
5 siblings, 0 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2025-05-26 14:19 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The way we use IORESOURCE_BUSY in barebox is different than in Linux and
was only done to have a bit that doesn't sound too off-topic.
Now that we have proper memory type and attributes, let's make use of
them and retire IORESOURCE_BUSY.
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
commands/iomemport.c | 2 +-
common/memory.c | 22 ++++++----------------
common/oftree.c | 2 +-
drivers/tee/optee/of_fixup.c | 2 +-
include/memory.h | 6 +++---
5 files changed, 12 insertions(+), 22 deletions(-)
diff --git a/commands/iomemport.c b/commands/iomemport.c
index f2baa0e29397..bbe41f571b48 100644
--- a/commands/iomemport.c
+++ b/commands/iomemport.c
@@ -18,7 +18,7 @@ static void __print_resources(struct resource *res, int indent)
printf("%pa - %pa (size %pa) %s%s\n",
&res->start, &res->end, &size,
- res->flags & IORESOURCE_BUSY ? "[R] " : "",
+ is_reserved_resource(res) ? "[R] " : "",
res->name);
list_for_each_entry(r, &res->children, sibling) {
diff --git a/common/memory.c b/common/memory.c
index 684907e8e933..8c9f29ca71b2 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -251,25 +251,18 @@ postmem_initcall(add_mem_devices);
/*
* Request a region from the registered sdram
*/
-struct resource *__request_sdram_region(const char *name, unsigned flags,
- resource_size_t start, resource_size_t size,
- enum resource_memtype memtype, unsigned memattrs)
+struct resource *__request_sdram_region(const char *name,
+ 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, flags);
- if (!IS_ERR(res)) {
- res->type = memtype;
- res->attrs = memattrs;
- res->flags |= IORESOURCE_TYPE_VALID;
+ name, IORESOURCE_MEM);
+ if (!IS_ERR(res))
return res;
- }
}
return NULL;
@@ -291,14 +284,11 @@ struct resource *reserve_sdram_region(const char *name, resource_size_t start,
size = ALIGN(size, PAGE_SIZE);
}
- res = __request_sdram_region(name, IORESOURCE_BUSY, start, size);
+ res = request_sdram_region(name, start, size,
+ MEMTYPE_RESERVED, MEMATTRS_RW_DEVICE);
if (!res)
return NULL;
- res->type = MEMTYPE_RESERVED;
- res->attrs = MEMATTRS_RW_DEVICE;
- res->flags |= IORESOURCE_TYPE_VALID;
-
remap_range((void *)start, size, MAP_UNCACHED);
return res;
diff --git a/common/oftree.c b/common/oftree.c
index b9a854c786f6..a7479164e288 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -304,7 +304,7 @@ int of_fixup_reserved_memory(struct device_node *root, void *_res)
child = of_get_child_by_name(node, res->name) ?: of_new_node(node, res->name);
- if (res->flags & IORESOURCE_BUSY)
+ if (is_reserved_resource(res))
of_property_write_bool(child, "no-map", true);
of_write_number(reg, res->start, addr_n_cells);
diff --git a/drivers/tee/optee/of_fixup.c b/drivers/tee/optee/of_fixup.c
index 223f67e872aa..f3ccff31e68a 100644
--- a/drivers/tee/optee/of_fixup.c
+++ b/drivers/tee/optee/of_fixup.c
@@ -37,7 +37,7 @@ int of_optee_fixup(struct device_node *root, void *_data)
res_core.start = arm_mem_endmem_get() - OPTEE_SIZE;
res_core.end = arm_mem_endmem_get() - fixup_data->shm_size - 1;
}
- res_core.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ res_core.flags = IORESOURCE_MEM;
reserve_resource(&res_core);
res_core.name = "optee_core";
diff --git a/include/memory.h b/include/memory.h
index 7c5b133b7693..c430375e4316 100644
--- a/include/memory.h
+++ b/include/memory.h
@@ -30,9 +30,9 @@ 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)
#define for_each_reserved_region(mem, rsv) \
list_for_each_entry(rsv, &(mem)->res->children, sibling) \
- if (((rsv)->flags & IORESOURCE_BUSY))
+ if (is_reserved_resource(rsv))
-struct resource *__request_sdram_region(const char *name, unsigned flags,
+struct resource *__request_sdram_region(const char *name,
resource_size_t start, resource_size_t size);
static inline struct resource *request_sdram_region(const char *name,
@@ -44,7 +44,7 @@ static inline struct resource *request_sdram_region(const char *name,
struct resource *res;
/* IORESOURCE_MEM is implicit for all SDRAM regions */
- res = __request_sdram_region(name, 0, start, size);
+ res = __request_sdram_region(name, start, size);
if (IS_ENABLED(CONFIG_MEMORY_ATTRIBUTES) && res) {
res->type = memtype;
res->attrs = memattrs;
--
2.39.5
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-05-26 14:20 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-05-26 14:19 [PATCH v2 0/6] resource: record memory type/attrs on all SDRAM Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 1/6] memory: export inside_barebox_area Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 2/6] resource: record EFI memory type and attributes Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 3/6] resource: add MEMATTRS_ definitions for common attribute sets Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 4/6] drivers: tee: optee: separate local variables for each resource Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 5/6] resource: supply memory type/attrs on all SDRAM requests Ahmad Fatoum
2025-05-26 14:19 ` [PATCH v2 6/6] resource: retire IORESOURCE_BUSY in favor of resource::type Ahmad Fatoum
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox