1caab277bSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 29cce7a43SCatalin Marinas/* 39cce7a43SCatalin Marinas * Based on arch/arm/mm/proc.S 49cce7a43SCatalin Marinas * 59cce7a43SCatalin Marinas * Copyright (C) 2001 Deep Blue Solutions Ltd. 69cce7a43SCatalin Marinas * Copyright (C) 2012 ARM Ltd. 79cce7a43SCatalin Marinas * Author: Catalin Marinas <catalin.marinas@arm.com> 89cce7a43SCatalin Marinas */ 99cce7a43SCatalin Marinas 109cce7a43SCatalin Marinas#include <linux/init.h> 119cce7a43SCatalin Marinas#include <linux/linkage.h> 1265fddcfcSMike Rapoport#include <linux/pgtable.h> 13c50d3285SSami Tolvanen#include <linux/cfi_types.h> 149cce7a43SCatalin Marinas#include <asm/assembler.h> 159cce7a43SCatalin Marinas#include <asm/asm-offsets.h> 16e51f5f56SAmit Daniel Kachhap#include <asm/asm_pointer_auth.h> 179cce7a43SCatalin Marinas#include <asm/hwcap.h> 1847546a19SArd Biesheuvel#include <asm/kernel-pgtable.h> 19cabe1c81SJames Morse#include <asm/pgtable-hwdef.h> 20104a0c02SAndrew Pinski#include <asm/cpufeature.h> 21104a0c02SAndrew Pinski#include <asm/alternative.h> 226982934eSKristina Martsenko#include <asm/smp.h> 233b714d24SVincenzo Frascino#include <asm/sysreg.h> 249cce7a43SCatalin Marinas 2535a86976SCatalin Marinas#ifdef CONFIG_ARM64_64K_PAGES 2635a86976SCatalin Marinas#define TCR_TG_FLAGS TCR_TG0_64K | TCR_TG1_64K 2744eaacf1SSuzuki K. Poulose#elif defined(CONFIG_ARM64_16K_PAGES) 2844eaacf1SSuzuki K. Poulose#define TCR_TG_FLAGS TCR_TG0_16K | TCR_TG1_16K 2944eaacf1SSuzuki K. Poulose#else /* CONFIG_ARM64_4K_PAGES */ 3035a86976SCatalin Marinas#define TCR_TG_FLAGS TCR_TG0_4K | TCR_TG1_4K 319cce7a43SCatalin Marinas#endif 329cce7a43SCatalin Marinas 33e03e61c3SWill Deacon#ifdef CONFIG_RANDOMIZE_BASE 34e03e61c3SWill Deacon#define TCR_KASLR_FLAGS TCR_NFD1 35e03e61c3SWill Deacon#else 36e03e61c3SWill Deacon#define TCR_KASLR_FLAGS 0 37e03e61c3SWill Deacon#endif 38e03e61c3SWill Deacon 3935a86976SCatalin Marinas#define TCR_SMP_FLAGS TCR_SHARED 4035a86976SCatalin Marinas 4135a86976SCatalin Marinas/* PTWs cacheable, inner/outer WBWA */ 4235a86976SCatalin Marinas#define TCR_CACHE_FLAGS TCR_IRGN_WBWA | TCR_ORGN_WBWA 4335a86976SCatalin Marinas 4421696c16SAndrey Konovalov#ifdef CONFIG_KASAN_SW_TAGS 45bfc62c59SVincenzo Frascino#define TCR_KASAN_SW_FLAGS TCR_TBI1 | TCR_TBID1 4621696c16SAndrey Konovalov#else 47bfc62c59SVincenzo Frascino#define TCR_KASAN_SW_FLAGS 0 48bfc62c59SVincenzo Frascino#endif 49bfc62c59SVincenzo Frascino 50bfc62c59SVincenzo Frascino#ifdef CONFIG_KASAN_HW_TAGS 51e921da6bSAnshuman Khandual#define TCR_MTE_FLAGS TCR_TCMA1 | TCR_TBI1 | TCR_TBID1 52973b9e37SPeter Collingbourne#elif defined(CONFIG_ARM64_MTE) 53013bb59dSPeter Collingbourne/* 54013bb59dSPeter Collingbourne * The mte_zero_clear_page_tags() implementation uses DC GZVA, which relies on 55013bb59dSPeter Collingbourne * TBI being enabled at EL1. 56013bb59dSPeter Collingbourne */ 57013bb59dSPeter Collingbourne#define TCR_MTE_FLAGS TCR_TBI1 | TCR_TBID1 58973b9e37SPeter Collingbourne#else 59973b9e37SPeter Collingbourne#define TCR_MTE_FLAGS 0 6021696c16SAndrey Konovalov#endif 6121696c16SAndrey Konovalov 620178dc76SCatalin Marinas/* 630178dc76SCatalin Marinas * Default MAIR_EL1. MT_NORMAL_TAGGED is initially mapped as Normal memory and 64973b9e37SPeter Collingbourne * changed during mte_cpu_setup to Normal Tagged if the system supports MTE. 650178dc76SCatalin Marinas */ 6695b3f74bSCatalin Marinas#define MAIR_EL1_SET \ 6795b3f74bSCatalin Marinas (MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRnE, MT_DEVICE_nGnRnE) | \ 6895b3f74bSCatalin Marinas MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRE, MT_DEVICE_nGnRE) | \ 6995b3f74bSCatalin Marinas MAIR_ATTRIDX(MAIR_ATTR_NORMAL_NC, MT_NORMAL_NC) | \ 7095b3f74bSCatalin Marinas MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL) | \ 710178dc76SCatalin Marinas MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL_TAGGED)) 729cce7a43SCatalin Marinas 73af3cfdbfSLorenzo Pieralisi#ifdef CONFIG_CPU_PM 746732bc65SLorenzo Pieralisi/** 756732bc65SLorenzo Pieralisi * cpu_do_suspend - save CPU registers context 766732bc65SLorenzo Pieralisi * 776732bc65SLorenzo Pieralisi * x0: virtual address of context pointer 786d37d81fSSami Tolvanen * 796d37d81fSSami Tolvanen * This must be kept in sync with struct cpu_suspend_ctx in <asm/suspend.h>. 806732bc65SLorenzo Pieralisi */ 81f4659254SMark BrownSYM_FUNC_START(cpu_do_suspend) 826732bc65SLorenzo Pieralisi mrs x2, tpidr_el0 836732bc65SLorenzo Pieralisi mrs x3, tpidrro_el0 846732bc65SLorenzo Pieralisi mrs x4, contextidr_el1 85827a108eSJean-Philippe Brucker mrs x5, osdlr_el1 86827a108eSJean-Philippe Brucker mrs x6, cpacr_el1 87827a108eSJean-Philippe Brucker mrs x7, tcr_el1 88827a108eSJean-Philippe Brucker mrs x8, vbar_el1 89827a108eSJean-Philippe Brucker mrs x9, mdscr_el1 90827a108eSJean-Philippe Brucker mrs x10, oslsr_el1 91827a108eSJean-Philippe Brucker mrs x11, sctlr_el1 92e176e267SMark Rutland get_this_cpu_offset x12 93827a108eSJean-Philippe Brucker mrs x13, sp_el0 946732bc65SLorenzo Pieralisi stp x2, x3, [x0] 95827a108eSJean-Philippe Brucker stp x4, x5, [x0, #16] 96827a108eSJean-Philippe Brucker stp x6, x7, [x0, #32] 97827a108eSJean-Philippe Brucker stp x8, x9, [x0, #48] 98827a108eSJean-Philippe Brucker stp x10, x11, [x0, #64] 99827a108eSJean-Philippe Brucker stp x12, x13, [x0, #80] 1006d37d81fSSami Tolvanen /* 1016d37d81fSSami Tolvanen * Save x18 as it may be used as a platform register, e.g. by shadow 1026d37d81fSSami Tolvanen * call stack. 1036d37d81fSSami Tolvanen */ 1046d37d81fSSami Tolvanen str x18, [x0, #96] 1056732bc65SLorenzo Pieralisi ret 106f4659254SMark BrownSYM_FUNC_END(cpu_do_suspend) 1076732bc65SLorenzo Pieralisi 1086732bc65SLorenzo Pieralisi/** 1096732bc65SLorenzo Pieralisi * cpu_do_resume - restore CPU register context 1106732bc65SLorenzo Pieralisi * 111cabe1c81SJames Morse * x0: Address of context pointer 1126732bc65SLorenzo Pieralisi */ 113f4659254SMark BrownSYM_FUNC_START(cpu_do_resume) 1146732bc65SLorenzo Pieralisi ldp x2, x3, [x0] 1156732bc65SLorenzo Pieralisi ldp x4, x5, [x0, #16] 116cabe1c81SJames Morse ldp x6, x8, [x0, #32] 117cabe1c81SJames Morse ldp x9, x10, [x0, #48] 118cabe1c81SJames Morse ldp x11, x12, [x0, #64] 119623b476fSMark Rutland ldp x13, x14, [x0, #80] 1206d37d81fSSami Tolvanen /* 1216d37d81fSSami Tolvanen * Restore x18, as it may be used as a platform register, and clear 1226d37d81fSSami Tolvanen * the buffer to minimize the risk of exposure when used for shadow 1236d37d81fSSami Tolvanen * call stack. 1246d37d81fSSami Tolvanen */ 1256d37d81fSSami Tolvanen ldr x18, [x0, #96] 1266d37d81fSSami Tolvanen str xzr, [x0, #96] 1276732bc65SLorenzo Pieralisi msr tpidr_el0, x2 1286732bc65SLorenzo Pieralisi msr tpidrro_el0, x3 1296732bc65SLorenzo Pieralisi msr contextidr_el1, x4 1306732bc65SLorenzo Pieralisi msr cpacr_el1, x6 131cabe1c81SJames Morse 132cabe1c81SJames Morse /* Don't change t0sz here, mask those bits when restoring */ 133827a108eSJean-Philippe Brucker mrs x7, tcr_el1 134827a108eSJean-Philippe Brucker bfi x8, x7, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH 135cabe1c81SJames Morse 1366732bc65SLorenzo Pieralisi msr tcr_el1, x8 1376732bc65SLorenzo Pieralisi msr vbar_el1, x9 138744c6c37SJames Morse 139744c6c37SJames Morse /* 140744c6c37SJames Morse * __cpu_setup() cleared MDSCR_EL1.MDE and friends, before unmasking 141744c6c37SJames Morse * debug exceptions. By restoring MDSCR_EL1 here, we may take a debug 1420fbeb318SJames Morse * exception. Mask them until local_daif_restore() in cpu_suspend() 143744c6c37SJames Morse * resets them. 144744c6c37SJames Morse */ 1450fbeb318SJames Morse disable_daif 1466732bc65SLorenzo Pieralisi msr mdscr_el1, x10 147744c6c37SJames Morse 148cabe1c81SJames Morse msr sctlr_el1, x12 149e176e267SMark Rutland set_this_cpu_offset x13 150623b476fSMark Rutland msr sp_el0, x14 1516732bc65SLorenzo Pieralisi /* 1526732bc65SLorenzo Pieralisi * Restore oslsr_el1 by writing oslar_el1 1536732bc65SLorenzo Pieralisi */ 154827a108eSJean-Philippe Brucker msr osdlr_el1, x5 1556732bc65SLorenzo Pieralisi ubfx x11, x11, #1, #1 1566732bc65SLorenzo Pieralisi msr oslar_el1, x11 157f436b2acSLorenzo Pieralisi reset_pmuserenr_el0 x0 // Disable PMU access from EL0 15887a1f063SIonela Voinescu reset_amuserenr_el0 x0 // Disable AMU access from EL0 15968ddbf09SJames Morse 16068ddbf09SJames Morsealternative_if ARM64_HAS_RAS_EXTN 16168ddbf09SJames Morse msr_s SYS_DISR_EL1, xzr 16268ddbf09SJames Morsealternative_else_nop_endif 16368ddbf09SJames Morse 164d0055da5SMark Rutland ptrauth_keys_install_kernel_nosync x14, x1, x2, x3 1656732bc65SLorenzo Pieralisi isb 1666732bc65SLorenzo Pieralisi ret 167f4659254SMark BrownSYM_FUNC_END(cpu_do_resume) 1686732bc65SLorenzo Pieralisi#endif 1696732bc65SLorenzo Pieralisi 1704df69e0dSndesaulniers@google.com .pushsection ".idmap.text", "a" 171f992b4dfSWill Deacon 172f992b4dfSWill Deacon.macro __idmap_cpu_set_reserved_ttbr1, tmp1, tmp2 173833be850SMark Rutland adrp \tmp1, reserved_pg_dir 174fa0465fcSWill Deacon phys_to_ttbr \tmp2, \tmp1 175c812026cSSteve Capper offset_ttbr1 \tmp2, \tmp1 176f992b4dfSWill Deacon msr ttbr1_el1, \tmp2 177f992b4dfSWill Deacon isb 178f992b4dfSWill Deacon tlbi vmalle1 179f992b4dfSWill Deacon dsb nsh 180f992b4dfSWill Deacon isb 181f992b4dfSWill Deacon.endm 182f992b4dfSWill Deacon 18350e1881dSMark Rutland/* 1845ffdfaedSVladimir Murzin * void idmap_cpu_replace_ttbr1(phys_addr_t ttbr1) 18550e1881dSMark Rutland * 18650e1881dSMark Rutland * This is the low-level counterpart to cpu_replace_ttbr1, and should not be 18750e1881dSMark Rutland * called by anything else. It can only be executed from a TTBR0 mapping. 18850e1881dSMark Rutland */ 189c50d3285SSami TolvanenSYM_TYPED_FUNC_START(idmap_cpu_replace_ttbr1) 190f992b4dfSWill Deacon __idmap_cpu_set_reserved_ttbr1 x1, x3 19150e1881dSMark Rutland 192c812026cSSteve Capper offset_ttbr1 x0, x3 1935ffdfaedSVladimir Murzin msr ttbr1_el1, x0 19450e1881dSMark Rutland isb 19550e1881dSMark Rutland 19650e1881dSMark Rutland ret 197f4659254SMark BrownSYM_FUNC_END(idmap_cpu_replace_ttbr1) 19850e1881dSMark Rutland .popsection 19950e1881dSMark Rutland 200f992b4dfSWill Deacon#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 20147546a19SArd Biesheuvel 202f0af339fSJoey Gouly#define KPTI_NG_PTE_FLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS | PTE_WRITE) 20347546a19SArd Biesheuvel 2044df69e0dSndesaulniers@google.com .pushsection ".idmap.text", "a" 205f992b4dfSWill Deacon 206c7eff738SArd Biesheuvel .macro kpti_mk_tbl_ng, type, num_entries 207c7eff738SArd Biesheuvel add end_\type\()p, cur_\type\()p, #\num_entries * 8 208c7eff738SArd Biesheuvel.Ldo_\type: 20947546a19SArd Biesheuvel ldr \type, [cur_\type\()p] // Load the entry 210c7eff738SArd Biesheuvel tbz \type, #0, .Lnext_\type // Skip invalid and 211c7eff738SArd Biesheuvel tbnz \type, #11, .Lnext_\type // non-global entries 212f992b4dfSWill Deacon orr \type, \type, #PTE_NG // Same bit for blocks and pages 21347546a19SArd Biesheuvel str \type, [cur_\type\()p] // Update the entry 214c7eff738SArd Biesheuvel .ifnc \type, pte 215c7eff738SArd Biesheuvel tbnz \type, #1, .Lderef_\type 216c7eff738SArd Biesheuvel .endif 217c7eff738SArd Biesheuvel.Lnext_\type: 218c7eff738SArd Biesheuvel add cur_\type\()p, cur_\type\()p, #8 219c7eff738SArd Biesheuvel cmp cur_\type\()p, end_\type\()p 220c7eff738SArd Biesheuvel b.ne .Ldo_\type 221f992b4dfSWill Deacon .endm 222f992b4dfSWill Deacon 223f992b4dfSWill Deacon /* 22447546a19SArd Biesheuvel * Dereference the current table entry and map it into the temporary 22547546a19SArd Biesheuvel * fixmap slot associated with the current level. 22647546a19SArd Biesheuvel */ 22747546a19SArd Biesheuvel .macro kpti_map_pgtbl, type, level 22847546a19SArd Biesheuvel str xzr, [temp_pte, #8 * (\level + 1)] // break before make 22947546a19SArd Biesheuvel dsb nshst 23047546a19SArd Biesheuvel add pte, temp_pte, #PAGE_SIZE * (\level + 1) 23147546a19SArd Biesheuvel lsr pte, pte, #12 23247546a19SArd Biesheuvel tlbi vaae1, pte 23347546a19SArd Biesheuvel dsb nsh 23447546a19SArd Biesheuvel isb 23547546a19SArd Biesheuvel 23647546a19SArd Biesheuvel phys_to_pte pte, cur_\type\()p 23747546a19SArd Biesheuvel add cur_\type\()p, temp_pte, #PAGE_SIZE * (\level + 1) 23847546a19SArd Biesheuvel orr pte, pte, pte_flags 23947546a19SArd Biesheuvel str pte, [temp_pte, #8 * (\level + 1)] 24047546a19SArd Biesheuvel dsb nshst 24147546a19SArd Biesheuvel .endm 24247546a19SArd Biesheuvel 24347546a19SArd Biesheuvel/* 24447546a19SArd Biesheuvel * void __kpti_install_ng_mappings(int cpu, int num_secondaries, phys_addr_t temp_pgd, 24547546a19SArd Biesheuvel * unsigned long temp_pte_va) 246f992b4dfSWill Deacon * 247f992b4dfSWill Deacon * Called exactly once from stop_machine context by each CPU found during boot. 248f992b4dfSWill Deacon */ 249c3cee924SArd Biesheuvel .pushsection ".data", "aw", %progbits 250c3cee924SArd BiesheuvelSYM_DATA(__idmap_kpti_flag, .long 1) 251c3cee924SArd Biesheuvel .popsection 252c3cee924SArd Biesheuvel 253c50d3285SSami TolvanenSYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings) 254f992b4dfSWill Deacon cpu .req w0 25547546a19SArd Biesheuvel temp_pte .req x0 256f992b4dfSWill Deacon num_cpus .req w1 25747546a19SArd Biesheuvel pte_flags .req x1 25847546a19SArd Biesheuvel temp_pgd_phys .req x2 259f992b4dfSWill Deacon swapper_ttb .req x3 260f992b4dfSWill Deacon flag_ptr .req x4 261f992b4dfSWill Deacon cur_pgdp .req x5 262f992b4dfSWill Deacon end_pgdp .req x6 263f992b4dfSWill Deacon pgd .req x7 264f992b4dfSWill Deacon cur_pudp .req x8 265f992b4dfSWill Deacon end_pudp .req x9 266f992b4dfSWill Deacon cur_pmdp .req x11 267f992b4dfSWill Deacon end_pmdp .req x12 268f992b4dfSWill Deacon cur_ptep .req x14 269f992b4dfSWill Deacon end_ptep .req x15 270f992b4dfSWill Deacon pte .req x16 27147546a19SArd Biesheuvel valid .req x17 272f992b4dfSWill Deacon 27347546a19SArd Biesheuvel mov x5, x3 // preserve temp_pte arg 274f992b4dfSWill Deacon mrs swapper_ttb, ttbr1_el1 275c3cee924SArd Biesheuvel adr_l flag_ptr, __idmap_kpti_flag 276f992b4dfSWill Deacon 277f992b4dfSWill Deacon cbnz cpu, __idmap_kpti_secondary 278f992b4dfSWill Deacon 279f992b4dfSWill Deacon /* We're the boot CPU. Wait for the others to catch up */ 280f992b4dfSWill Deacon sevl 281f992b4dfSWill Deacon1: wfe 282e3ec6582SSami Tolvanen ldaxr w17, [flag_ptr] 283e3ec6582SSami Tolvanen eor w17, w17, num_cpus 284e3ec6582SSami Tolvanen cbnz w17, 1b 285f992b4dfSWill Deacon 28647546a19SArd Biesheuvel /* Switch to the temporary page tables on this CPU only */ 28747546a19SArd Biesheuvel __idmap_cpu_set_reserved_ttbr1 x8, x9 28847546a19SArd Biesheuvel offset_ttbr1 temp_pgd_phys, x8 28947546a19SArd Biesheuvel msr ttbr1_el1, temp_pgd_phys 290f992b4dfSWill Deacon isb 291f992b4dfSWill Deacon 29247546a19SArd Biesheuvel mov temp_pte, x5 293f0af339fSJoey Gouly mov_q pte_flags, KPTI_NG_PTE_FLAGS 29447546a19SArd Biesheuvel 295f992b4dfSWill Deacon /* Everybody is enjoying the idmap, so we can rewrite swapper. */ 296f992b4dfSWill Deacon /* PGD */ 29747546a19SArd Biesheuvel adrp cur_pgdp, swapper_pg_dir 29847546a19SArd Biesheuvel kpti_map_pgtbl pgd, 0 299c7eff738SArd Biesheuvel kpti_mk_tbl_ng pgd, PTRS_PER_PGD 300f992b4dfSWill Deacon 30147546a19SArd Biesheuvel /* Ensure all the updated entries are visible to secondary CPUs */ 30247546a19SArd Biesheuvel dsb ishst 303f992b4dfSWill Deacon 30447546a19SArd Biesheuvel /* We're done: fire up swapper_pg_dir again */ 30547546a19SArd Biesheuvel __idmap_cpu_set_reserved_ttbr1 x8, x9 30647546a19SArd Biesheuvel msr ttbr1_el1, swapper_ttb 30747546a19SArd Biesheuvel isb 308f32c7a8eSMark Rutland 309f992b4dfSWill Deacon /* Set the flag to zero to indicate that we're all done */ 310f992b4dfSWill Deacon str wzr, [flag_ptr] 311f992b4dfSWill Deacon ret 312f992b4dfSWill Deacon 313c7eff738SArd Biesheuvel.Lderef_pgd: 314f992b4dfSWill Deacon /* PUD */ 315f992b4dfSWill Deacon .if CONFIG_PGTABLE_LEVELS > 3 316c7eff738SArd Biesheuvel pud .req x10 317f992b4dfSWill Deacon pte_to_phys cur_pudp, pgd 31847546a19SArd Biesheuvel kpti_map_pgtbl pud, 1 319c7eff738SArd Biesheuvel kpti_mk_tbl_ng pud, PTRS_PER_PUD 320c7eff738SArd Biesheuvel b .Lnext_pgd 321f992b4dfSWill Deacon .else /* CONFIG_PGTABLE_LEVELS <= 3 */ 322c7eff738SArd Biesheuvel pud .req pgd 323c7eff738SArd Biesheuvel .set .Lnext_pud, .Lnext_pgd 324f992b4dfSWill Deacon .endif 325f992b4dfSWill Deacon 326c7eff738SArd Biesheuvel.Lderef_pud: 327f992b4dfSWill Deacon /* PMD */ 328f992b4dfSWill Deacon .if CONFIG_PGTABLE_LEVELS > 2 329c7eff738SArd Biesheuvel pmd .req x13 330f992b4dfSWill Deacon pte_to_phys cur_pmdp, pud 33147546a19SArd Biesheuvel kpti_map_pgtbl pmd, 2 332c7eff738SArd Biesheuvel kpti_mk_tbl_ng pmd, PTRS_PER_PMD 333c7eff738SArd Biesheuvel b .Lnext_pud 334f992b4dfSWill Deacon .else /* CONFIG_PGTABLE_LEVELS <= 2 */ 335c7eff738SArd Biesheuvel pmd .req pgd 336c7eff738SArd Biesheuvel .set .Lnext_pmd, .Lnext_pgd 337f992b4dfSWill Deacon .endif 338f992b4dfSWill Deacon 339c7eff738SArd Biesheuvel.Lderef_pmd: 340f992b4dfSWill Deacon /* PTE */ 341f992b4dfSWill Deacon pte_to_phys cur_ptep, pmd 34247546a19SArd Biesheuvel kpti_map_pgtbl pte, 3 343c7eff738SArd Biesheuvel kpti_mk_tbl_ng pte, PTRS_PER_PTE 344c7eff738SArd Biesheuvel b .Lnext_pmd 345f992b4dfSWill Deacon 346f992b4dfSWill Deacon .unreq cpu 34747546a19SArd Biesheuvel .unreq temp_pte 348f992b4dfSWill Deacon .unreq num_cpus 34947546a19SArd Biesheuvel .unreq pte_flags 35047546a19SArd Biesheuvel .unreq temp_pgd_phys 351f992b4dfSWill Deacon .unreq cur_pgdp 352f992b4dfSWill Deacon .unreq end_pgdp 353f992b4dfSWill Deacon .unreq pgd 354f992b4dfSWill Deacon .unreq cur_pudp 355f992b4dfSWill Deacon .unreq end_pudp 356f992b4dfSWill Deacon .unreq pud 357f992b4dfSWill Deacon .unreq cur_pmdp 358f992b4dfSWill Deacon .unreq end_pmdp 359f992b4dfSWill Deacon .unreq pmd 360f992b4dfSWill Deacon .unreq cur_ptep 361f992b4dfSWill Deacon .unreq end_ptep 362f992b4dfSWill Deacon .unreq pte 36347546a19SArd Biesheuvel .unreq valid 364e3ec6582SSami Tolvanen 365e3ec6582SSami Tolvanen /* Secondary CPUs end up here */ 366e3ec6582SSami Tolvanen__idmap_kpti_secondary: 367e3ec6582SSami Tolvanen /* Uninstall swapper before surgery begins */ 368e3ec6582SSami Tolvanen __idmap_cpu_set_reserved_ttbr1 x16, x17 369e3ec6582SSami Tolvanen 370e3ec6582SSami Tolvanen /* Increment the flag to let the boot CPU we're ready */ 371e3ec6582SSami Tolvanen1: ldxr w16, [flag_ptr] 372e3ec6582SSami Tolvanen add w16, w16, #1 373e3ec6582SSami Tolvanen stxr w17, w16, [flag_ptr] 374e3ec6582SSami Tolvanen cbnz w17, 1b 375e3ec6582SSami Tolvanen 376e3ec6582SSami Tolvanen /* Wait for the boot CPU to finish messing around with swapper */ 377e3ec6582SSami Tolvanen sevl 378e3ec6582SSami Tolvanen1: wfe 379e3ec6582SSami Tolvanen ldxr w16, [flag_ptr] 380e3ec6582SSami Tolvanen cbnz w16, 1b 381e3ec6582SSami Tolvanen 382e3ec6582SSami Tolvanen /* All done, act like nothing happened */ 383e3ec6582SSami Tolvanen msr ttbr1_el1, swapper_ttb 384e3ec6582SSami Tolvanen isb 385e3ec6582SSami Tolvanen ret 386e3ec6582SSami Tolvanen 387e3ec6582SSami Tolvanen .unreq swapper_ttb 388e3ec6582SSami Tolvanen .unreq flag_ptr 389f4659254SMark BrownSYM_FUNC_END(idmap_kpti_install_ng_mappings) 390f992b4dfSWill Deacon .popsection 391f992b4dfSWill Deacon#endif 392f992b4dfSWill Deacon 3939cce7a43SCatalin Marinas/* 3949cce7a43SCatalin Marinas * __cpu_setup 3959cce7a43SCatalin Marinas * 396df355101SAmit Daniel Kachhap * Initialise the processor for turning the MMU on. 397df355101SAmit Daniel Kachhap * 3980aaa6853SArd Biesheuvel * Input: 3990aaa6853SArd Biesheuvel * x0 - actual number of VA bits (ignored unless VA_BITS > 48) 400df355101SAmit Daniel Kachhap * Output: 401df355101SAmit Daniel Kachhap * Return in x0 the value of the SCTLR_EL1 register. 4029cce7a43SCatalin Marinas */ 4034df69e0dSndesaulniers@google.com .pushsection ".idmap.text", "a" 404f4659254SMark BrownSYM_FUNC_START(__cpu_setup) 405fa7aae8aSWill Deacon tlbi vmalle1 // Invalidate local TLB 406fa7aae8aSWill Deacon dsb nsh 4079cce7a43SCatalin Marinas 408df355101SAmit Daniel Kachhap mov x1, #3 << 20 409df355101SAmit Daniel Kachhap msr cpacr_el1, x1 // Enable FP/ASIMD 410df355101SAmit Daniel Kachhap mov x1, #1 << 12 // Reset mdscr_el1 and disable 411df355101SAmit Daniel Kachhap msr mdscr_el1, x1 // access to the DCC from EL0 4122ce39ad1SWill Deacon isb // Unmask debug exceptions now, 4132ce39ad1SWill Deacon enable_dbg // since this is per-cpu 414df355101SAmit Daniel Kachhap reset_pmuserenr_el0 x1 // Disable PMU access from EL0 41544ca0e00SCatalin Marinas reset_amuserenr_el0 x1 // Disable AMU access from EL0 41687a1f063SIonela Voinescu 4179cce7a43SCatalin Marinas /* 4185cd6fa6dSMark Rutland * Default values for VMSA control registers. These will be adjusted 4195cd6fa6dSMark Rutland * below depending on detected CPU features. 4209cce7a43SCatalin Marinas */ 421776e49afSMark Rutland mair .req x17 4225cd6fa6dSMark Rutland tcr .req x16 423776e49afSMark Rutland mov_q mair, MAIR_EL1_SET 4245cd6fa6dSMark Rutland mov_q tcr, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \ 4255cd6fa6dSMark Rutland TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \ 426973b9e37SPeter Collingbourne TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS 4275cd6fa6dSMark Rutland 4285cd6fa6dSMark Rutland tcr_clear_errata_bits tcr, x9, x5 42967e7fdfcSSteve Capper 430b6d00d47SSteve Capper#ifdef CONFIG_ARM64_VA_BITS_52 4310aaa6853SArd Biesheuvel sub x9, xzr, x0 43267e7fdfcSSteve Capper add x9, x9, #64 4335cd6fa6dSMark Rutland tcr_set_t1sz tcr, x9 43467e7fdfcSSteve Capper#else 435e8d13cceSArd Biesheuvel idmap_get_t0sz x9 43667e7fdfcSSteve Capper#endif 4375cd6fa6dSMark Rutland tcr_set_t0sz tcr, x9 438dd006da2SArd Biesheuvel 43987366d8cSRadha Mohan Chintakuntla /* 440787fd1d0SKristina Martsenko * Set the IPS bits in TCR_EL1. 44187366d8cSRadha Mohan Chintakuntla */ 4425cd6fa6dSMark Rutland tcr_compute_pa_size tcr, #TCR_IPS_SHIFT, x5, x6 4432f4b829cSCatalin Marinas#ifdef CONFIG_ARM64_HW_AFDBM 4442f4b829cSCatalin Marinas /* 44505abb595SSuzuki K Poulose * Enable hardware update of the Access Flags bit. 44605abb595SSuzuki K Poulose * Hardware dirty bit management is enabled later, 44705abb595SSuzuki K Poulose * via capabilities. 4482f4b829cSCatalin Marinas */ 4492f4b829cSCatalin Marinas mrs x9, ID_AA64MMFR1_EL1 450*d0999555SAnshuman Khandual and x9, x9, ID_AA64MMFR1_EL1_HAFDBS_MASK 45105abb595SSuzuki K Poulose cbz x9, 1f 4525cd6fa6dSMark Rutland orr tcr, tcr, #TCR_HA // hardware Access flag update 45305abb595SSuzuki K Poulose1: 4542f4b829cSCatalin Marinas#endif /* CONFIG_ARM64_HW_AFDBM */ 455776e49afSMark Rutland msr mair_el1, mair 4565cd6fa6dSMark Rutland msr tcr_el1, tcr 4579e9bb6edSJoey Gouly 4589e9bb6edSJoey Gouly mrs_s x1, SYS_ID_AA64MMFR3_EL1 4599e9bb6edSJoey Gouly ubfx x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4 4609e9bb6edSJoey Gouly cbz x1, .Lskip_indirection 4619e9bb6edSJoey Gouly 4629e9bb6edSJoey Gouly mov_q x0, PIE_E0 4639e9bb6edSJoey Gouly msr REG_PIRE0_EL1, x0 4649e9bb6edSJoey Gouly mov_q x0, PIE_E1 4659e9bb6edSJoey Gouly msr REG_PIR_EL1, x0 4669e9bb6edSJoey Gouly 4679e9bb6edSJoey Gouly mov x0, TCR2_EL1x_PIE 4689e9bb6edSJoey Gouly msr REG_TCR2_EL1, x0 4699e9bb6edSJoey Gouly 4709e9bb6edSJoey Gouly.Lskip_indirection: 4719e9bb6edSJoey Gouly 472df355101SAmit Daniel Kachhap /* 473df355101SAmit Daniel Kachhap * Prepare SCTLR 474df355101SAmit Daniel Kachhap */ 4752ffac9e3SMark Rutland mov_q x0, INIT_SCTLR_EL1_MMU_ON 4769cce7a43SCatalin Marinas ret // return to head.S 477776e49afSMark Rutland 478776e49afSMark Rutland .unreq mair 4795cd6fa6dSMark Rutland .unreq tcr 480f4659254SMark BrownSYM_FUNC_END(__cpu_setup) 481