process.c (94fb1afb14c4f0ceb8c5508ddddac6819f662e95) | process.c (b3545192e2b4647234254c5122f8cbfddbcbdaa0) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Architecture-specific setup. 4 * 5 * Copyright (C) 1998-2003 Hewlett-Packard Co 6 * David Mosberger-Tang <davidm@hpl.hp.com> 7 * 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support 8 * --- 34 unchanged lines hidden (view full) --- 43#include <asm/pgalloc.h> 44#include <asm/processor.h> 45#include <asm/sal.h> 46#include <asm/switch_to.h> 47#include <asm/tlbflush.h> 48#include <linux/uaccess.h> 49#include <asm/unwind.h> 50#include <asm/user.h> | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Architecture-specific setup. 4 * 5 * Copyright (C) 1998-2003 Hewlett-Packard Co 6 * David Mosberger-Tang <davidm@hpl.hp.com> 7 * 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support 8 * --- 34 unchanged lines hidden (view full) --- 43#include <asm/pgalloc.h> 44#include <asm/processor.h> 45#include <asm/sal.h> 46#include <asm/switch_to.h> 47#include <asm/tlbflush.h> 48#include <linux/uaccess.h> 49#include <asm/unwind.h> 50#include <asm/user.h> |
51#include <asm/xtp.h> |
|
51 52#include "entry.h" 53 54#ifdef CONFIG_PERFMON 55# include <asm/perfmon.h> 56#endif 57 58#include "sigframe.h" --- 232 unchanged lines hidden (view full) --- 291 if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) 292 ia64_load_debug_regs(&task->thread.dbr[0]); 293 294#ifdef CONFIG_PERFMON 295 if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0) 296 pfm_load_regs(task); 297 298 info = __this_cpu_read(pfm_syst_info); | 52 53#include "entry.h" 54 55#ifdef CONFIG_PERFMON 56# include <asm/perfmon.h> 57#endif 58 59#include "sigframe.h" --- 232 unchanged lines hidden (view full) --- 292 if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) 293 ia64_load_debug_regs(&task->thread.dbr[0]); 294 295#ifdef CONFIG_PERFMON 296 if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0) 297 pfm_load_regs(task); 298 299 info = __this_cpu_read(pfm_syst_info); |
299 if (info & PFM_CPUINFO_SYST_WIDE) | 300 if (info & PFM_CPUINFO_SYST_WIDE) |
300 pfm_syst_wide_update_task(task, info, 1); 301#endif 302} 303 304/* 305 * Copy the state of an ia-64 thread. 306 * 307 * We get here through the following call chain: 308 * 309 * from user-level: from kernel: 310 * 311 * <clone syscall> <some kernel call frames> 312 * sys_clone : | 301 pfm_syst_wide_update_task(task, info, 1); 302#endif 303} 304 305/* 306 * Copy the state of an ia-64 thread. 307 * 308 * We get here through the following call chain: 309 * 310 * from user-level: from kernel: 311 * 312 * <clone syscall> <some kernel call frames> 313 * sys_clone : |
313 * _do_fork _do_fork | 314 * do_fork do_fork |
314 * copy_thread copy_thread 315 * 316 * This means that the stack layout is as follows: 317 * 318 * +---------------------+ (highest addr) 319 * | struct pt_regs | 320 * +---------------------+ 321 * | struct switch_stack | --- 6 unchanged lines hidden (view full) --- 328 * Observe that we copy the unat values that are in pt_regs and switch_stack. Spilling an 329 * integer to address X causes bit N in ar.unat to be set to the NaT bit of the register, 330 * with N=(X & 0x1ff)/8. Thus, copying the unat value preserves the NaT bits ONLY if the 331 * pt_regs structure in the parent is congruent to that of the child, modulo 512. Since 332 * the stack is page aligned and the page size is at least 4KB, this is always the case, 333 * so there is nothing to worry about. 334 */ 335int | 315 * copy_thread copy_thread 316 * 317 * This means that the stack layout is as follows: 318 * 319 * +---------------------+ (highest addr) 320 * | struct pt_regs | 321 * +---------------------+ 322 * | struct switch_stack | --- 6 unchanged lines hidden (view full) --- 329 * Observe that we copy the unat values that are in pt_regs and switch_stack. Spilling an 330 * integer to address X causes bit N in ar.unat to be set to the NaT bit of the register, 331 * with N=(X & 0x1ff)/8. Thus, copying the unat value preserves the NaT bits ONLY if the 332 * pt_regs structure in the parent is congruent to that of the child, modulo 512. Since 333 * the stack is page aligned and the page size is at least 4KB, this is always the case, 334 * so there is nothing to worry about. 335 */ 336int |
336copy_thread(unsigned long clone_flags, unsigned long user_stack_base, 337 unsigned long user_stack_size, struct task_struct *p, unsigned long tls) | 337copy_thread(unsigned long clone_flags, 338 unsigned long user_stack_base, unsigned long user_stack_size, 339 struct task_struct *p) |
338{ 339 extern char ia64_ret_from_clone; 340 struct switch_stack *child_stack, *stack; 341 unsigned long rbs, child_rbs, rbs_size; 342 struct pt_regs *child_ptregs; 343 struct pt_regs *regs = current_pt_regs(); 344 int retval = 0; 345 --- 64 unchanged lines hidden (view full) --- 410 stack = ((struct switch_stack *) regs) - 1; 411 /* copy parent's switch_stack & pt_regs to child: */ 412 memcpy(child_stack, stack, sizeof(*child_ptregs) + sizeof(*child_stack)); 413 414 /* copy the parent's register backing store to the child: */ 415 rbs_size = stack->ar_bspstore - rbs; 416 memcpy((void *) child_rbs, (void *) rbs, rbs_size); 417 if (clone_flags & CLONE_SETTLS) | 340{ 341 extern char ia64_ret_from_clone; 342 struct switch_stack *child_stack, *stack; 343 unsigned long rbs, child_rbs, rbs_size; 344 struct pt_regs *child_ptregs; 345 struct pt_regs *regs = current_pt_regs(); 346 int retval = 0; 347 --- 64 unchanged lines hidden (view full) --- 412 stack = ((struct switch_stack *) regs) - 1; 413 /* copy parent's switch_stack & pt_regs to child: */ 414 memcpy(child_stack, stack, sizeof(*child_ptregs) + sizeof(*child_stack)); 415 416 /* copy the parent's register backing store to the child: */ 417 rbs_size = stack->ar_bspstore - rbs; 418 memcpy((void *) child_rbs, (void *) rbs, rbs_size); 419 if (clone_flags & CLONE_SETTLS) |
418 child_ptregs->r13 = tls; | 420 child_ptregs->r13 = regs->r16; /* see sys_clone2() in entry.S */ |
419 if (user_stack_base) { 420 child_ptregs->r12 = user_stack_base + user_stack_size - 16; 421 child_ptregs->ar_bspstore = user_stack_base; 422 child_ptregs->ar_rnat = 0; 423 child_ptregs->loadrs = 0; 424 } 425 child_stack->ar_bspstore = child_rbs + rbs_size; 426 child_stack->b0 = (unsigned long) &ia64_ret_from_clone; --- 8 unchanged lines hidden (view full) --- 435 436#ifdef CONFIG_PERFMON 437 if (current->thread.pfm_context) 438 pfm_inherit(p, child_ptregs); 439#endif 440 return retval; 441} 442 | 421 if (user_stack_base) { 422 child_ptregs->r12 = user_stack_base + user_stack_size - 16; 423 child_ptregs->ar_bspstore = user_stack_base; 424 child_ptregs->ar_rnat = 0; 425 child_ptregs->loadrs = 0; 426 } 427 child_stack->ar_bspstore = child_rbs + rbs_size; 428 child_stack->b0 = (unsigned long) &ia64_ret_from_clone; --- 8 unchanged lines hidden (view full) --- 437 438#ifdef CONFIG_PERFMON 439 if (current->thread.pfm_context) 440 pfm_inherit(p, child_ptregs); 441#endif 442 return retval; 443} 444 |
443asmlinkage long ia64_clone(unsigned long clone_flags, unsigned long stack_start, 444 unsigned long stack_size, unsigned long parent_tidptr, 445 unsigned long child_tidptr, unsigned long tls) 446{ 447 struct kernel_clone_args args = { 448 .flags = (lower_32_bits(clone_flags) & ~CSIGNAL), 449 .pidfd = (int __user *)parent_tidptr, 450 .child_tid = (int __user *)child_tidptr, 451 .parent_tid = (int __user *)parent_tidptr, 452 .exit_signal = (lower_32_bits(clone_flags) & CSIGNAL), 453 .stack = stack_start, 454 .stack_size = stack_size, 455 .tls = tls, 456 }; 457 458 return _do_fork(&args); 459} 460 | |
461static void 462do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg) 463{ 464 unsigned long mask, sp, nat_bits = 0, ar_rnat, urbs_end, cfm; | 445static void 446do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg) 447{ 448 unsigned long mask, sp, nat_bits = 0, ar_rnat, urbs_end, cfm; |
465 unsigned long ip; | 449 unsigned long uninitialized_var(ip); /* GCC be quiet */ |
466 elf_greg_t *dst = arg; 467 struct pt_regs *pt; 468 char nat; 469 int i; 470 471 memset(dst, 0, sizeof(elf_gregset_t)); /* don't leak any kernel bits to user-level */ 472 473 if (unw_unwind_to_user(info) < 0) --- 223 unchanged lines hidden --- | 450 elf_greg_t *dst = arg; 451 struct pt_regs *pt; 452 char nat; 453 int i; 454 455 memset(dst, 0, sizeof(elf_gregset_t)); /* don't leak any kernel bits to user-level */ 456 457 if (unw_unwind_to_user(info) < 0) --- 223 unchanged lines hidden --- |