23
23
#ifdef CONFIG_RELOCATABLE
24
24
#include <linux/elf.h>
25
25
#endif
26
+ #include <linux/kfence.h>
26
27
27
28
#include <asm/fixmap.h>
28
29
#include <asm/tlbflush.h>
@@ -293,7 +294,7 @@ static const pgprot_t protection_map[16] = {
293
294
[VM_EXEC ] = PAGE_EXEC ,
294
295
[VM_EXEC | VM_READ ] = PAGE_READ_EXEC ,
295
296
[VM_EXEC | VM_WRITE ] = PAGE_COPY_EXEC ,
296
- [VM_EXEC | VM_WRITE | VM_READ ] = PAGE_COPY_READ_EXEC ,
297
+ [VM_EXEC | VM_WRITE | VM_READ ] = PAGE_COPY_EXEC ,
297
298
[VM_SHARED ] = PAGE_NONE ,
298
299
[VM_SHARED | VM_READ ] = PAGE_READ ,
299
300
[VM_SHARED | VM_WRITE ] = PAGE_SHARED ,
@@ -659,18 +660,19 @@ void __init create_pgd_mapping(pgd_t *pgdp,
659
660
create_pgd_next_mapping (nextp , va , pa , sz , prot );
660
661
}
661
662
662
- static uintptr_t __init best_map_size (phys_addr_t base , phys_addr_t size )
663
+ static uintptr_t __init best_map_size (phys_addr_t pa , uintptr_t va ,
664
+ phys_addr_t size )
663
665
{
664
- if (!(base & (PGDIR_SIZE - 1 )) && size >= PGDIR_SIZE )
666
+ if (!(pa & ( PGDIR_SIZE - 1 )) && !( va & (PGDIR_SIZE - 1 )) && size >= PGDIR_SIZE )
665
667
return PGDIR_SIZE ;
666
668
667
- if (!(base & (P4D_SIZE - 1 )) && size >= P4D_SIZE )
669
+ if (!(pa & ( P4D_SIZE - 1 )) && !( va & (P4D_SIZE - 1 )) && size >= P4D_SIZE )
668
670
return P4D_SIZE ;
669
671
670
- if (!(base & (PUD_SIZE - 1 )) && size >= PUD_SIZE )
672
+ if (!(pa & ( PUD_SIZE - 1 )) && !( va & (PUD_SIZE - 1 )) && size >= PUD_SIZE )
671
673
return PUD_SIZE ;
672
674
673
- if (!(base & (PMD_SIZE - 1 )) && size >= PMD_SIZE )
675
+ if (!(pa & ( PMD_SIZE - 1 )) && !( va & (PMD_SIZE - 1 )) && size >= PMD_SIZE )
674
676
return PMD_SIZE ;
675
677
676
678
return PAGE_SIZE ;
@@ -1167,14 +1169,16 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
1167
1169
}
1168
1170
1169
1171
static void __init create_linear_mapping_range (phys_addr_t start ,
1170
- phys_addr_t end )
1172
+ phys_addr_t end ,
1173
+ uintptr_t fixed_map_size )
1171
1174
{
1172
1175
phys_addr_t pa ;
1173
1176
uintptr_t va , map_size ;
1174
1177
1175
1178
for (pa = start ; pa < end ; pa += map_size ) {
1176
1179
va = (uintptr_t )__va (pa );
1177
- map_size = best_map_size (pa , end - pa );
1180
+ map_size = fixed_map_size ? fixed_map_size :
1181
+ best_map_size (pa , va , end - pa );
1178
1182
1179
1183
create_pgd_mapping (swapper_pg_dir , va , pa , map_size ,
1180
1184
pgprot_from_va (va ));
@@ -1184,6 +1188,7 @@ static void __init create_linear_mapping_range(phys_addr_t start,
1184
1188
static void __init create_linear_mapping_page_table (void )
1185
1189
{
1186
1190
phys_addr_t start , end ;
1191
+ phys_addr_t kfence_pool __maybe_unused ;
1187
1192
u64 i ;
1188
1193
1189
1194
#ifdef CONFIG_STRICT_KERNEL_RWX
@@ -1197,6 +1202,19 @@ static void __init create_linear_mapping_page_table(void)
1197
1202
memblock_mark_nomap (krodata_start , krodata_size );
1198
1203
#endif
1199
1204
1205
+ #ifdef CONFIG_KFENCE
1206
+ /*
1207
+ * kfence pool must be backed by PAGE_SIZE mappings, so allocate it
1208
+ * before we setup the linear mapping so that we avoid using hugepages
1209
+ * for this region.
1210
+ */
1211
+ kfence_pool = memblock_phys_alloc (KFENCE_POOL_SIZE , PAGE_SIZE );
1212
+ BUG_ON (!kfence_pool );
1213
+
1214
+ memblock_mark_nomap (kfence_pool , KFENCE_POOL_SIZE );
1215
+ __kfence_pool = __va (kfence_pool );
1216
+ #endif
1217
+
1200
1218
/* Map all memory banks in the linear mapping */
1201
1219
for_each_mem_range (i , & start , & end ) {
1202
1220
if (start >= end )
@@ -1207,17 +1225,25 @@ static void __init create_linear_mapping_page_table(void)
1207
1225
if (end >= __pa (PAGE_OFFSET ) + memory_limit )
1208
1226
end = __pa (PAGE_OFFSET ) + memory_limit ;
1209
1227
1210
- create_linear_mapping_range (start , end );
1228
+ create_linear_mapping_range (start , end , 0 );
1211
1229
}
1212
1230
1213
1231
#ifdef CONFIG_STRICT_KERNEL_RWX
1214
- create_linear_mapping_range (ktext_start , ktext_start + ktext_size );
1232
+ create_linear_mapping_range (ktext_start , ktext_start + ktext_size , 0 );
1215
1233
create_linear_mapping_range (krodata_start ,
1216
- krodata_start + krodata_size );
1234
+ krodata_start + krodata_size , 0 );
1217
1235
1218
1236
memblock_clear_nomap (ktext_start , ktext_size );
1219
1237
memblock_clear_nomap (krodata_start , krodata_size );
1220
1238
#endif
1239
+
1240
+ #ifdef CONFIG_KFENCE
1241
+ create_linear_mapping_range (kfence_pool ,
1242
+ kfence_pool + KFENCE_POOL_SIZE ,
1243
+ PAGE_SIZE );
1244
+
1245
+ memblock_clear_nomap (kfence_pool , KFENCE_POOL_SIZE );
1246
+ #endif
1221
1247
}
1222
1248
1223
1249
static void __init setup_vm_final (void )
0 commit comments