summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/cpu/armv8/cache_v8.c48
-rw-r--r--arch/arm/include/asm/system.h18
2 files changed, 46 insertions, 20 deletions
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index c4b3da4a8da..c9948e99e2e 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -967,61 +967,69 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
flush_dcache_range(real_start, real_start + real_size);
}
-/*
- * Modify MMU table for a region with updated PXN/UXN/Memory type/valid bits.
- * The procecess is break-before-make. The target region will be marked as
- * invalid during the process of changing.
- */
-void mmu_change_region_attr(phys_addr_t addr, size_t siz, u64 attrs)
+void mmu_change_region_attr_nobreak(phys_addr_t addr, size_t siz, u64 attrs)
{
int level;
u64 r, size, start;
- start = addr;
- size = siz;
/*
* Loop through the address range until we find a page granule that fits
- * our alignment constraints, then set it to "invalid".
+ * our alignment constraints and set the new permissions
*/
+ start = addr;
+ size = siz;
while (size > 0) {
for (level = 1; level < 4; level++) {
- /* Set PTE to fault */
- r = set_one_region(start, size, PTE_TYPE_FAULT, true,
- level);
+ /* Set PTE to new attributes */
+ r = set_one_region(start, size, attrs, true, level);
if (r) {
- /* PTE successfully invalidated */
+ /* PTE successfully updated */
size -= r;
start += r;
break;
}
}
}
-
flush_dcache_range(gd->arch.tlb_addr,
gd->arch.tlb_addr + gd->arch.tlb_size);
__asm_invalidate_tlb_all();
+}
+/*
+ * Modify MMU table for a region with updated PXN/UXN/Memory type/valid bits.
+ * The procecess is break-before-make. The target region will be marked as
+ * invalid during the process of changing.
+ */
+void mmu_change_region_attr(phys_addr_t addr, size_t siz, u64 attrs)
+{
+ int level;
+ u64 r, size, start;
+
+ start = addr;
+ size = siz;
/*
* Loop through the address range until we find a page granule that fits
- * our alignment constraints, then set it to the new cache attributes
+ * our alignment constraints, then set it to "invalid".
*/
- start = addr;
- size = siz;
while (size > 0) {
for (level = 1; level < 4; level++) {
- /* Set PTE to new attributes */
- r = set_one_region(start, size, attrs, true, level);
+ /* Set PTE to fault */
+ r = set_one_region(start, size, PTE_TYPE_FAULT, true,
+ level);
if (r) {
- /* PTE successfully updated */
+ /* PTE successfully invalidated */
size -= r;
start += r;
break;
}
}
}
+
flush_dcache_range(gd->arch.tlb_addr,
gd->arch.tlb_addr + gd->arch.tlb_size);
__asm_invalidate_tlb_all();
+
+ mmu_change_region_attr_nobreak(addr, siz, attrs);
}
#else /* !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 091082281c7..849b3d0efb7 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -303,8 +303,26 @@ void flush_l3_cache(void);
* @emerg: Also map the region in the emergency table
*/
void mmu_map_region(phys_addr_t start, u64 size, bool emerg);
+
+/**
+ * mmu_change_region_attr() - change a mapped region attributes
+ *
+ * @start: Start address of the region
+ * @size: Size of the region
+ * @aatrs: New attributes
+ */
void mmu_change_region_attr(phys_addr_t start, size_t size, u64 attrs);
+/**
+ * mmu_change_region_attr_nobreak() - change a mapped region attributes without doing
+ * break-before-make
+ *
+ * @start: Start address of the region
+ * @size: Size of the region
+ * @aatrs: New attributes
+ */
+void mmu_change_region_attr_nobreak(phys_addr_t addr, size_t size, u64 attrs);
+
/*
* smc_call() - issue a secure monitor call
*