diff options
author | Alexandre Ghiti <alex@ghiti.fr> | 2020-06-13 09:59:13 +0300 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2020-06-15 06:55:44 +0300 |
commit | 6966ad0abe7077b1b5c9342f588621426d997c38 (patch) | |
tree | 2e3cc405f9c5bebff0b54621578fa04d18d52da7 /lib | |
parent | e2c3f01af4329aa7e9009edee13b7cfdf379071f (diff) | |
download | opensbi-6966ad0abe7077b1b5c9342f588621426d997c38.tar.xz |
platform/lib: Allow the OS to map the regions that are protected by PMP
This is achieved by removing the 'no-map' property from the
'reserved-memory' node when PMP is present, otherwise we keep it as it
offers a small protection if the OS does not map this region at all.
A new callback in platform_override is introduced and allows to fixup the
device-tree. It is used here to override this new default behaviour on
SiFive Fu540 platforms that has an erratum that prevents S-mode software
to access a PMP protected region using 1GB page table mapping.
If PMP is present, telling the OS not to map the reserved regions does not
add much protection since it only avoids access to regions that are already
protected by PMP. But by not allowing the OS to map those regions, it
creates holes in the OS system memory map and prevents the use of
hugepages which would generate, among other benefits, less TLB miss.
Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/utils/fdt/fdt_fixup.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/lib/utils/fdt/fdt_fixup.c b/lib/utils/fdt/fdt_fixup.c index 49848b2..adf1be3 100644 --- a/lib/utils/fdt/fdt_fixup.c +++ b/lib/utils/fdt/fdt_fixup.c @@ -70,7 +70,7 @@ void fdt_plic_fixup(void *fdt, const char *compat) static int fdt_resv_memory_update_node(void *fdt, unsigned long addr, unsigned long size, int index, - int parent) + int parent, bool no_map) { int na = fdt_address_cells(fdt, 0); int ns = fdt_size_cells(fdt, 0); @@ -99,14 +99,16 @@ static int fdt_resv_memory_update_node(void *fdt, unsigned long addr, if (subnode < 0) return subnode; - /* - * Tell operating system not to create a virtual - * mapping of the region as part of its standard - * mapping of system memory. - */ - err = fdt_setprop_empty(fdt, subnode, "no-map"); - if (err < 0) - return err; + if (no_map) { + /* + * Tell operating system not to create a virtual + * mapping of the region as part of its standard + * mapping of system memory. + */ + err = fdt_setprop_empty(fdt, subnode, "no-map"); + if (err < 0) + return err; + } /* encode the <reg> property value */ val = reg; @@ -199,7 +201,8 @@ int fdt_reserved_memory_fixup(void *fdt) */ addr = scratch->fw_start & ~(scratch->fw_size - 1UL); size = (1UL << log2roundup(scratch->fw_size)); - return fdt_resv_memory_update_node(fdt, addr, size, 0, parent); + return fdt_resv_memory_update_node(fdt, addr, size, + 0, parent, true); } for (i = 0, j = 0; i < sbi_hart_pmp_count(scratch); i++) { @@ -211,13 +214,37 @@ int fdt_reserved_memory_fixup(void *fdt) if (prot & (PMP_R | PMP_W | PMP_X)) continue; - fdt_resv_memory_update_node(fdt, addr, size, j, parent); + fdt_resv_memory_update_node(fdt, addr, size, j, parent, false); j++; } return 0; } +int fdt_reserved_memory_nomap_fixup(void *fdt) +{ + int parent, subnode; + int err; + + /* Locate the reserved memory node */ + parent = fdt_path_offset(fdt, "/reserved-memory"); + if (parent < 0) + return parent; + + fdt_for_each_subnode(subnode, fdt, parent) { + /* + * Tell operating system not to create a virtual + * mapping of the region as part of its standard + * mapping of system memory. + */ + err = fdt_setprop_empty(fdt, subnode, "no-map"); + if (err < 0) + return err; + } + + return 0; +} + void fdt_fixups(void *fdt) { fdt_plic_fixup(fdt, "riscv,plic0"); |