1b3901d54SCatalin Marinas /* 2b3901d54SCatalin Marinas * Based on arch/arm/kernel/process.c 3b3901d54SCatalin Marinas * 4b3901d54SCatalin Marinas * Original Copyright (C) 1995 Linus Torvalds 5b3901d54SCatalin Marinas * Copyright (C) 1996-2000 Russell King - Converted to ARM. 6b3901d54SCatalin Marinas * Copyright (C) 2012 ARM Ltd. 7b3901d54SCatalin Marinas * 8b3901d54SCatalin Marinas * This program is free software; you can redistribute it and/or modify 9b3901d54SCatalin Marinas * it under the terms of the GNU General Public License version 2 as 10b3901d54SCatalin Marinas * published by the Free Software Foundation. 11b3901d54SCatalin Marinas * 12b3901d54SCatalin Marinas * This program is distributed in the hope that it will be useful, 13b3901d54SCatalin Marinas * but WITHOUT ANY WARRANTY; without even the implied warranty of 14b3901d54SCatalin Marinas * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15b3901d54SCatalin Marinas * GNU General Public License for more details. 16b3901d54SCatalin Marinas * 17b3901d54SCatalin Marinas * You should have received a copy of the GNU General Public License 18b3901d54SCatalin Marinas * along with this program. If not, see <http://www.gnu.org/licenses/>. 19b3901d54SCatalin Marinas */ 20b3901d54SCatalin Marinas 21b3901d54SCatalin Marinas #include <stdarg.h> 22b3901d54SCatalin Marinas 23fd92d4a5SAKASHI Takahiro #include <linux/compat.h> 2460c0d45aSArd Biesheuvel #include <linux/efi.h> 25b3901d54SCatalin Marinas #include <linux/export.h> 26b3901d54SCatalin Marinas #include <linux/sched.h> 27b17b0153SIngo Molnar #include <linux/sched/debug.h> 2829930025SIngo Molnar #include <linux/sched/task.h> 2968db0cf1SIngo Molnar #include <linux/sched/task_stack.h> 30b3901d54SCatalin Marinas #include <linux/kernel.h> 31b3901d54SCatalin Marinas #include <linux/mm.h> 32b3901d54SCatalin Marinas #include <linux/stddef.h> 33b3901d54SCatalin Marinas #include <linux/unistd.h> 34b3901d54SCatalin Marinas #include <linux/user.h> 35b3901d54SCatalin Marinas #include <linux/delay.h> 36b3901d54SCatalin Marinas #include <linux/reboot.h> 37b3901d54SCatalin Marinas #include <linux/interrupt.h> 38b3901d54SCatalin Marinas #include <linux/kallsyms.h> 39b3901d54SCatalin Marinas #include <linux/init.h> 40b3901d54SCatalin Marinas #include <linux/cpu.h> 41b3901d54SCatalin Marinas #include <linux/elfcore.h> 42b3901d54SCatalin Marinas #include <linux/pm.h> 43b3901d54SCatalin Marinas #include <linux/tick.h> 44b3901d54SCatalin Marinas #include <linux/utsname.h> 45b3901d54SCatalin Marinas #include <linux/uaccess.h> 46b3901d54SCatalin Marinas #include <linux/random.h> 47b3901d54SCatalin Marinas #include <linux/hw_breakpoint.h> 48b3901d54SCatalin Marinas #include <linux/personality.h> 49b3901d54SCatalin Marinas #include <linux/notifier.h> 50096b3224SJisheng Zhang #include <trace/events/power.h> 51c02433ddSMark Rutland #include <linux/percpu.h> 52b3901d54SCatalin Marinas 5357f4959bSJames Morse #include <asm/alternative.h> 54b3901d54SCatalin Marinas #include <asm/compat.h> 55b3901d54SCatalin Marinas #include <asm/cacheflush.h> 56d0854412SJames Morse #include <asm/exec.h> 57ec45d1cfSWill Deacon #include <asm/fpsimd.h> 58ec45d1cfSWill Deacon #include <asm/mmu_context.h> 59b3901d54SCatalin Marinas #include <asm/processor.h> 60b3901d54SCatalin Marinas #include <asm/stacktrace.h> 61b3901d54SCatalin Marinas 62c0c264aeSLaura Abbott #ifdef CONFIG_CC_STACKPROTECTOR 63c0c264aeSLaura Abbott #include <linux/stackprotector.h> 64c0c264aeSLaura Abbott unsigned long __stack_chk_guard __read_mostly; 65c0c264aeSLaura Abbott EXPORT_SYMBOL(__stack_chk_guard); 66c0c264aeSLaura Abbott #endif 67c0c264aeSLaura Abbott 68b3901d54SCatalin Marinas /* 69b3901d54SCatalin Marinas * Function pointers to optional machine specific functions 70b3901d54SCatalin Marinas */ 71b3901d54SCatalin Marinas void (*pm_power_off)(void); 72b3901d54SCatalin Marinas EXPORT_SYMBOL_GPL(pm_power_off); 73b3901d54SCatalin Marinas 74b0946fc8SCatalin Marinas void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd); 75b3901d54SCatalin Marinas 76b3901d54SCatalin Marinas /* 77b3901d54SCatalin Marinas * This is our default idle handler. 78b3901d54SCatalin Marinas */ 790087298fSThomas Gleixner void arch_cpu_idle(void) 80b3901d54SCatalin Marinas { 81b3901d54SCatalin Marinas /* 82b3901d54SCatalin Marinas * This should do all the clock switching and wait for interrupt 83b3901d54SCatalin Marinas * tricks 84b3901d54SCatalin Marinas */ 85096b3224SJisheng Zhang trace_cpu_idle_rcuidle(1, smp_processor_id()); 86b3901d54SCatalin Marinas cpu_do_idle(); 87b3901d54SCatalin Marinas local_irq_enable(); 88096b3224SJisheng Zhang trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); 89b3901d54SCatalin Marinas } 90b3901d54SCatalin Marinas 919327e2c6SMark Rutland #ifdef CONFIG_HOTPLUG_CPU 929327e2c6SMark Rutland void arch_cpu_idle_dead(void) 939327e2c6SMark Rutland { 949327e2c6SMark Rutland cpu_die(); 959327e2c6SMark Rutland } 969327e2c6SMark Rutland #endif 979327e2c6SMark Rutland 9890f51a09SArun KS /* 9990f51a09SArun KS * Called by kexec, immediately prior to machine_kexec(). 10090f51a09SArun KS * 10190f51a09SArun KS * This must completely disable all secondary CPUs; simply causing those CPUs 10290f51a09SArun KS * to execute e.g. a RAM-based pin loop is not sufficient. This allows the 10390f51a09SArun KS * kexec'd kernel to use any and all RAM as it sees fit, without having to 10490f51a09SArun KS * avoid any code or data used by any SW CPU pin loop. The CPU hotplug 10590f51a09SArun KS * functionality embodied in disable_nonboot_cpus() to achieve this. 10690f51a09SArun KS */ 107b3901d54SCatalin Marinas void machine_shutdown(void) 108b3901d54SCatalin Marinas { 10990f51a09SArun KS disable_nonboot_cpus(); 110b3901d54SCatalin Marinas } 111b3901d54SCatalin Marinas 11290f51a09SArun KS /* 11390f51a09SArun KS * Halting simply requires that the secondary CPUs stop performing any 11490f51a09SArun KS * activity (executing tasks, handling interrupts). smp_send_stop() 11590f51a09SArun KS * achieves this. 11690f51a09SArun KS */ 117b3901d54SCatalin Marinas void machine_halt(void) 118b3901d54SCatalin Marinas { 119b9acc49eSArun KS local_irq_disable(); 12090f51a09SArun KS smp_send_stop(); 121b3901d54SCatalin Marinas while (1); 122b3901d54SCatalin Marinas } 123b3901d54SCatalin Marinas 12490f51a09SArun KS /* 12590f51a09SArun KS * Power-off simply requires that the secondary CPUs stop performing any 12690f51a09SArun KS * activity (executing tasks, handling interrupts). smp_send_stop() 12790f51a09SArun KS * achieves this. When the system power is turned off, it will take all CPUs 12890f51a09SArun KS * with it. 12990f51a09SArun KS */ 130b3901d54SCatalin Marinas void machine_power_off(void) 131b3901d54SCatalin Marinas { 132b9acc49eSArun KS local_irq_disable(); 13390f51a09SArun KS smp_send_stop(); 134b3901d54SCatalin Marinas if (pm_power_off) 135b3901d54SCatalin Marinas pm_power_off(); 136b3901d54SCatalin Marinas } 137b3901d54SCatalin Marinas 13890f51a09SArun KS /* 13990f51a09SArun KS * Restart requires that the secondary CPUs stop performing any activity 14068234df4SMark Rutland * while the primary CPU resets the system. Systems with multiple CPUs must 14190f51a09SArun KS * provide a HW restart implementation, to ensure that all CPUs reset at once. 14290f51a09SArun KS * This is required so that any code running after reset on the primary CPU 14390f51a09SArun KS * doesn't have to co-ordinate with other CPUs to ensure they aren't still 14490f51a09SArun KS * executing pre-reset code, and using RAM that the primary CPU's code wishes 14590f51a09SArun KS * to use. Implementing such co-ordination would be essentially impossible. 14690f51a09SArun KS */ 147b3901d54SCatalin Marinas void machine_restart(char *cmd) 148b3901d54SCatalin Marinas { 149b3901d54SCatalin Marinas /* Disable interrupts first */ 150b3901d54SCatalin Marinas local_irq_disable(); 151b9acc49eSArun KS smp_send_stop(); 152b3901d54SCatalin Marinas 15360c0d45aSArd Biesheuvel /* 15460c0d45aSArd Biesheuvel * UpdateCapsule() depends on the system being reset via 15560c0d45aSArd Biesheuvel * ResetSystem(). 15660c0d45aSArd Biesheuvel */ 15760c0d45aSArd Biesheuvel if (efi_enabled(EFI_RUNTIME_SERVICES)) 15860c0d45aSArd Biesheuvel efi_reboot(reboot_mode, NULL); 15960c0d45aSArd Biesheuvel 160b3901d54SCatalin Marinas /* Now call the architecture specific reboot code. */ 161aa1e8ec1SCatalin Marinas if (arm_pm_restart) 162ff701306SMarc Zyngier arm_pm_restart(reboot_mode, cmd); 1631c7ffc32SGuenter Roeck else 1641c7ffc32SGuenter Roeck do_kernel_restart(cmd); 165b3901d54SCatalin Marinas 166b3901d54SCatalin Marinas /* 167b3901d54SCatalin Marinas * Whoops - the architecture was unable to reboot. 168b3901d54SCatalin Marinas */ 169b3901d54SCatalin Marinas printk("Reboot failed -- System halted\n"); 170b3901d54SCatalin Marinas while (1); 171b3901d54SCatalin Marinas } 172b3901d54SCatalin Marinas 173*b7300d4cSWill Deacon static void print_pstate(struct pt_regs *regs) 174*b7300d4cSWill Deacon { 175*b7300d4cSWill Deacon u64 pstate = regs->pstate; 176*b7300d4cSWill Deacon 177*b7300d4cSWill Deacon if (compat_user_mode(regs)) { 178*b7300d4cSWill Deacon printk("pstate: %08llx (%c%c%c%c %c %s %s %c%c%c)\n", 179*b7300d4cSWill Deacon pstate, 180*b7300d4cSWill Deacon pstate & COMPAT_PSR_N_BIT ? 'N' : 'n', 181*b7300d4cSWill Deacon pstate & COMPAT_PSR_Z_BIT ? 'Z' : 'z', 182*b7300d4cSWill Deacon pstate & COMPAT_PSR_C_BIT ? 'C' : 'c', 183*b7300d4cSWill Deacon pstate & COMPAT_PSR_V_BIT ? 'V' : 'v', 184*b7300d4cSWill Deacon pstate & COMPAT_PSR_Q_BIT ? 'Q' : 'q', 185*b7300d4cSWill Deacon pstate & COMPAT_PSR_T_BIT ? "T32" : "A32", 186*b7300d4cSWill Deacon pstate & COMPAT_PSR_E_BIT ? "BE" : "LE", 187*b7300d4cSWill Deacon pstate & COMPAT_PSR_A_BIT ? 'A' : 'a', 188*b7300d4cSWill Deacon pstate & COMPAT_PSR_I_BIT ? 'I' : 'i', 189*b7300d4cSWill Deacon pstate & COMPAT_PSR_F_BIT ? 'F' : 'f'); 190*b7300d4cSWill Deacon } else { 191*b7300d4cSWill Deacon printk("pstate: %08llx (%c%c%c%c %c%c%c%c %cPAN %cUAO)\n", 192*b7300d4cSWill Deacon pstate, 193*b7300d4cSWill Deacon pstate & PSR_N_BIT ? 'N' : 'n', 194*b7300d4cSWill Deacon pstate & PSR_Z_BIT ? 'Z' : 'z', 195*b7300d4cSWill Deacon pstate & PSR_C_BIT ? 'C' : 'c', 196*b7300d4cSWill Deacon pstate & PSR_V_BIT ? 'V' : 'v', 197*b7300d4cSWill Deacon pstate & PSR_D_BIT ? 'D' : 'd', 198*b7300d4cSWill Deacon pstate & PSR_A_BIT ? 'A' : 'a', 199*b7300d4cSWill Deacon pstate & PSR_I_BIT ? 'I' : 'i', 200*b7300d4cSWill Deacon pstate & PSR_F_BIT ? 'F' : 'f', 201*b7300d4cSWill Deacon pstate & PSR_PAN_BIT ? '+' : '-', 202*b7300d4cSWill Deacon pstate & PSR_UAO_BIT ? '+' : '-'); 203*b7300d4cSWill Deacon } 204*b7300d4cSWill Deacon } 205*b7300d4cSWill Deacon 206b3901d54SCatalin Marinas void __show_regs(struct pt_regs *regs) 207b3901d54SCatalin Marinas { 2086ca68e80SCatalin Marinas int i, top_reg; 2096ca68e80SCatalin Marinas u64 lr, sp; 2106ca68e80SCatalin Marinas 2116ca68e80SCatalin Marinas if (compat_user_mode(regs)) { 2126ca68e80SCatalin Marinas lr = regs->compat_lr; 2136ca68e80SCatalin Marinas sp = regs->compat_sp; 2146ca68e80SCatalin Marinas top_reg = 12; 2156ca68e80SCatalin Marinas } else { 2166ca68e80SCatalin Marinas lr = regs->regs[30]; 2176ca68e80SCatalin Marinas sp = regs->sp; 2186ca68e80SCatalin Marinas top_reg = 29; 2196ca68e80SCatalin Marinas } 220b3901d54SCatalin Marinas 221a43cb95dSTejun Heo show_regs_print_info(KERN_DEFAULT); 222*b7300d4cSWill Deacon print_pstate(regs); 223a25ffd3aSWill Deacon print_symbol("pc : %s\n", regs->pc); 224a25ffd3aSWill Deacon print_symbol("lr : %s\n", lr); 225*b7300d4cSWill Deacon printk("sp : %016llx\n", sp); 226db4b0710SMark Rutland 227db4b0710SMark Rutland i = top_reg; 228db4b0710SMark Rutland 229db4b0710SMark Rutland while (i >= 0) { 230b3901d54SCatalin Marinas printk("x%-2d: %016llx ", i, regs->regs[i]); 231db4b0710SMark Rutland i--; 232db4b0710SMark Rutland 233db4b0710SMark Rutland if (i % 2 == 0) { 234db4b0710SMark Rutland pr_cont("x%-2d: %016llx ", i, regs->regs[i]); 235db4b0710SMark Rutland i--; 236db4b0710SMark Rutland } 237db4b0710SMark Rutland 238db4b0710SMark Rutland pr_cont("\n"); 239b3901d54SCatalin Marinas } 240b3901d54SCatalin Marinas } 241b3901d54SCatalin Marinas 242b3901d54SCatalin Marinas void show_regs(struct pt_regs * regs) 243b3901d54SCatalin Marinas { 244b3901d54SCatalin Marinas __show_regs(regs); 2451149aad1SKefeng Wang dump_backtrace(regs, NULL); 246b3901d54SCatalin Marinas } 247b3901d54SCatalin Marinas 248eb35bdd7SWill Deacon static void tls_thread_flush(void) 249eb35bdd7SWill Deacon { 250adf75899SMark Rutland write_sysreg(0, tpidr_el0); 251eb35bdd7SWill Deacon 252eb35bdd7SWill Deacon if (is_compat_task()) { 253eb35bdd7SWill Deacon current->thread.tp_value = 0; 254eb35bdd7SWill Deacon 255eb35bdd7SWill Deacon /* 256eb35bdd7SWill Deacon * We need to ensure ordering between the shadow state and the 257eb35bdd7SWill Deacon * hardware state, so that we don't corrupt the hardware state 258eb35bdd7SWill Deacon * with a stale shadow state during context switch. 259eb35bdd7SWill Deacon */ 260eb35bdd7SWill Deacon barrier(); 261adf75899SMark Rutland write_sysreg(0, tpidrro_el0); 262eb35bdd7SWill Deacon } 263eb35bdd7SWill Deacon } 264eb35bdd7SWill Deacon 265b3901d54SCatalin Marinas void flush_thread(void) 266b3901d54SCatalin Marinas { 267b3901d54SCatalin Marinas fpsimd_flush_thread(); 268eb35bdd7SWill Deacon tls_thread_flush(); 269b3901d54SCatalin Marinas flush_ptrace_hw_breakpoint(current); 270b3901d54SCatalin Marinas } 271b3901d54SCatalin Marinas 272b3901d54SCatalin Marinas void release_thread(struct task_struct *dead_task) 273b3901d54SCatalin Marinas { 274b3901d54SCatalin Marinas } 275b3901d54SCatalin Marinas 276b3901d54SCatalin Marinas int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) 277b3901d54SCatalin Marinas { 2786eb6c801SJanet Liu if (current->mm) 279c51f9269SArd Biesheuvel fpsimd_preserve_current_state(); 280b3901d54SCatalin Marinas *dst = *src; 281b3901d54SCatalin Marinas return 0; 282b3901d54SCatalin Marinas } 283b3901d54SCatalin Marinas 284b3901d54SCatalin Marinas asmlinkage void ret_from_fork(void) asm("ret_from_fork"); 285b3901d54SCatalin Marinas 286b3901d54SCatalin Marinas int copy_thread(unsigned long clone_flags, unsigned long stack_start, 287afa86fc4SAl Viro unsigned long stk_sz, struct task_struct *p) 288b3901d54SCatalin Marinas { 289b3901d54SCatalin Marinas struct pt_regs *childregs = task_pt_regs(p); 290b3901d54SCatalin Marinas 291c34501d2SCatalin Marinas memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context)); 292c34501d2SCatalin Marinas 2939ac08002SAl Viro if (likely(!(p->flags & PF_KTHREAD))) { 2949ac08002SAl Viro *childregs = *current_pt_regs(); 295b3901d54SCatalin Marinas childregs->regs[0] = 0; 296d00a3810SWill Deacon 297b3901d54SCatalin Marinas /* 298b3901d54SCatalin Marinas * Read the current TLS pointer from tpidr_el0 as it may be 299b3901d54SCatalin Marinas * out-of-sync with the saved value. 300b3901d54SCatalin Marinas */ 301adf75899SMark Rutland *task_user_tls(p) = read_sysreg(tpidr_el0); 302d00a3810SWill Deacon 303e0fd18ceSAl Viro if (stack_start) { 304d00a3810SWill Deacon if (is_compat_thread(task_thread_info(p))) 305d00a3810SWill Deacon childregs->compat_sp = stack_start; 306d00a3810SWill Deacon else 307b3901d54SCatalin Marinas childregs->sp = stack_start; 308b3901d54SCatalin Marinas } 309d00a3810SWill Deacon 310c34501d2SCatalin Marinas /* 311c34501d2SCatalin Marinas * If a TLS pointer was passed to clone (4th argument), use it 312c34501d2SCatalin Marinas * for the new thread. 313c34501d2SCatalin Marinas */ 314b3901d54SCatalin Marinas if (clone_flags & CLONE_SETTLS) 315d00a3810SWill Deacon p->thread.tp_value = childregs->regs[3]; 316c34501d2SCatalin Marinas } else { 317c34501d2SCatalin Marinas memset(childregs, 0, sizeof(struct pt_regs)); 318c34501d2SCatalin Marinas childregs->pstate = PSR_MODE_EL1h; 31957f4959bSJames Morse if (IS_ENABLED(CONFIG_ARM64_UAO) && 320a4023f68SSuzuki K Poulose cpus_have_const_cap(ARM64_HAS_UAO)) 32157f4959bSJames Morse childregs->pstate |= PSR_UAO_BIT; 322c34501d2SCatalin Marinas p->thread.cpu_context.x19 = stack_start; 323c34501d2SCatalin Marinas p->thread.cpu_context.x20 = stk_sz; 324c34501d2SCatalin Marinas } 325c34501d2SCatalin Marinas p->thread.cpu_context.pc = (unsigned long)ret_from_fork; 326c34501d2SCatalin Marinas p->thread.cpu_context.sp = (unsigned long)childregs; 327b3901d54SCatalin Marinas 328b3901d54SCatalin Marinas ptrace_hw_copy_thread(p); 329b3901d54SCatalin Marinas 330b3901d54SCatalin Marinas return 0; 331b3901d54SCatalin Marinas } 332b3901d54SCatalin Marinas 333936eb65cSDave Martin void tls_preserve_current_state(void) 334936eb65cSDave Martin { 335936eb65cSDave Martin *task_user_tls(current) = read_sysreg(tpidr_el0); 336936eb65cSDave Martin } 337936eb65cSDave Martin 338b3901d54SCatalin Marinas static void tls_thread_switch(struct task_struct *next) 339b3901d54SCatalin Marinas { 340b3901d54SCatalin Marinas unsigned long tpidr, tpidrro; 341b3901d54SCatalin Marinas 342936eb65cSDave Martin tls_preserve_current_state(); 343b3901d54SCatalin Marinas 344d00a3810SWill Deacon tpidr = *task_user_tls(next); 345d00a3810SWill Deacon tpidrro = is_compat_thread(task_thread_info(next)) ? 346d00a3810SWill Deacon next->thread.tp_value : 0; 347b3901d54SCatalin Marinas 348adf75899SMark Rutland write_sysreg(tpidr, tpidr_el0); 349adf75899SMark Rutland write_sysreg(tpidrro, tpidrro_el0); 350b3901d54SCatalin Marinas } 351b3901d54SCatalin Marinas 35257f4959bSJames Morse /* Restore the UAO state depending on next's addr_limit */ 353d0854412SJames Morse void uao_thread_switch(struct task_struct *next) 35457f4959bSJames Morse { 355e950631eSCatalin Marinas if (IS_ENABLED(CONFIG_ARM64_UAO)) { 356e950631eSCatalin Marinas if (task_thread_info(next)->addr_limit == KERNEL_DS) 357e950631eSCatalin Marinas asm(ALTERNATIVE("nop", SET_PSTATE_UAO(1), ARM64_HAS_UAO)); 35857f4959bSJames Morse else 359e950631eSCatalin Marinas asm(ALTERNATIVE("nop", SET_PSTATE_UAO(0), ARM64_HAS_UAO)); 360e950631eSCatalin Marinas } 36157f4959bSJames Morse } 36257f4959bSJames Morse 363b3901d54SCatalin Marinas /* 364c02433ddSMark Rutland * We store our current task in sp_el0, which is clobbered by userspace. Keep a 365c02433ddSMark Rutland * shadow copy so that we can restore this upon entry from userspace. 366c02433ddSMark Rutland * 367c02433ddSMark Rutland * This is *only* for exception entry from EL0, and is not valid until we 368c02433ddSMark Rutland * __switch_to() a user task. 369c02433ddSMark Rutland */ 370c02433ddSMark Rutland DEFINE_PER_CPU(struct task_struct *, __entry_task); 371c02433ddSMark Rutland 372c02433ddSMark Rutland static void entry_task_switch(struct task_struct *next) 373c02433ddSMark Rutland { 374c02433ddSMark Rutland __this_cpu_write(__entry_task, next); 375c02433ddSMark Rutland } 376c02433ddSMark Rutland 377c02433ddSMark Rutland /* 378b3901d54SCatalin Marinas * Thread switching. 379b3901d54SCatalin Marinas */ 3808f4b326dSJoel Fernandes __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev, 381b3901d54SCatalin Marinas struct task_struct *next) 382b3901d54SCatalin Marinas { 383b3901d54SCatalin Marinas struct task_struct *last; 384b3901d54SCatalin Marinas 385b3901d54SCatalin Marinas fpsimd_thread_switch(next); 386b3901d54SCatalin Marinas tls_thread_switch(next); 387b3901d54SCatalin Marinas hw_breakpoint_thread_switch(next); 3883325732fSChristopher Covington contextidr_thread_switch(next); 389c02433ddSMark Rutland entry_task_switch(next); 39057f4959bSJames Morse uao_thread_switch(next); 391b3901d54SCatalin Marinas 3925108c67cSCatalin Marinas /* 3935108c67cSCatalin Marinas * Complete any pending TLB or cache maintenance on this CPU in case 3945108c67cSCatalin Marinas * the thread migrates to a different CPU. 39522e4ebb9SMathieu Desnoyers * This full barrier is also required by the membarrier system 39622e4ebb9SMathieu Desnoyers * call. 3975108c67cSCatalin Marinas */ 39898f7685eSWill Deacon dsb(ish); 399b3901d54SCatalin Marinas 400b3901d54SCatalin Marinas /* the actual thread switch */ 401b3901d54SCatalin Marinas last = cpu_switch_to(prev, next); 402b3901d54SCatalin Marinas 403b3901d54SCatalin Marinas return last; 404b3901d54SCatalin Marinas } 405b3901d54SCatalin Marinas 406b3901d54SCatalin Marinas unsigned long get_wchan(struct task_struct *p) 407b3901d54SCatalin Marinas { 408b3901d54SCatalin Marinas struct stackframe frame; 4099bbd4c56SMark Rutland unsigned long stack_page, ret = 0; 410b3901d54SCatalin Marinas int count = 0; 411b3901d54SCatalin Marinas if (!p || p == current || p->state == TASK_RUNNING) 412b3901d54SCatalin Marinas return 0; 413b3901d54SCatalin Marinas 4149bbd4c56SMark Rutland stack_page = (unsigned long)try_get_task_stack(p); 4159bbd4c56SMark Rutland if (!stack_page) 4169bbd4c56SMark Rutland return 0; 4179bbd4c56SMark Rutland 418b3901d54SCatalin Marinas frame.fp = thread_saved_fp(p); 419b3901d54SCatalin Marinas frame.pc = thread_saved_pc(p); 42020380bb3SAKASHI Takahiro #ifdef CONFIG_FUNCTION_GRAPH_TRACER 42120380bb3SAKASHI Takahiro frame.graph = p->curr_ret_stack; 42220380bb3SAKASHI Takahiro #endif 423b3901d54SCatalin Marinas do { 42431e43ad3SArd Biesheuvel if (unwind_frame(p, &frame)) 4259bbd4c56SMark Rutland goto out; 4269bbd4c56SMark Rutland if (!in_sched_functions(frame.pc)) { 4279bbd4c56SMark Rutland ret = frame.pc; 4289bbd4c56SMark Rutland goto out; 4299bbd4c56SMark Rutland } 430b3901d54SCatalin Marinas } while (count ++ < 16); 4319bbd4c56SMark Rutland 4329bbd4c56SMark Rutland out: 4339bbd4c56SMark Rutland put_task_stack(p); 4349bbd4c56SMark Rutland return ret; 435b3901d54SCatalin Marinas } 436b3901d54SCatalin Marinas 437b3901d54SCatalin Marinas unsigned long arch_align_stack(unsigned long sp) 438b3901d54SCatalin Marinas { 439b3901d54SCatalin Marinas if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) 440b3901d54SCatalin Marinas sp -= get_random_int() & ~PAGE_MASK; 441b3901d54SCatalin Marinas return sp & ~0xf; 442b3901d54SCatalin Marinas } 443b3901d54SCatalin Marinas 444b3901d54SCatalin Marinas unsigned long arch_randomize_brk(struct mm_struct *mm) 445b3901d54SCatalin Marinas { 44661462c8aSKees Cook if (is_compat_task()) 447ffe3d1e4SMiles Chen return randomize_page(mm->brk, SZ_32M); 44861462c8aSKees Cook else 449ffe3d1e4SMiles Chen return randomize_page(mm->brk, SZ_1G); 450b3901d54SCatalin Marinas } 451d1be5c99SYury Norov 452d1be5c99SYury Norov /* 453d1be5c99SYury Norov * Called from setup_new_exec() after (COMPAT_)SET_PERSONALITY. 454d1be5c99SYury Norov */ 455d1be5c99SYury Norov void arch_setup_new_exec(void) 456d1be5c99SYury Norov { 457d1be5c99SYury Norov current->mm->context.flags = is_compat_task() ? MMCF_AARCH32 : 0; 458d1be5c99SYury Norov } 459