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 173b3901d54SCatalin Marinas void __show_regs(struct pt_regs *regs) 174b3901d54SCatalin Marinas { 1756ca68e80SCatalin Marinas int i, top_reg; 1766ca68e80SCatalin Marinas u64 lr, sp; 1776ca68e80SCatalin Marinas 1786ca68e80SCatalin Marinas if (compat_user_mode(regs)) { 1796ca68e80SCatalin Marinas lr = regs->compat_lr; 1806ca68e80SCatalin Marinas sp = regs->compat_sp; 1816ca68e80SCatalin Marinas top_reg = 12; 1826ca68e80SCatalin Marinas } else { 1836ca68e80SCatalin Marinas lr = regs->regs[30]; 1846ca68e80SCatalin Marinas sp = regs->sp; 1856ca68e80SCatalin Marinas top_reg = 29; 1866ca68e80SCatalin Marinas } 187b3901d54SCatalin Marinas 188a43cb95dSTejun Heo show_regs_print_info(KERN_DEFAULT); 189b3901d54SCatalin Marinas print_symbol("PC is at %s\n", instruction_pointer(regs)); 1906ca68e80SCatalin Marinas print_symbol("LR is at %s\n", lr); 191b3901d54SCatalin Marinas printk("pc : [<%016llx>] lr : [<%016llx>] pstate: %08llx\n", 1926ca68e80SCatalin Marinas regs->pc, lr, regs->pstate); 1936ca68e80SCatalin Marinas printk("sp : %016llx\n", sp); 194db4b0710SMark Rutland 195db4b0710SMark Rutland i = top_reg; 196db4b0710SMark Rutland 197db4b0710SMark Rutland while (i >= 0) { 198b3901d54SCatalin Marinas printk("x%-2d: %016llx ", i, regs->regs[i]); 199db4b0710SMark Rutland i--; 200db4b0710SMark Rutland 201db4b0710SMark Rutland if (i % 2 == 0) { 202db4b0710SMark Rutland pr_cont("x%-2d: %016llx ", i, regs->regs[i]); 203db4b0710SMark Rutland i--; 204db4b0710SMark Rutland } 205db4b0710SMark Rutland 206db4b0710SMark Rutland pr_cont("\n"); 207b3901d54SCatalin Marinas } 208b3901d54SCatalin Marinas } 209b3901d54SCatalin Marinas 210b3901d54SCatalin Marinas void show_regs(struct pt_regs * regs) 211b3901d54SCatalin Marinas { 212b3901d54SCatalin Marinas __show_regs(regs); 213*1149aad1SKefeng Wang dump_backtrace(regs, NULL); 214b3901d54SCatalin Marinas } 215b3901d54SCatalin Marinas 216eb35bdd7SWill Deacon static void tls_thread_flush(void) 217eb35bdd7SWill Deacon { 218adf75899SMark Rutland write_sysreg(0, tpidr_el0); 219eb35bdd7SWill Deacon 220eb35bdd7SWill Deacon if (is_compat_task()) { 221eb35bdd7SWill Deacon current->thread.tp_value = 0; 222eb35bdd7SWill Deacon 223eb35bdd7SWill Deacon /* 224eb35bdd7SWill Deacon * We need to ensure ordering between the shadow state and the 225eb35bdd7SWill Deacon * hardware state, so that we don't corrupt the hardware state 226eb35bdd7SWill Deacon * with a stale shadow state during context switch. 227eb35bdd7SWill Deacon */ 228eb35bdd7SWill Deacon barrier(); 229adf75899SMark Rutland write_sysreg(0, tpidrro_el0); 230eb35bdd7SWill Deacon } 231eb35bdd7SWill Deacon } 232eb35bdd7SWill Deacon 233b3901d54SCatalin Marinas void flush_thread(void) 234b3901d54SCatalin Marinas { 235b3901d54SCatalin Marinas fpsimd_flush_thread(); 236eb35bdd7SWill Deacon tls_thread_flush(); 237b3901d54SCatalin Marinas flush_ptrace_hw_breakpoint(current); 238b3901d54SCatalin Marinas } 239b3901d54SCatalin Marinas 240b3901d54SCatalin Marinas void release_thread(struct task_struct *dead_task) 241b3901d54SCatalin Marinas { 242b3901d54SCatalin Marinas } 243b3901d54SCatalin Marinas 244b3901d54SCatalin Marinas int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) 245b3901d54SCatalin Marinas { 2466eb6c801SJanet Liu if (current->mm) 247c51f9269SArd Biesheuvel fpsimd_preserve_current_state(); 248b3901d54SCatalin Marinas *dst = *src; 249b3901d54SCatalin Marinas return 0; 250b3901d54SCatalin Marinas } 251b3901d54SCatalin Marinas 252b3901d54SCatalin Marinas asmlinkage void ret_from_fork(void) asm("ret_from_fork"); 253b3901d54SCatalin Marinas 254b3901d54SCatalin Marinas int copy_thread(unsigned long clone_flags, unsigned long stack_start, 255afa86fc4SAl Viro unsigned long stk_sz, struct task_struct *p) 256b3901d54SCatalin Marinas { 257b3901d54SCatalin Marinas struct pt_regs *childregs = task_pt_regs(p); 258b3901d54SCatalin Marinas 259c34501d2SCatalin Marinas memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context)); 260c34501d2SCatalin Marinas 2619ac08002SAl Viro if (likely(!(p->flags & PF_KTHREAD))) { 2629ac08002SAl Viro *childregs = *current_pt_regs(); 263b3901d54SCatalin Marinas childregs->regs[0] = 0; 264d00a3810SWill Deacon 265b3901d54SCatalin Marinas /* 266b3901d54SCatalin Marinas * Read the current TLS pointer from tpidr_el0 as it may be 267b3901d54SCatalin Marinas * out-of-sync with the saved value. 268b3901d54SCatalin Marinas */ 269adf75899SMark Rutland *task_user_tls(p) = read_sysreg(tpidr_el0); 270d00a3810SWill Deacon 271e0fd18ceSAl Viro if (stack_start) { 272d00a3810SWill Deacon if (is_compat_thread(task_thread_info(p))) 273d00a3810SWill Deacon childregs->compat_sp = stack_start; 274d00a3810SWill Deacon else 275b3901d54SCatalin Marinas childregs->sp = stack_start; 276b3901d54SCatalin Marinas } 277d00a3810SWill Deacon 278c34501d2SCatalin Marinas /* 279c34501d2SCatalin Marinas * If a TLS pointer was passed to clone (4th argument), use it 280c34501d2SCatalin Marinas * for the new thread. 281c34501d2SCatalin Marinas */ 282b3901d54SCatalin Marinas if (clone_flags & CLONE_SETTLS) 283d00a3810SWill Deacon p->thread.tp_value = childregs->regs[3]; 284c34501d2SCatalin Marinas } else { 285c34501d2SCatalin Marinas memset(childregs, 0, sizeof(struct pt_regs)); 286c34501d2SCatalin Marinas childregs->pstate = PSR_MODE_EL1h; 28757f4959bSJames Morse if (IS_ENABLED(CONFIG_ARM64_UAO) && 288a4023f68SSuzuki K Poulose cpus_have_const_cap(ARM64_HAS_UAO)) 28957f4959bSJames Morse childregs->pstate |= PSR_UAO_BIT; 290c34501d2SCatalin Marinas p->thread.cpu_context.x19 = stack_start; 291c34501d2SCatalin Marinas p->thread.cpu_context.x20 = stk_sz; 292c34501d2SCatalin Marinas } 293c34501d2SCatalin Marinas p->thread.cpu_context.pc = (unsigned long)ret_from_fork; 294c34501d2SCatalin Marinas p->thread.cpu_context.sp = (unsigned long)childregs; 295b3901d54SCatalin Marinas 296b3901d54SCatalin Marinas ptrace_hw_copy_thread(p); 297b3901d54SCatalin Marinas 298b3901d54SCatalin Marinas return 0; 299b3901d54SCatalin Marinas } 300b3901d54SCatalin Marinas 301b3901d54SCatalin Marinas static void tls_thread_switch(struct task_struct *next) 302b3901d54SCatalin Marinas { 303b3901d54SCatalin Marinas unsigned long tpidr, tpidrro; 304b3901d54SCatalin Marinas 305adf75899SMark Rutland tpidr = read_sysreg(tpidr_el0); 306d00a3810SWill Deacon *task_user_tls(current) = tpidr; 307b3901d54SCatalin Marinas 308d00a3810SWill Deacon tpidr = *task_user_tls(next); 309d00a3810SWill Deacon tpidrro = is_compat_thread(task_thread_info(next)) ? 310d00a3810SWill Deacon next->thread.tp_value : 0; 311b3901d54SCatalin Marinas 312adf75899SMark Rutland write_sysreg(tpidr, tpidr_el0); 313adf75899SMark Rutland write_sysreg(tpidrro, tpidrro_el0); 314b3901d54SCatalin Marinas } 315b3901d54SCatalin Marinas 31657f4959bSJames Morse /* Restore the UAO state depending on next's addr_limit */ 317d0854412SJames Morse void uao_thread_switch(struct task_struct *next) 31857f4959bSJames Morse { 319e950631eSCatalin Marinas if (IS_ENABLED(CONFIG_ARM64_UAO)) { 320e950631eSCatalin Marinas if (task_thread_info(next)->addr_limit == KERNEL_DS) 321e950631eSCatalin Marinas asm(ALTERNATIVE("nop", SET_PSTATE_UAO(1), ARM64_HAS_UAO)); 32257f4959bSJames Morse else 323e950631eSCatalin Marinas asm(ALTERNATIVE("nop", SET_PSTATE_UAO(0), ARM64_HAS_UAO)); 324e950631eSCatalin Marinas } 32557f4959bSJames Morse } 32657f4959bSJames Morse 327b3901d54SCatalin Marinas /* 328c02433ddSMark Rutland * We store our current task in sp_el0, which is clobbered by userspace. Keep a 329c02433ddSMark Rutland * shadow copy so that we can restore this upon entry from userspace. 330c02433ddSMark Rutland * 331c02433ddSMark Rutland * This is *only* for exception entry from EL0, and is not valid until we 332c02433ddSMark Rutland * __switch_to() a user task. 333c02433ddSMark Rutland */ 334c02433ddSMark Rutland DEFINE_PER_CPU(struct task_struct *, __entry_task); 335c02433ddSMark Rutland 336c02433ddSMark Rutland static void entry_task_switch(struct task_struct *next) 337c02433ddSMark Rutland { 338c02433ddSMark Rutland __this_cpu_write(__entry_task, next); 339c02433ddSMark Rutland } 340c02433ddSMark Rutland 341c02433ddSMark Rutland /* 342b3901d54SCatalin Marinas * Thread switching. 343b3901d54SCatalin Marinas */ 3448f4b326dSJoel Fernandes __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev, 345b3901d54SCatalin Marinas struct task_struct *next) 346b3901d54SCatalin Marinas { 347b3901d54SCatalin Marinas struct task_struct *last; 348b3901d54SCatalin Marinas 349b3901d54SCatalin Marinas fpsimd_thread_switch(next); 350b3901d54SCatalin Marinas tls_thread_switch(next); 351b3901d54SCatalin Marinas hw_breakpoint_thread_switch(next); 3523325732fSChristopher Covington contextidr_thread_switch(next); 353c02433ddSMark Rutland entry_task_switch(next); 35457f4959bSJames Morse uao_thread_switch(next); 355b3901d54SCatalin Marinas 3565108c67cSCatalin Marinas /* 3575108c67cSCatalin Marinas * Complete any pending TLB or cache maintenance on this CPU in case 3585108c67cSCatalin Marinas * the thread migrates to a different CPU. 3595108c67cSCatalin Marinas */ 36098f7685eSWill Deacon dsb(ish); 361b3901d54SCatalin Marinas 362b3901d54SCatalin Marinas /* the actual thread switch */ 363b3901d54SCatalin Marinas last = cpu_switch_to(prev, next); 364b3901d54SCatalin Marinas 365b3901d54SCatalin Marinas return last; 366b3901d54SCatalin Marinas } 367b3901d54SCatalin Marinas 368b3901d54SCatalin Marinas unsigned long get_wchan(struct task_struct *p) 369b3901d54SCatalin Marinas { 370b3901d54SCatalin Marinas struct stackframe frame; 3719bbd4c56SMark Rutland unsigned long stack_page, ret = 0; 372b3901d54SCatalin Marinas int count = 0; 373b3901d54SCatalin Marinas if (!p || p == current || p->state == TASK_RUNNING) 374b3901d54SCatalin Marinas return 0; 375b3901d54SCatalin Marinas 3769bbd4c56SMark Rutland stack_page = (unsigned long)try_get_task_stack(p); 3779bbd4c56SMark Rutland if (!stack_page) 3789bbd4c56SMark Rutland return 0; 3799bbd4c56SMark Rutland 380b3901d54SCatalin Marinas frame.fp = thread_saved_fp(p); 381b3901d54SCatalin Marinas frame.sp = thread_saved_sp(p); 382b3901d54SCatalin Marinas frame.pc = thread_saved_pc(p); 38320380bb3SAKASHI Takahiro #ifdef CONFIG_FUNCTION_GRAPH_TRACER 38420380bb3SAKASHI Takahiro frame.graph = p->curr_ret_stack; 38520380bb3SAKASHI Takahiro #endif 386b3901d54SCatalin Marinas do { 387408c3658SKonstantin Khlebnikov if (frame.sp < stack_page || 388408c3658SKonstantin Khlebnikov frame.sp >= stack_page + THREAD_SIZE || 389fe13f95bSAKASHI Takahiro unwind_frame(p, &frame)) 3909bbd4c56SMark Rutland goto out; 3919bbd4c56SMark Rutland if (!in_sched_functions(frame.pc)) { 3929bbd4c56SMark Rutland ret = frame.pc; 3939bbd4c56SMark Rutland goto out; 3949bbd4c56SMark Rutland } 395b3901d54SCatalin Marinas } while (count ++ < 16); 3969bbd4c56SMark Rutland 3979bbd4c56SMark Rutland out: 3989bbd4c56SMark Rutland put_task_stack(p); 3999bbd4c56SMark Rutland return ret; 400b3901d54SCatalin Marinas } 401b3901d54SCatalin Marinas 402b3901d54SCatalin Marinas unsigned long arch_align_stack(unsigned long sp) 403b3901d54SCatalin Marinas { 404b3901d54SCatalin Marinas if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) 405b3901d54SCatalin Marinas sp -= get_random_int() & ~PAGE_MASK; 406b3901d54SCatalin Marinas return sp & ~0xf; 407b3901d54SCatalin Marinas } 408b3901d54SCatalin Marinas 409b3901d54SCatalin Marinas unsigned long arch_randomize_brk(struct mm_struct *mm) 410b3901d54SCatalin Marinas { 41161462c8aSKees Cook if (is_compat_task()) 412ffe3d1e4SMiles Chen return randomize_page(mm->brk, SZ_32M); 41361462c8aSKees Cook else 414ffe3d1e4SMiles Chen return randomize_page(mm->brk, SZ_1G); 415b3901d54SCatalin Marinas } 416