diff options
Diffstat (limited to 'arch/arm64/kernel/head.S')
-rw-r--r-- | arch/arm64/kernel/head.S | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 61035d6814cb..26109682d2fa 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/assembler.h> | 26 | #include <asm/assembler.h> |
27 | #include <asm/ptrace.h> | 27 | #include <asm/ptrace.h> |
28 | #include <asm/asm-offsets.h> | 28 | #include <asm/asm-offsets.h> |
29 | #include <asm/cache.h> | ||
29 | #include <asm/cputype.h> | 30 | #include <asm/cputype.h> |
30 | #include <asm/memory.h> | 31 | #include <asm/memory.h> |
31 | #include <asm/thread_info.h> | 32 | #include <asm/thread_info.h> |
@@ -229,7 +230,11 @@ ENTRY(set_cpu_boot_mode_flag) | |||
229 | cmp w20, #BOOT_CPU_MODE_EL2 | 230 | cmp w20, #BOOT_CPU_MODE_EL2 |
230 | b.ne 1f | 231 | b.ne 1f |
231 | add x1, x1, #4 | 232 | add x1, x1, #4 |
232 | 1: str w20, [x1] // This CPU has booted in EL1 | 233 | 1: dc cvac, x1 // Clean potentially dirty cache line |
234 | dsb sy | ||
235 | str w20, [x1] // This CPU has booted in EL1 | ||
236 | dc civac, x1 // Clean&invalidate potentially stale cache line | ||
237 | dsb sy | ||
233 | ret | 238 | ret |
234 | ENDPROC(set_cpu_boot_mode_flag) | 239 | ENDPROC(set_cpu_boot_mode_flag) |
235 | 240 | ||
@@ -240,8 +245,9 @@ ENDPROC(set_cpu_boot_mode_flag) | |||
240 | * This is not in .bss, because we set it sufficiently early that the boot-time | 245 | * This is not in .bss, because we set it sufficiently early that the boot-time |
241 | * zeroing of .bss would clobber it. | 246 | * zeroing of .bss would clobber it. |
242 | */ | 247 | */ |
243 | .pushsection .data | 248 | .pushsection .data..cacheline_aligned |
244 | ENTRY(__boot_cpu_mode) | 249 | ENTRY(__boot_cpu_mode) |
250 | .align L1_CACHE_SHIFT | ||
245 | .long BOOT_CPU_MODE_EL2 | 251 | .long BOOT_CPU_MODE_EL2 |
246 | .long 0 | 252 | .long 0 |
247 | .popsection | 253 | .popsection |
@@ -408,6 +414,15 @@ ENDPROC(__calc_phys_offset) | |||
408 | */ | 414 | */ |
409 | __create_page_tables: | 415 | __create_page_tables: |
410 | pgtbl x25, x26, x24 // idmap_pg_dir and swapper_pg_dir addresses | 416 | pgtbl x25, x26, x24 // idmap_pg_dir and swapper_pg_dir addresses |
417 | mov x27, lr | ||
418 | |||
419 | /* | ||
420 | * Invalidate the idmap and swapper page tables to avoid potential | ||
421 | * dirty cache lines being evicted. | ||
422 | */ | ||
423 | mov x0, x25 | ||
424 | add x1, x26, #SWAPPER_DIR_SIZE | ||
425 | bl __inval_cache_range | ||
411 | 426 | ||
412 | /* | 427 | /* |
413 | * Clear the idmap and swapper page tables. | 428 | * Clear the idmap and swapper page tables. |
@@ -470,6 +485,17 @@ __create_page_tables: | |||
470 | add x0, x26, #2 * PAGE_SIZE // section table address | 485 | add x0, x26, #2 * PAGE_SIZE // section table address |
471 | create_pgd_entry x26, x0, x5, x6, x7 | 486 | create_pgd_entry x26, x0, x5, x6, x7 |
472 | #endif | 487 | #endif |
488 | |||
489 | /* | ||
490 | * Since the page tables have been populated with non-cacheable | ||
491 | * accesses (MMU disabled), invalidate the idmap and swapper page | ||
492 | * tables again to remove any speculatively loaded cache lines. | ||
493 | */ | ||
494 | mov x0, x25 | ||
495 | add x1, x26, #SWAPPER_DIR_SIZE | ||
496 | bl __inval_cache_range | ||
497 | |||
498 | mov lr, x27 | ||
473 | ret | 499 | ret |
474 | ENDPROC(__create_page_tables) | 500 | ENDPROC(__create_page_tables) |
475 | .ltorg | 501 | .ltorg |