2019-06-03 05:44:50 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2016-04-27 16:47:12 +00:00
|
|
|
/*
|
|
|
|
* Hibernate low-level support
|
|
|
|
*
|
|
|
|
* Copyright (C) 2016 ARM Ltd.
|
|
|
|
* Author: James Morse <james.morse@arm.com>
|
|
|
|
*/
|
|
|
|
#include <linux/linkage.h>
|
|
|
|
#include <linux/errno.h>
|
|
|
|
|
|
|
|
#include <asm/asm-offsets.h>
|
|
|
|
#include <asm/assembler.h>
|
|
|
|
#include <asm/cputype.h>
|
|
|
|
#include <asm/memory.h>
|
|
|
|
#include <asm/page.h>
|
|
|
|
#include <asm/virt.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Resume from hibernate
|
|
|
|
*
|
|
|
|
* Loads temporary page tables then restores the memory image.
|
|
|
|
* Finally branches to cpu_resume() to restore the state saved by
|
|
|
|
* swsusp_arch_suspend().
|
|
|
|
*
|
|
|
|
* Because this code has to be copied to a 'safe' page, it can't call out to
|
|
|
|
* other functions by PC-relative address. Also remember that it may be
|
|
|
|
* mid-way through over-writing other functions. For this reason it contains
|
arm64: Rename arm64-internal cache maintenance functions
Although naming across the codebase isn't that consistent, it
tends to follow certain patterns. Moreover, the term "flush"
isn't defined in the Arm Architecture reference manual, and might
be interpreted to mean clean, invalidate, or both for a cache.
Rename arm64-internal functions to make the naming internally
consistent, as well as making it consistent with the Arm ARM, by
specifying whether it applies to the instruction, data, or both
caches, whether the operation is a clean, invalidate, or both.
Also specify which point the operation applies to, i.e., to the
point of unification (PoU), coherency (PoC), or persistence
(PoP).
This commit applies the following sed transformation to all files
under arch/arm64:
"s/\b__flush_cache_range\b/caches_clean_inval_pou_macro/g;"\
"s/\b__flush_icache_range\b/caches_clean_inval_pou/g;"\
"s/\binvalidate_icache_range\b/icache_inval_pou/g;"\
"s/\b__flush_dcache_area\b/dcache_clean_inval_poc/g;"\
"s/\b__inval_dcache_area\b/dcache_inval_poc/g;"\
"s/__clean_dcache_area_poc\b/dcache_clean_poc/g;"\
"s/\b__clean_dcache_area_pop\b/dcache_clean_pop/g;"\
"s/\b__clean_dcache_area_pou\b/dcache_clean_pou/g;"\
"s/\b__flush_cache_user_range\b/caches_clean_inval_user_pou/g;"\
"s/\b__flush_icache_all\b/icache_inval_all_pou/g;"
Note that __clean_dcache_area_poc is deliberately missing a word
boundary check at the beginning in order to match the efistub
symbols in image-vars.h.
Also note that, despite its name, __flush_icache_range operates
on both instruction and data caches. The name change here
reflects that.
No functional change intended.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20210524083001.2586635-19-tabba@google.com
Signed-off-by: Will Deacon <will@kernel.org>
2021-05-24 08:30:01 +00:00
|
|
|
* code from caches_clean_inval_pou() and uses the copy_page() macro.
|
2016-04-27 16:47:12 +00:00
|
|
|
*
|
|
|
|
* This 'safe' page is mapped via ttbr0, and executed from there. This function
|
|
|
|
* switches to a copy of the linear map in ttbr1, performs the restore, then
|
|
|
|
* switches ttbr1 to the original kernel's swapper_pg_dir.
|
|
|
|
*
|
|
|
|
* All of memory gets written to, including code. We need to clean the kernel
|
|
|
|
* text to the Point of Coherence (PoC) before secondary cores can be booted.
|
|
|
|
* Because the kernel modules and executable pages mapped to user space are
|
|
|
|
* also written as data, we clean all pages we touch to the Point of
|
|
|
|
* Unification (PoU).
|
|
|
|
*
|
|
|
|
* x0: physical address of temporary page tables
|
|
|
|
* x1: physical address of swapper page tables
|
|
|
|
* x2: address of cpu_resume
|
|
|
|
* x3: linear map address of restore_pblist in the current kernel
|
|
|
|
* x4: physical address of __hyp_stub_vectors, or 0
|
|
|
|
* x5: physical address of a zero page that remains zero after resume
|
|
|
|
*/
|
|
|
|
.pushsection ".hibernate_exit.text", "ax"
|
2020-05-01 11:54:29 +00:00
|
|
|
SYM_CODE_START(swsusp_arch_suspend_exit)
|
2016-04-27 16:47:12 +00:00
|
|
|
/*
|
|
|
|
* We execute from ttbr0, change ttbr1 to our copied linear map tables
|
|
|
|
* with a break-before-make via the zero page
|
|
|
|
*/
|
2019-08-07 15:55:19 +00:00
|
|
|
break_before_make_ttbr_switch x5, x0, x6, x8
|
2016-04-27 16:47:12 +00:00
|
|
|
|
|
|
|
mov x21, x1
|
|
|
|
mov x30, x2
|
|
|
|
mov x24, x4
|
|
|
|
mov x25, x5
|
|
|
|
|
|
|
|
/* walk the restore_pblist and use copy_page() to over-write memory */
|
|
|
|
mov x19, x3
|
|
|
|
|
|
|
|
1: ldr x10, [x19, #HIBERN_PBE_ORIG]
|
|
|
|
mov x0, x10
|
|
|
|
ldr x1, [x19, #HIBERN_PBE_ADDR]
|
|
|
|
|
|
|
|
copy_page x0, x1, x2, x3, x4, x5, x6, x7, x8, x9
|
|
|
|
|
|
|
|
add x1, x10, #PAGE_SIZE
|
arm64: Rename arm64-internal cache maintenance functions
Although naming across the codebase isn't that consistent, it
tends to follow certain patterns. Moreover, the term "flush"
isn't defined in the Arm Architecture reference manual, and might
be interpreted to mean clean, invalidate, or both for a cache.
Rename arm64-internal functions to make the naming internally
consistent, as well as making it consistent with the Arm ARM, by
specifying whether it applies to the instruction, data, or both
caches, whether the operation is a clean, invalidate, or both.
Also specify which point the operation applies to, i.e., to the
point of unification (PoU), coherency (PoC), or persistence
(PoP).
This commit applies the following sed transformation to all files
under arch/arm64:
"s/\b__flush_cache_range\b/caches_clean_inval_pou_macro/g;"\
"s/\b__flush_icache_range\b/caches_clean_inval_pou/g;"\
"s/\binvalidate_icache_range\b/icache_inval_pou/g;"\
"s/\b__flush_dcache_area\b/dcache_clean_inval_poc/g;"\
"s/\b__inval_dcache_area\b/dcache_inval_poc/g;"\
"s/__clean_dcache_area_poc\b/dcache_clean_poc/g;"\
"s/\b__clean_dcache_area_pop\b/dcache_clean_pop/g;"\
"s/\b__clean_dcache_area_pou\b/dcache_clean_pou/g;"\
"s/\b__flush_cache_user_range\b/caches_clean_inval_user_pou/g;"\
"s/\b__flush_icache_all\b/icache_inval_all_pou/g;"
Note that __clean_dcache_area_poc is deliberately missing a word
boundary check at the beginning in order to match the efistub
symbols in image-vars.h.
Also note that, despite its name, __flush_icache_range operates
on both instruction and data caches. The name change here
reflects that.
No functional change intended.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20210524083001.2586635-19-tabba@google.com
Signed-off-by: Will Deacon <will@kernel.org>
2021-05-24 08:30:01 +00:00
|
|
|
/* Clean the copied page to PoU - based on caches_clean_inval_pou() */
|
2016-09-09 13:07:14 +00:00
|
|
|
raw_dcache_line_size x2, x3
|
2016-04-27 16:47:12 +00:00
|
|
|
sub x3, x2, #1
|
|
|
|
bic x4, x10, x3
|
2021-05-24 08:29:46 +00:00
|
|
|
2: /* clean D line / unified line */
|
|
|
|
alternative_insn "dc cvau, x4", "dc civac, x4", ARM64_WORKAROUND_CLEAN_CACHE
|
2016-04-27 16:47:12 +00:00
|
|
|
add x4, x4, x2
|
|
|
|
cmp x4, x1
|
|
|
|
b.lo 2b
|
|
|
|
|
|
|
|
ldr x19, [x19, #HIBERN_PBE_NEXT]
|
|
|
|
cbnz x19, 1b
|
|
|
|
dsb ish /* wait for PoU cleaning to finish */
|
|
|
|
|
|
|
|
/* switch to the restored kernels page tables */
|
2019-08-07 15:55:19 +00:00
|
|
|
break_before_make_ttbr_switch x25, x21, x6, x8
|
2016-04-27 16:47:12 +00:00
|
|
|
|
|
|
|
ic ialluis
|
|
|
|
dsb ish
|
|
|
|
isb
|
|
|
|
|
|
|
|
cbz x24, 3f /* Do we need to re-initialise EL2? */
|
|
|
|
hvc #0
|
|
|
|
3: ret
|
2020-05-01 11:54:29 +00:00
|
|
|
SYM_CODE_END(swsusp_arch_suspend_exit)
|
2016-04-27 16:47:12 +00:00
|
|
|
.popsection
|