Skip to content

Commit 598f0a9

Browse files
Zhen LeiRussell King (Oracle)
authored andcommitted
ARM: 9210/1: Mark the FDT_FIXED sections as shareable
commit 7a1be31 ("ARM: 9012/1: move device tree mapping out of linear region") use FDT_FIXED_BASE to map the whole FDT_FIXED_SIZE memory area which contains fdt. But it only reserves the exact physical memory that fdt occupied. Unfortunately, this mapping is non-shareable. An illegal or speculative read access can bring the RAM content from non-fdt zone into cache, PIPT makes it to be hit by subsequently read access through shareable mapping(such as linear mapping), and the cache consistency between cores is lost due to non-shareable property. |<---------FDT_FIXED_SIZE------>| | | ------------------------------- | <non-fdt> | <fdt> | <non-fdt> | ------------------------------- 1. CoreA read <non-fdt> through MT_ROM mapping, the old data is loaded into the cache. 2. CoreB write <non-fdt> to update data through linear mapping. CoreA received the notification to invalid the corresponding cachelines, but the property non-shareable makes it to be ignored. 3. CoreA read <non-fdt> through linear mapping, cache hit, the old data is read. To eliminate this risk, add a new memory type MT_MEMORY_RO. Compared to MT_ROM, it is shareable and non-executable. Here's an example: list_del corruption. prev->next should be c0ecbf74, but was c08410dc kernel BUG at lib/list_debug.c:53! ... ... PC is at __list_del_entry_valid+0x58/0x98 LR is at __list_del_entry_valid+0x58/0x98 psr: 60000093 sp : c0ecbf30 ip : 00000000 fp : 00000001 r10: c08410d0 r9 : 00000001 r8 : c0825e0c r7 : 20000013 r6 : c08410d0 r5 : c0ecbf74 r4 : c0ecbf74 r3 : c0825d08 r2 : 00000000 r1 : df7ce6f4 r0 : 00000044 ... ... Stack: (0xc0ecbf30 to 0xc0ecc000) bf20: c0ecbf74 c0164fd0 c0ecbf70 c016517 bf40: c0eca000 c0840c00 c0840c00 c0824500 c0825e0c c0189bbc c088f404 60000013 bf60: 60000013 c0e85100 000004ec 00000000 c0ebcdc0 c0ecbf74 c0ecbf74 c0825d08 ... ... < next prev > (__list_del_entry_valid) from (__list_del_entry+0xc/0x20) (__list_del_entry) from (finish_swait+0x60/0x7c) (finish_swait) from (rcu_gp_kthread+0x560/0xa20) (rcu_gp_kthread) from (kthread+0x14c/0x15c) (kthread) from (ret_from_fork+0x14/0x24) The faulty list node to be deleted is a local variable, its address is c0ecbf74. The dumped stack shows that 'prev' = c0ecbf74, but its value before lib/list_debug.c:53 is c08410dc. A large amount of printing results in swapping out the cacheline containing the old data(MT_ROM mapping is read only, so the cacheline cannot be dirty), and the subsequent dump operation obtains new data from the DDR. Fixes: 7a1be31 ("ARM: 9012/1: move device tree mapping out of linear region") Suggested-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org> Reviewed-by: Kefeng Wang <wangkefeng.wang@huawei.com> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
1 parent 0609e20 commit 598f0a9

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

arch/arm/include/asm/mach/map.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ enum {
2727
MT_HIGH_VECTORS,
2828
MT_MEMORY_RWX,
2929
MT_MEMORY_RW,
30+
MT_MEMORY_RO,
3031
MT_ROM,
3132
MT_MEMORY_RWX_NONCACHED,
3233
MT_MEMORY_RW_DTCM,

arch/arm/mm/mmu.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,13 @@ static struct mem_type mem_types[] __ro_after_init = {
296296
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
297297
.domain = DOMAIN_KERNEL,
298298
},
299+
[MT_MEMORY_RO] = {
300+
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
301+
L_PTE_XN | L_PTE_RDONLY,
302+
.prot_l1 = PMD_TYPE_TABLE,
303+
.prot_sect = PMD_TYPE_SECT,
304+
.domain = DOMAIN_KERNEL,
305+
},
299306
[MT_ROM] = {
300307
.prot_sect = PMD_TYPE_SECT,
301308
.domain = DOMAIN_KERNEL,
@@ -489,6 +496,7 @@ static void __init build_mem_type_table(void)
489496

490497
/* Also setup NX memory mapping */
491498
mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_XN;
499+
mem_types[MT_MEMORY_RO].prot_sect |= PMD_SECT_XN;
492500
}
493501
if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
494502
/*
@@ -568,6 +576,7 @@ static void __init build_mem_type_table(void)
568576
mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
569577
mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
570578
mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
579+
mem_types[MT_MEMORY_RO].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
571580
#endif
572581

573582
/*
@@ -587,6 +596,8 @@ static void __init build_mem_type_table(void)
587596
mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED;
588597
mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_S;
589598
mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_SHARED;
599+
mem_types[MT_MEMORY_RO].prot_sect |= PMD_SECT_S;
600+
mem_types[MT_MEMORY_RO].prot_pte |= L_PTE_SHARED;
590601
mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
591602
mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S;
592603
mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= L_PTE_SHARED;
@@ -647,6 +658,8 @@ static void __init build_mem_type_table(void)
647658
mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot;
648659
mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd;
649660
mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot;
661+
mem_types[MT_MEMORY_RO].prot_sect |= ecc_mask | cp->pmd;
662+
mem_types[MT_MEMORY_RO].prot_pte |= kern_pgprot;
650663
mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
651664
mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask;
652665
mem_types[MT_ROM].prot_sect |= cp->pmd;
@@ -1360,7 +1373,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
13601373
map.pfn = __phys_to_pfn(__atags_pointer & SECTION_MASK);
13611374
map.virtual = FDT_FIXED_BASE;
13621375
map.length = FDT_FIXED_SIZE;
1363-
map.type = MT_ROM;
1376+
map.type = MT_MEMORY_RO;
13641377
create_mapping(&map);
13651378
}
13661379

0 commit comments

Comments
 (0)