forked from luck/tmp_suning_uos_patched
arm64: consistently use reserved_pg_dir
[ Upstream commit 833be850f1cabd0e3b5337c0fcab20a6e936dd48 ] Depending on configuration options and specific code paths, we either use the empty_zero_page or the configuration-dependent reserved_ttbr0 as a reserved value for TTBR{0,1}_EL1. To simplify this code, let's always allocate and use the same reserved_pg_dir, replacing reserved_ttbr0. Note that this is allocated (and hence pre-zeroed), and is also marked as read-only in the kernel Image mapping. Keeping this separate from the empty_zero_page potentially helps with robustness as the empty_zero_page is used in a number of cases where a failure to map it read-only could allow it to become corrupted. The (presently unused) swapper_pg_end symbol is also removed, and comments are added wherever we rely on the offsets between the pre-allocated pg_dirs to keep these cases easily identifiable. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Will Deacon <will@kernel.org> Link: https://lore.kernel.org/r/20201103102229.8542-1-mark.rutland@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
f1f30b3373
commit
8d6acfe80d
|
@ -15,10 +15,10 @@
|
|||
.macro __uaccess_ttbr0_disable, tmp1
|
||||
mrs \tmp1, ttbr1_el1 // swapper_pg_dir
|
||||
bic \tmp1, \tmp1, #TTBR_ASID_MASK
|
||||
sub \tmp1, \tmp1, #RESERVED_TTBR0_SIZE // reserved_ttbr0 just before swapper_pg_dir
|
||||
sub \tmp1, \tmp1, #PAGE_SIZE // reserved_pg_dir just before swapper_pg_dir
|
||||
msr ttbr0_el1, \tmp1 // set reserved TTBR0_EL1
|
||||
isb
|
||||
add \tmp1, \tmp1, #RESERVED_TTBR0_SIZE
|
||||
add \tmp1, \tmp1, #PAGE_SIZE
|
||||
msr ttbr1_el1, \tmp1 // set reserved ASID
|
||||
isb
|
||||
.endm
|
||||
|
|
|
@ -89,12 +89,6 @@
|
|||
#define INIT_DIR_SIZE (PAGE_SIZE * EARLY_PAGES(KIMAGE_VADDR, _end))
|
||||
#define IDMAP_DIR_SIZE (IDMAP_PGTABLE_LEVELS * PAGE_SIZE)
|
||||
|
||||
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
|
||||
#define RESERVED_TTBR0_SIZE (PAGE_SIZE)
|
||||
#else
|
||||
#define RESERVED_TTBR0_SIZE (0)
|
||||
#endif
|
||||
|
||||
/* Initial memory map size */
|
||||
#if ARM64_SWAPPER_USES_SECTION_MAPS
|
||||
#define SWAPPER_BLOCK_SHIFT SECTION_SHIFT
|
||||
|
|
|
@ -36,11 +36,11 @@ static inline void contextidr_thread_switch(struct task_struct *next)
|
|||
}
|
||||
|
||||
/*
|
||||
* Set TTBR0 to empty_zero_page. No translations will be possible via TTBR0.
|
||||
* Set TTBR0 to reserved_pg_dir. No translations will be possible via TTBR0.
|
||||
*/
|
||||
static inline void cpu_set_reserved_ttbr0(void)
|
||||
{
|
||||
unsigned long ttbr = phys_to_ttbr(__pa_symbol(empty_zero_page));
|
||||
unsigned long ttbr = phys_to_ttbr(__pa_symbol(reserved_pg_dir));
|
||||
|
||||
write_sysreg(ttbr, ttbr0_el1);
|
||||
isb();
|
||||
|
@ -192,7 +192,7 @@ static inline void update_saved_ttbr0(struct task_struct *tsk,
|
|||
return;
|
||||
|
||||
if (mm == &init_mm)
|
||||
ttbr = __pa_symbol(empty_zero_page);
|
||||
ttbr = __pa_symbol(reserved_pg_dir);
|
||||
else
|
||||
ttbr = virt_to_phys(mm->pgd) | ASID(mm) << 48;
|
||||
|
||||
|
|
|
@ -530,6 +530,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
|||
extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
|
||||
extern pgd_t idmap_pg_end[];
|
||||
extern pgd_t tramp_pg_dir[PTRS_PER_PGD];
|
||||
extern pgd_t reserved_pg_dir[PTRS_PER_PGD];
|
||||
|
||||
extern void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd);
|
||||
|
||||
|
|
|
@ -113,8 +113,8 @@ static inline void __uaccess_ttbr0_disable(void)
|
|||
local_irq_save(flags);
|
||||
ttbr = read_sysreg(ttbr1_el1);
|
||||
ttbr &= ~TTBR_ASID_MASK;
|
||||
/* reserved_ttbr0 placed before swapper_pg_dir */
|
||||
write_sysreg(ttbr - RESERVED_TTBR0_SIZE, ttbr0_el1);
|
||||
/* reserved_pg_dir placed before swapper_pg_dir */
|
||||
write_sysreg(ttbr - PAGE_SIZE, ttbr0_el1);
|
||||
isb();
|
||||
/* Set reserved ASID */
|
||||
write_sysreg(ttbr, ttbr1_el1);
|
||||
|
|
|
@ -770,9 +770,10 @@ SYM_CODE_END(ret_to_user)
|
|||
*/
|
||||
.pushsection ".entry.tramp.text", "ax"
|
||||
|
||||
// Move from tramp_pg_dir to swapper_pg_dir
|
||||
.macro tramp_map_kernel, tmp
|
||||
mrs \tmp, ttbr1_el1
|
||||
add \tmp, \tmp, #(PAGE_SIZE + RESERVED_TTBR0_SIZE)
|
||||
add \tmp, \tmp, #(2 * PAGE_SIZE)
|
||||
bic \tmp, \tmp, #USER_ASID_FLAG
|
||||
msr ttbr1_el1, \tmp
|
||||
#ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003
|
||||
|
@ -789,9 +790,10 @@ alternative_else_nop_endif
|
|||
#endif /* CONFIG_QCOM_FALKOR_ERRATUM_1003 */
|
||||
.endm
|
||||
|
||||
// Move from swapper_pg_dir to tramp_pg_dir
|
||||
.macro tramp_unmap_kernel, tmp
|
||||
mrs \tmp, ttbr1_el1
|
||||
sub \tmp, \tmp, #(PAGE_SIZE + RESERVED_TTBR0_SIZE)
|
||||
sub \tmp, \tmp, #(2 * PAGE_SIZE)
|
||||
orr \tmp, \tmp, #USER_ASID_FLAG
|
||||
msr ttbr1_el1, \tmp
|
||||
/*
|
||||
|
|
|
@ -366,7 +366,7 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
|
|||
* faults in case uaccess_enable() is inadvertently called by the init
|
||||
* thread.
|
||||
*/
|
||||
init_task.thread_info.ttbr0 = __pa_symbol(empty_zero_page);
|
||||
init_task.thread_info.ttbr0 = __pa_symbol(reserved_pg_dir);
|
||||
#endif
|
||||
|
||||
if (boot_args[1] || boot_args[2] || boot_args[3]) {
|
||||
|
|
|
@ -164,13 +164,11 @@ SECTIONS
|
|||
. += PAGE_SIZE;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
|
||||
reserved_ttbr0 = .;
|
||||
. += RESERVED_TTBR0_SIZE;
|
||||
#endif
|
||||
reserved_pg_dir = .;
|
||||
. += PAGE_SIZE;
|
||||
|
||||
swapper_pg_dir = .;
|
||||
. += PAGE_SIZE;
|
||||
swapper_pg_end = .;
|
||||
|
||||
. = ALIGN(SEGMENT_ALIGN);
|
||||
__init_begin = .;
|
||||
|
|
|
@ -168,7 +168,7 @@ SYM_FUNC_END(cpu_do_resume)
|
|||
.pushsection ".idmap.text", "awx"
|
||||
|
||||
.macro __idmap_cpu_set_reserved_ttbr1, tmp1, tmp2
|
||||
adrp \tmp1, empty_zero_page
|
||||
adrp \tmp1, reserved_pg_dir
|
||||
phys_to_ttbr \tmp2, \tmp1
|
||||
offset_ttbr1 \tmp2, \tmp1
|
||||
msr ttbr1_el1, \tmp2
|
||||
|
|
Loading…
Reference in New Issue
Block a user